clean searchResolvers in server (#11114)
Introduces break in change - remove search... resolvers - rename globalSearch to search - rename searchRecord.objectSingularName > objectNameSingular closes https://github.com/twentyhq/core-team-issues/issues/643
This commit is contained in:
@ -14,7 +14,6 @@ import { GraphqlQueryFindManyResolverService } from 'src/engine/api/graphql/grap
|
||||
import { GraphqlQueryFindOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service';
|
||||
import { GraphqlQueryRestoreManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service';
|
||||
import { GraphqlQueryRestoreOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-one-resolver.service';
|
||||
import { GraphqlQuerySearchResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service';
|
||||
import { GraphqlQueryUpdateManyResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service';
|
||||
import { GraphqlQueryUpdateOneResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-one-resolver.service';
|
||||
import { ApiEventEmitterService } from 'src/engine/api/graphql/graphql-query-runner/services/api-event-emitter.service';
|
||||
@ -35,7 +34,6 @@ const graphqlQueryResolvers = [
|
||||
GraphqlQueryFindOneResolverService,
|
||||
GraphqlQueryRestoreManyResolverService,
|
||||
GraphqlQueryRestoreOneResolverService,
|
||||
GraphqlQuerySearchResolverService,
|
||||
GraphqlQueryUpdateManyResolverService,
|
||||
GraphqlQueryUpdateOneResolverService,
|
||||
];
|
||||
|
||||
@ -245,7 +245,6 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
case RESOLVER_METHOD_NAMES.FIND_MANY:
|
||||
case RESOLVER_METHOD_NAMES.FIND_ONE:
|
||||
case RESOLVER_METHOD_NAMES.FIND_DUPLICATES:
|
||||
case RESOLVER_METHOD_NAMES.SEARCH:
|
||||
return PermissionsOnAllObjectRecords.READ_ALL_OBJECT_RECORDS;
|
||||
case RESOLVER_METHOD_NAMES.CREATE_MANY:
|
||||
case RESOLVER_METHOD_NAMES.CREATE_ONE:
|
||||
|
||||
@ -1,158 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { Brackets } from 'typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import {
|
||||
ObjectRecord,
|
||||
ObjectRecordFilter,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { SearchResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant';
|
||||
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms';
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
|
||||
import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util';
|
||||
|
||||
@Injectable()
|
||||
export class GraphqlQuerySearchResolverService extends GraphqlQueryBaseResolverService<
|
||||
SearchResolverArgs,
|
||||
IConnection<ObjectRecord>
|
||||
> {
|
||||
async resolve(
|
||||
executionArgs: GraphqlQueryResolverExecutionArgs<SearchResolverArgs>,
|
||||
featureFlagsMap: Record<FeatureFlagKey, boolean>,
|
||||
): Promise<IConnection<ObjectRecord>> {
|
||||
const { authContext, objectMetadataMaps, objectMetadataItemWithFieldMaps } =
|
||||
executionArgs.options;
|
||||
|
||||
const typeORMObjectRecordsParser =
|
||||
new ObjectRecordsToGraphqlConnectionHelper(
|
||||
objectMetadataMaps,
|
||||
featureFlagsMap,
|
||||
);
|
||||
|
||||
if (!isDefined(executionArgs.args.searchInput)) {
|
||||
return typeORMObjectRecordsParser.createConnection({
|
||||
objectRecords: [],
|
||||
objectName: objectMetadataItemWithFieldMaps.nameSingular,
|
||||
take: 0,
|
||||
totalCount: 0,
|
||||
order: [{ id: OrderByDirection.AscNullsFirst }],
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
});
|
||||
}
|
||||
|
||||
const searchTerms = formatSearchTerms(
|
||||
executionArgs.args.searchInput,
|
||||
'and',
|
||||
);
|
||||
const searchTermsOr = formatSearchTerms(
|
||||
executionArgs.args.searchInput,
|
||||
'or',
|
||||
);
|
||||
|
||||
const limit = executionArgs.args?.limit ?? QUERY_MAX_RECORDS;
|
||||
|
||||
const queryBuilder = executionArgs.repository.createQueryBuilder(
|
||||
objectMetadataItemWithFieldMaps.nameSingular,
|
||||
);
|
||||
|
||||
executionArgs.graphqlQueryParser.applyFilterToBuilder(
|
||||
queryBuilder,
|
||||
objectMetadataItemWithFieldMaps.nameSingular,
|
||||
executionArgs.args.filter ?? ({} as ObjectRecordFilter),
|
||||
);
|
||||
|
||||
const countQueryBuilder = queryBuilder.clone();
|
||||
|
||||
const resultsQueryBuilder =
|
||||
searchTerms !== ''
|
||||
? queryBuilder
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where(
|
||||
`"${SEARCH_VECTOR_FIELD.name}" @@ to_tsquery('simple', :searchTerms)`,
|
||||
{ searchTerms },
|
||||
).orWhere(
|
||||
`"${SEARCH_VECTOR_FIELD.name}" @@ to_tsquery('simple', :searchTermsOr)`,
|
||||
{ searchTermsOr },
|
||||
);
|
||||
}),
|
||||
)
|
||||
.orderBy(
|
||||
`ts_rank_cd("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTerms))`,
|
||||
'DESC',
|
||||
)
|
||||
.addOrderBy(
|
||||
`ts_rank("${SEARCH_VECTOR_FIELD.name}", to_tsquery(:searchTermsOr))`,
|
||||
'DESC',
|
||||
)
|
||||
.setParameter('searchTerms', searchTerms)
|
||||
.setParameter('searchTermsOr', searchTermsOr)
|
||||
.take(limit)
|
||||
: queryBuilder
|
||||
.andWhere(
|
||||
new Brackets((qb) => {
|
||||
qb.where(`"${SEARCH_VECTOR_FIELD.name}" IS NOT NULL`);
|
||||
}),
|
||||
)
|
||||
.take(limit);
|
||||
|
||||
const resultsWithTsVector =
|
||||
(await resultsQueryBuilder.getMany()) as ObjectRecord[];
|
||||
|
||||
const objectRecords = formatResult<ObjectRecord[]>(
|
||||
resultsWithTsVector,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
objectMetadataMaps,
|
||||
);
|
||||
|
||||
const totalCount = isDefined(
|
||||
executionArgs.graphqlQuerySelectedFieldsResult.aggregate.totalCount,
|
||||
)
|
||||
? await countQueryBuilder.getCount()
|
||||
: 0;
|
||||
const order = undefined;
|
||||
|
||||
if (executionArgs.graphqlQuerySelectedFieldsResult.relations) {
|
||||
await this.processNestedRelationsHelper.processNestedRelations({
|
||||
objectMetadataMaps,
|
||||
parentObjectMetadataItem: objectMetadataItemWithFieldMaps,
|
||||
parentObjectRecords: objectRecords,
|
||||
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
|
||||
aggregate: executionArgs.graphqlQuerySelectedFieldsResult.aggregate,
|
||||
limit,
|
||||
authContext,
|
||||
dataSource: executionArgs.dataSource,
|
||||
isNewRelationEnabled:
|
||||
featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled],
|
||||
});
|
||||
}
|
||||
|
||||
return typeORMObjectRecordsParser.createConnection({
|
||||
objectRecords: objectRecords ?? [],
|
||||
objectName: objectMetadataItemWithFieldMaps.nameSingular,
|
||||
take: limit,
|
||||
totalCount,
|
||||
order,
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
});
|
||||
}
|
||||
|
||||
async validate(
|
||||
_args: SearchResolverArgs,
|
||||
_options: WorkspaceQueryRunnerOptions,
|
||||
): Promise<void> {}
|
||||
}
|
||||
@ -9,7 +9,6 @@ import {
|
||||
FindManyResolverArgs,
|
||||
FindOneResolverArgs,
|
||||
RestoreManyResolverArgs,
|
||||
SearchResolverArgs,
|
||||
UpdateManyResolverArgs,
|
||||
UpdateOneResolverArgs,
|
||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
@ -43,6 +42,4 @@ export type WorkspacePreQueryHookPayload<T> = T extends 'createMany'
|
||||
? DestroyManyResolverArgs
|
||||
: T extends 'destroyOne'
|
||||
? DestroyOneResolverArgs
|
||||
: T extends 'search'
|
||||
? SearchResolverArgs
|
||||
: never;
|
||||
: never;
|
||||
|
||||
@ -2,7 +2,6 @@ export const RESOLVER_METHOD_NAMES = {
|
||||
FIND_MANY: 'findMany',
|
||||
FIND_ONE: 'findOne',
|
||||
FIND_DUPLICATES: 'findDuplicates',
|
||||
SEARCH: 'search',
|
||||
CREATE_MANY: 'createMany',
|
||||
CREATE_ONE: 'createOne',
|
||||
UPDATE_MANY: 'updateMany',
|
||||
|
||||
@ -2,7 +2,6 @@ import { DestroyManyResolverFactory } from 'src/engine/api/graphql/workspace-res
|
||||
import { DestroyOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/destroy-one-resolver.factory';
|
||||
import { RestoreManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-many-resolver.factory';
|
||||
import { RestoreOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-one-resolver.factory';
|
||||
import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory';
|
||||
import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory';
|
||||
|
||||
import { CreateManyResolverFactory } from './create-many-resolver.factory';
|
||||
@ -28,7 +27,6 @@ export const workspaceResolverBuilderFactories = [
|
||||
DestroyManyResolverFactory,
|
||||
RestoreOneResolverFactory,
|
||||
RestoreManyResolverFactory,
|
||||
SearchResolverFactory,
|
||||
];
|
||||
|
||||
export const workspaceResolverBuilderMethodNames = {
|
||||
@ -36,7 +34,6 @@ export const workspaceResolverBuilderMethodNames = {
|
||||
FindManyResolverFactory.methodName,
|
||||
FindOneResolverFactory.methodName,
|
||||
FindDuplicatesResolverFactory.methodName,
|
||||
SearchResolverFactory.methodName,
|
||||
],
|
||||
mutations: [
|
||||
CreateManyResolverFactory.methodName,
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { WorkspaceResolverBuilderFactoryInterface } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolver-builder-factory.interface';
|
||||
import {
|
||||
Resolver,
|
||||
SearchResolverArgs,
|
||||
} from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
import { WorkspaceSchemaBuilderContext } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-schema-builder-context.interface';
|
||||
|
||||
import { GraphqlQuerySearchResolverService } from 'src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service';
|
||||
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
|
||||
|
||||
@Injectable()
|
||||
export class SearchResolverFactory
|
||||
implements WorkspaceResolverBuilderFactoryInterface
|
||||
{
|
||||
public static methodName = RESOLVER_METHOD_NAMES.SEARCH;
|
||||
|
||||
constructor(
|
||||
private readonly graphqlQueryRunnerService: GraphqlQuerySearchResolverService,
|
||||
) {}
|
||||
|
||||
create(context: WorkspaceSchemaBuilderContext): Resolver<SearchResolverArgs> {
|
||||
const internalContext = context;
|
||||
|
||||
return async (_source, args, _context, info) => {
|
||||
const options: WorkspaceQueryRunnerOptions = {
|
||||
authContext: internalContext.authContext,
|
||||
info,
|
||||
objectMetadataMaps: internalContext.objectMetadataMaps,
|
||||
objectMetadataItemWithFieldMaps:
|
||||
internalContext.objectMetadataItemWithFieldMaps,
|
||||
};
|
||||
|
||||
return await this.graphqlQueryRunnerService.execute(
|
||||
args,
|
||||
options,
|
||||
SearchResolverFactory.methodName,
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -48,14 +48,6 @@ export interface FindDuplicatesResolverArgs<
|
||||
data?: Data[];
|
||||
}
|
||||
|
||||
export interface SearchResolverArgs<
|
||||
Filter extends ObjectRecordFilter = ObjectRecordFilter,
|
||||
> {
|
||||
searchInput?: string;
|
||||
filter?: Filter;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface CreateOneResolverArgs<
|
||||
Data extends Partial<ObjectRecord> = Partial<ObjectRecord>,
|
||||
> {
|
||||
@ -135,6 +127,5 @@ export type ResolverArgs =
|
||||
| FindOneResolverArgs
|
||||
| RestoreManyResolverArgs
|
||||
| RestoreOneResolverArgs
|
||||
| SearchResolverArgs
|
||||
| UpdateManyResolverArgs
|
||||
| UpdateOneResolverArgs;
|
||||
|
||||
@ -6,7 +6,6 @@ import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/work
|
||||
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
import { FindDuplicatesResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/find-duplicates-resolver.factory';
|
||||
import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceResolverBuilderService {
|
||||
@ -19,8 +18,6 @@ export class WorkspaceResolverBuilderService {
|
||||
switch (methodName) {
|
||||
case FindDuplicatesResolverFactory.methodName:
|
||||
return isDefined(objectMetadata.duplicateCriteria);
|
||||
case SearchResolverFactory.methodName:
|
||||
return objectMetadata.isSearchable;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import { DestroyManyResolverFactory } from 'src/engine/api/graphql/workspace-res
|
||||
import { DestroyOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/destroy-one-resolver.factory';
|
||||
import { RestoreManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-many-resolver.factory';
|
||||
import { RestoreOneResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/restore-one-resolver.factory';
|
||||
import { SearchResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/search-resolver-factory';
|
||||
import { UpdateManyResolverFactory } from 'src/engine/api/graphql/workspace-resolver-builder/factories/update-many-resolver.factory';
|
||||
import { WorkspaceResolverBuilderService } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service';
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
@ -45,7 +44,6 @@ export class WorkspaceResolverFactory {
|
||||
private readonly restoreOneResolverFactory: RestoreOneResolverFactory,
|
||||
private readonly restoreManyResolverFactory: RestoreManyResolverFactory,
|
||||
private readonly destroyManyResolverFactory: DestroyManyResolverFactory,
|
||||
private readonly searchResolverFactory: SearchResolverFactory,
|
||||
private readonly workspaceResolverBuilderService: WorkspaceResolverBuilderService,
|
||||
) {}
|
||||
|
||||
@ -69,7 +67,6 @@ export class WorkspaceResolverFactory {
|
||||
['findOne', this.findOneResolverFactory],
|
||||
['restoreMany', this.restoreManyResolverFactory],
|
||||
['restoreOne', this.restoreOneResolverFactory],
|
||||
['search', this.searchResolverFactory],
|
||||
['updateMany', this.updateManyResolverFactory],
|
||||
['updateOne', this.updateOneResolverFactory],
|
||||
]);
|
||||
|
||||
@ -138,7 +138,6 @@ export class RootTypeFactory {
|
||||
switch (methodName) {
|
||||
case 'findMany':
|
||||
case 'findDuplicates':
|
||||
case 'search':
|
||||
return ObjectTypeDefinitionKind.Connection;
|
||||
default:
|
||||
return ObjectTypeDefinitionKind.Plain;
|
||||
|
||||
@ -144,21 +144,6 @@ export const getResolverArgs = (
|
||||
isNullable: false,
|
||||
},
|
||||
};
|
||||
case 'search':
|
||||
return {
|
||||
searchInput: {
|
||||
type: GraphQLString,
|
||||
isNullable: true,
|
||||
},
|
||||
limit: {
|
||||
type: GraphQLInt,
|
||||
isNullable: true,
|
||||
},
|
||||
filter: {
|
||||
kind: InputTypeDefinitionKind.Filter,
|
||||
isNullable: true,
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error(`Unknown resolver type: ${type}`);
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-
|
||||
import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module';
|
||||
import { fileStorageModuleFactory } from 'src/engine/core-modules/file-storage/file-storage.module-factory';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { GlobalSearchModule } from 'src/engine/core-modules/global-search/global-search.module';
|
||||
import { HealthModule } from 'src/engine/core-modules/health/health.module';
|
||||
import { LabModule } from 'src/engine/core-modules/lab/lab.module';
|
||||
import { LLMChatModelModule } from 'src/engine/core-modules/llm-chat-model/llm-chat-model.module';
|
||||
@ -38,6 +37,7 @@ import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module'
|
||||
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
|
||||
import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module';
|
||||
import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service';
|
||||
import { SearchModule } from 'src/engine/core-modules/search/search.module';
|
||||
import { serverlessModuleFactory } from 'src/engine/core-modules/serverless/serverless-module.factory';
|
||||
import { ServerlessModule } from 'src/engine/core-modules/serverless/serverless.module';
|
||||
import { WorkspaceSSOModule } from 'src/engine/core-modules/sso/sso.module';
|
||||
@ -121,7 +121,7 @@ import { FileModule } from './file/file.module';
|
||||
useFactory: serverlessModuleFactory,
|
||||
inject: [EnvironmentService, FileStorageService],
|
||||
}),
|
||||
GlobalSearchModule,
|
||||
SearchModule,
|
||||
],
|
||||
exports: [
|
||||
AnalyticsModule,
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/global-search/__mocks__/mockObjectMetadataItemsWithFieldMaps';
|
||||
import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service';
|
||||
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/search/__mocks__/mockObjectMetadataItemsWithFieldMaps';
|
||||
import { SearchService } from 'src/engine/core-modules/search/services/search.service';
|
||||
|
||||
describe('GlobalSearchService', () => {
|
||||
let service: GlobalSearchService;
|
||||
describe('SearchService', () => {
|
||||
let service: SearchService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [GlobalSearchService],
|
||||
providers: [SearchService],
|
||||
}).compile();
|
||||
|
||||
service = module.get<GlobalSearchService>(GlobalSearchService);
|
||||
service = module.get<SearchService>(SearchService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
@ -103,7 +103,7 @@ describe('GlobalSearchService', () => {
|
||||
it('should sort the search object results by tsRankCD', () => {
|
||||
const objectResults = [
|
||||
{
|
||||
objectSingularName: 'person',
|
||||
objectNameSingular: 'person',
|
||||
tsRankCD: 2,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -111,7 +111,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'company',
|
||||
objectNameSingular: 'company',
|
||||
tsRankCD: 1,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -119,7 +119,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'regular-custom-object',
|
||||
objectNameSingular: 'regular-custom-object',
|
||||
tsRankCD: 3,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -138,7 +138,7 @@ describe('GlobalSearchService', () => {
|
||||
it('should sort the search object results by tsRank, if tsRankCD is the same', () => {
|
||||
const objectResults = [
|
||||
{
|
||||
objectSingularName: 'person',
|
||||
objectNameSingular: 'person',
|
||||
tsRankCD: 1,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -146,7 +146,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'company',
|
||||
objectNameSingular: 'company',
|
||||
tsRankCD: 1,
|
||||
tsRank: 2,
|
||||
recordId: '',
|
||||
@ -154,7 +154,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'regular-custom-object',
|
||||
objectNameSingular: 'regular-custom-object',
|
||||
tsRankCD: 1,
|
||||
tsRank: 3,
|
||||
recordId: '',
|
||||
@ -173,7 +173,7 @@ describe('GlobalSearchService', () => {
|
||||
it('should sort the search object results by priority rank, if tsRankCD and tsRank are the same', () => {
|
||||
const objectResults = [
|
||||
{
|
||||
objectSingularName: 'company',
|
||||
objectNameSingular: 'company',
|
||||
tsRankCD: 1,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -181,7 +181,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'person',
|
||||
objectNameSingular: 'person',
|
||||
tsRankCD: 1,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -189,7 +189,7 @@ describe('GlobalSearchService', () => {
|
||||
imageUrl: '',
|
||||
},
|
||||
{
|
||||
objectSingularName: 'regular-custom-object',
|
||||
objectNameSingular: 'regular-custom-object',
|
||||
tsRankCD: 1,
|
||||
tsRank: 1,
|
||||
recordId: '',
|
||||
@ -2,10 +2,10 @@ import { ArgsType, Field, Int } from '@nestjs/graphql';
|
||||
|
||||
import { IsArray, IsInt, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
import { ObjectRecordFilterInput } from 'src/engine/core-modules/global-search/dtos/object-record-filter-input';
|
||||
import { ObjectRecordFilterInput } from 'src/engine/core-modules/search/dtos/object-record-filter-input';
|
||||
|
||||
@ArgsType()
|
||||
export class GlobalSearchArgs {
|
||||
export class SearchArgs {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
searchInput: string;
|
||||
@ -2,8 +2,8 @@ import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
@ObjectType('GlobalSearchRecord')
|
||||
export class GlobalSearchRecordDTO {
|
||||
@ObjectType('SearchRecord')
|
||||
export class SearchRecordDTO {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@ -12,7 +12,7 @@ export class GlobalSearchRecordDTO {
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
objectSingularName: string;
|
||||
objectNameSingular: string;
|
||||
|
||||
@Field(() => String)
|
||||
@IsString()
|
||||
@ -1,12 +1,12 @@
|
||||
import { CustomException } from 'src/utils/custom-exception';
|
||||
|
||||
export class GlobalSearchException extends CustomException {
|
||||
constructor(message: string, code: GlobalSearchExceptionCode) {
|
||||
export class SearchException extends CustomException {
|
||||
constructor(message: string, code: SearchExceptionCode) {
|
||||
super(message, code);
|
||||
}
|
||||
}
|
||||
|
||||
export enum GlobalSearchExceptionCode {
|
||||
export enum SearchExceptionCode {
|
||||
METADATA_CACHE_VERSION_NOT_FOUND = 'METADATA_CACHE_VERSION_NOT_FOUND',
|
||||
LABEL_IDENTIFIER_FIELD_NOT_FOUND = 'LABEL_IDENTIFIER_FIELD_NOT_FOUND',
|
||||
OBJECT_METADATA_MAP_NOT_FOUND = 'OBJECT_METADATA_MAP_NOT_FOUND',
|
||||
@ -1,13 +1,13 @@
|
||||
import { Catch, ExceptionFilter } from '@nestjs/common';
|
||||
|
||||
import { GlobalSearchException } from 'src/engine/core-modules/global-search/exceptions/global-search.exception';
|
||||
import { InternalServerError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { SearchException } from 'src/engine/core-modules/search/exceptions/search.exception';
|
||||
|
||||
@Catch(GlobalSearchException)
|
||||
export class GlobalSearchApiExceptionFilter implements ExceptionFilter {
|
||||
@Catch(SearchException)
|
||||
export class SearchApiExceptionFilter implements ExceptionFilter {
|
||||
constructor() {}
|
||||
|
||||
catch(exception: GlobalSearchException) {
|
||||
catch(exception: SearchException) {
|
||||
switch (exception.code) {
|
||||
default:
|
||||
throw new InternalServerError(exception.message);
|
||||
@ -1,12 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { GlobalSearchResolver } from 'src/engine/core-modules/global-search/global-search.resolver';
|
||||
import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service';
|
||||
import { SearchResolver } from 'src/engine/core-modules/search/search.resolver';
|
||||
import { SearchService } from 'src/engine/core-modules/search/services/search.service';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceCacheStorageModule, FeatureFlagModule],
|
||||
providers: [GlobalSearchResolver, GlobalSearchService],
|
||||
providers: [SearchResolver, SearchService],
|
||||
})
|
||||
export class GlobalSearchModule {}
|
||||
export class SearchModule {}
|
||||
@ -6,16 +6,16 @@ import chunk from 'lodash.chunk';
|
||||
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { GlobalSearchArgs } from 'src/engine/core-modules/global-search/dtos/global-search-args';
|
||||
import { GlobalSearchRecordDTO } from 'src/engine/core-modules/global-search/dtos/global-search-record-dto';
|
||||
import { SearchArgs } from 'src/engine/core-modules/search/dtos/search-args';
|
||||
import { SearchRecordDTO } from 'src/engine/core-modules/search/dtos/search-record-dto';
|
||||
import {
|
||||
GlobalSearchException,
|
||||
GlobalSearchExceptionCode,
|
||||
} from 'src/engine/core-modules/global-search/exceptions/global-search.exception';
|
||||
import { GlobalSearchApiExceptionFilter } from 'src/engine/core-modules/global-search/filters/global-search-api-exception.filter';
|
||||
import { GlobalSearchService } from 'src/engine/core-modules/global-search/services/global-search.service';
|
||||
import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/global-search/types/records-with-object-metadata-item';
|
||||
import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms';
|
||||
SearchException,
|
||||
SearchExceptionCode,
|
||||
} from 'src/engine/core-modules/search/exceptions/search.exception';
|
||||
import { SearchApiExceptionFilter } from 'src/engine/core-modules/search/filters/search-api-exception.filter';
|
||||
import { SearchService } from 'src/engine/core-modules/search/services/search.service';
|
||||
import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/search/types/records-with-object-metadata-item';
|
||||
import { formatSearchTerms } from 'src/engine/core-modules/search/utils/format-search-terms';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
@ -23,18 +23,18 @@ import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage
|
||||
|
||||
const OBJECT_METADATA_ITEMS_CHUNK_SIZE = 5;
|
||||
|
||||
@Resolver(() => [GlobalSearchRecordDTO])
|
||||
@UseFilters(GlobalSearchApiExceptionFilter)
|
||||
export class GlobalSearchResolver {
|
||||
@Resolver(() => [SearchRecordDTO])
|
||||
@UseFilters(SearchApiExceptionFilter)
|
||||
export class SearchResolver {
|
||||
constructor(
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
private readonly twentyORMManager: TwentyORMManager,
|
||||
private readonly globalSearchService: GlobalSearchService,
|
||||
private readonly searchService: SearchService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
@Query(() => [GlobalSearchRecordDTO])
|
||||
async globalSearch(
|
||||
@Query(() => [SearchRecordDTO])
|
||||
async search(
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args()
|
||||
{
|
||||
@ -43,15 +43,15 @@ export class GlobalSearchResolver {
|
||||
filter,
|
||||
includedObjectNameSingulars,
|
||||
excludedObjectNameSingulars,
|
||||
}: GlobalSearchArgs,
|
||||
}: SearchArgs,
|
||||
) {
|
||||
const currentCacheVersion =
|
||||
await this.workspaceCacheStorageService.getMetadataVersion(workspace.id);
|
||||
|
||||
if (currentCacheVersion === undefined) {
|
||||
throw new GlobalSearchException(
|
||||
throw new SearchException(
|
||||
'Metadata cache version not found',
|
||||
GlobalSearchExceptionCode.METADATA_CACHE_VERSION_NOT_FOUND,
|
||||
SearchExceptionCode.METADATA_CACHE_VERSION_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
@ -62,9 +62,9 @@ export class GlobalSearchResolver {
|
||||
);
|
||||
|
||||
if (!objectMetadataMaps) {
|
||||
throw new GlobalSearchException(
|
||||
throw new SearchException(
|
||||
`Object metadata map not found for workspace ${workspace.id} and metadata version ${currentCacheVersion}`,
|
||||
GlobalSearchExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND,
|
||||
SearchExceptionCode.OBJECT_METADATA_MAP_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ export class GlobalSearchResolver {
|
||||
);
|
||||
|
||||
const filteredObjectMetadataItems =
|
||||
this.globalSearchService.filterObjectMetadataItems({
|
||||
this.searchService.filterObjectMetadataItems({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
includedObjectNameSingulars: includedObjectNameSingulars ?? [],
|
||||
excludedObjectNameSingulars: excludedObjectNameSingulars ?? [],
|
||||
@ -99,16 +99,15 @@ export class GlobalSearchResolver {
|
||||
|
||||
return {
|
||||
objectMetadataItem,
|
||||
records:
|
||||
await this.globalSearchService.buildSearchQueryAndGetRecords({
|
||||
entityManager: repository,
|
||||
objectMetadataItem,
|
||||
featureFlagMap,
|
||||
searchTerms: formatSearchTerms(searchInput, 'and'),
|
||||
searchTermsOr: formatSearchTerms(searchInput, 'or'),
|
||||
limit,
|
||||
filter: filter ?? ({} as ObjectRecordFilter),
|
||||
}),
|
||||
records: await this.searchService.buildSearchQueryAndGetRecords({
|
||||
entityManager: repository,
|
||||
objectMetadataItem,
|
||||
featureFlagMap,
|
||||
searchTerms: formatSearchTerms(searchInput, 'and'),
|
||||
searchTermsOr: formatSearchTerms(searchInput, 'or'),
|
||||
limit,
|
||||
filter: filter ?? ({} as ObjectRecordFilter),
|
||||
}),
|
||||
};
|
||||
}),
|
||||
);
|
||||
@ -116,7 +115,7 @@ export class GlobalSearchResolver {
|
||||
allRecordsWithObjectMetadataItems.push(...recordsWithObjectMetadataItems);
|
||||
}
|
||||
|
||||
return this.globalSearchService.computeSearchObjectResults(
|
||||
return this.searchService.computeSearchObjectResults(
|
||||
allRecordsWithObjectMetadataItems,
|
||||
limit,
|
||||
);
|
||||
@ -8,22 +8,22 @@ import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/int
|
||||
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
|
||||
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { RESULTS_LIMIT_BY_OBJECT_WITHOUT_SEARCH_TERMS } from 'src/engine/core-modules/global-search/constants/results-limit-by-object-without-search-terms';
|
||||
import { STANDARD_OBJECTS_BY_PRIORITY_RANK } from 'src/engine/core-modules/global-search/constants/standard-objects-by-priority-rank';
|
||||
import { GlobalSearchRecordDTO } from 'src/engine/core-modules/global-search/dtos/global-search-record-dto';
|
||||
import { ObjectRecordFilterInput } from 'src/engine/core-modules/global-search/dtos/object-record-filter-input';
|
||||
import { RESULTS_LIMIT_BY_OBJECT_WITHOUT_SEARCH_TERMS } from 'src/engine/core-modules/search/constants/results-limit-by-object-without-search-terms';
|
||||
import { STANDARD_OBJECTS_BY_PRIORITY_RANK } from 'src/engine/core-modules/search/constants/standard-objects-by-priority-rank';
|
||||
import { ObjectRecordFilterInput } from 'src/engine/core-modules/search/dtos/object-record-filter-input';
|
||||
import { SearchRecordDTO } from 'src/engine/core-modules/search/dtos/search-record-dto';
|
||||
import {
|
||||
GlobalSearchException,
|
||||
GlobalSearchExceptionCode,
|
||||
} from 'src/engine/core-modules/global-search/exceptions/global-search.exception';
|
||||
import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/global-search/types/records-with-object-metadata-item';
|
||||
SearchException,
|
||||
SearchExceptionCode,
|
||||
} from 'src/engine/core-modules/search/exceptions/search.exception';
|
||||
import { RecordsWithObjectMetadataItem } from 'src/engine/core-modules/search/types/records-with-object-metadata-item';
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
import { generateObjectMetadataMaps } from 'src/engine/metadata-modules/utils/generate-object-metadata-maps.util';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
|
||||
@Injectable()
|
||||
export class GlobalSearchService {
|
||||
export class SearchService {
|
||||
filterObjectMetadataItems({
|
||||
objectMetadataItemWithFieldMaps,
|
||||
includedObjectNameSingulars,
|
||||
@ -143,9 +143,9 @@ export class GlobalSearchService {
|
||||
objectMetadataItem: ObjectMetadataItemWithFieldMaps,
|
||||
) {
|
||||
if (!objectMetadataItem.labelIdentifierFieldMetadataId) {
|
||||
throw new GlobalSearchException(
|
||||
throw new SearchException(
|
||||
'Label identifier field not found',
|
||||
GlobalSearchExceptionCode.LABEL_IDENTIFIER_FIELD_NOT_FOUND,
|
||||
SearchExceptionCode.LABEL_IDENTIFIER_FIELD_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ export class GlobalSearchService {
|
||||
return records.map((record) => {
|
||||
return {
|
||||
recordId: record.id,
|
||||
objectSingularName: objectMetadataItem.nameSingular,
|
||||
objectNameSingular: objectMetadataItem.nameSingular,
|
||||
label: this.getLabelIdentifierValue(record, objectMetadataItem),
|
||||
imageUrl: this.getImageIdentifierValue(record, objectMetadataItem),
|
||||
tsRankCD: record.tsRankCD,
|
||||
@ -230,9 +230,7 @@ export class GlobalSearchService {
|
||||
return this.sortSearchObjectResults(searchRecords).slice(0, limit);
|
||||
}
|
||||
|
||||
sortSearchObjectResults(
|
||||
searchObjectResultsWithRank: GlobalSearchRecordDTO[],
|
||||
) {
|
||||
sortSearchObjectResults(searchObjectResultsWithRank: SearchRecordDTO[]) {
|
||||
return searchObjectResultsWithRank.sort((a, b) => {
|
||||
if (a.tsRankCD !== b.tsRankCD) {
|
||||
return b.tsRankCD - a.tsRankCD;
|
||||
@ -243,8 +241,8 @@ export class GlobalSearchService {
|
||||
}
|
||||
|
||||
return (
|
||||
(STANDARD_OBJECTS_BY_PRIORITY_RANK[b.objectSingularName] || 0) -
|
||||
(STANDARD_OBJECTS_BY_PRIORITY_RANK[a.objectSingularName] || 0)
|
||||
(STANDARD_OBJECTS_BY_PRIORITY_RANK[b.objectNameSingular] || 0) -
|
||||
(STANDARD_OBJECTS_BY_PRIORITY_RANK[a.objectNameSingular] || 0)
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { formatSearchTerms } from 'src/engine/core-modules/global-search/utils/format-search-terms';
|
||||
import { formatSearchTerms } from 'src/engine/core-modules/search/utils/format-search-terms';
|
||||
|
||||
describe('formatSearchTerms', () => {
|
||||
it('should format the search terms', () => {
|
||||
@ -27,7 +27,7 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi
|
||||
import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter';
|
||||
import { RelationMetadataEntity } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { RemoteTableRelationsModule } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/remote-table-relations.module';
|
||||
import { SearchModule } from 'src/engine/metadata-modules/search/search.module';
|
||||
import { SearchVectorModule } from 'src/engine/metadata-modules/search-vector/search-vector.module';
|
||||
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
|
||||
@ -54,7 +54,7 @@ import { UpdateObjectPayload } from './dtos/update-object.input';
|
||||
WorkspaceMigrationRunnerModule,
|
||||
WorkspaceMetadataVersionModule,
|
||||
RemoteTableRelationsModule,
|
||||
SearchModule,
|
||||
SearchVectorModule,
|
||||
IndexMetadataModule,
|
||||
FeatureFlagModule,
|
||||
PermissionsModule,
|
||||
|
||||
@ -31,7 +31,7 @@ import {
|
||||
validateObjectMetadataInputNamesOrThrow,
|
||||
} from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util';
|
||||
import { RemoteTableRelationsService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table-relations/remote-table-relations.service';
|
||||
import { SearchService } from 'src/engine/metadata-modules/search/search.service';
|
||||
import { SearchVectorService } from 'src/engine/metadata-modules/search-vector/search-vector.service';
|
||||
import { validateNameAndLabelAreSyncOrThrow } from 'src/engine/metadata-modules/utils/validate-name-and-label-are-sync-or-throw.util';
|
||||
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
@ -56,7 +56,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
|
||||
private readonly searchService: SearchService,
|
||||
private readonly searchVectorService: SearchVectorService,
|
||||
private readonly objectMetadataRelationService: ObjectMetadataRelationService,
|
||||
private readonly objectMetadataMigrationService: ObjectMetadataMigrationService,
|
||||
private readonly objectMetadataRelatedRecordsService: ObjectMetadataRelatedRecordsService,
|
||||
@ -187,7 +187,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
createdRelatedObjectMetadataCollection,
|
||||
);
|
||||
|
||||
await this.searchService.createSearchVectorFieldForObject(
|
||||
await this.searchVectorService.createSearchVectorFieldForObject(
|
||||
objectMetadataInput,
|
||||
createdObjectMetadata,
|
||||
);
|
||||
@ -292,7 +292,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
});
|
||||
|
||||
if (isSearchableFieldType(labelIdentifierFieldMetadata.type)) {
|
||||
await this.searchService.updateSearchVector(
|
||||
await this.searchVectorService.updateSearchVector(
|
||||
input.id,
|
||||
[
|
||||
{
|
||||
|
||||
@ -5,7 +5,7 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { IndexMetadataModule } from 'src/engine/metadata-modules/index-metadata/index-metadata.module';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SearchService } from 'src/engine/metadata-modules/search/search.service';
|
||||
import { SearchVectorService } from 'src/engine/metadata-modules/search-vector/search-vector.service';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
|
||||
@Module({
|
||||
@ -17,7 +17,7 @@ import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-
|
||||
IndexMetadataModule,
|
||||
WorkspaceMigrationModule,
|
||||
],
|
||||
providers: [SearchService],
|
||||
exports: [SearchService],
|
||||
providers: [SearchVectorService],
|
||||
exports: [SearchVectorService],
|
||||
})
|
||||
export class SearchModule {}
|
||||
export class SearchVectorModule {}
|
||||
@ -31,7 +31,7 @@ import {
|
||||
import { SearchableFieldType } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-searchable-field.util';
|
||||
|
||||
@Injectable()
|
||||
export class SearchService {
|
||||
export class SearchVectorService {
|
||||
constructor(
|
||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||
@ -41,8 +41,6 @@ export const getResolverName = (
|
||||
case 'restoreMany':
|
||||
return `restore${pascalCase(objectMetadata.namePlural)}`;
|
||||
|
||||
case 'search':
|
||||
return `search${pascalCase(objectMetadata.namePlural)}`;
|
||||
default:
|
||||
throw new Error(`Unknown resolver type: ${type}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user