Steps to test

1. Run metadata migrations
2. Run sync-metadata on your workspace
3. Enable the following feature flags: 
IS_SEARCH_ENABLED
IS_QUERY_RUNNER_TWENTY_ORM_ENABLED
IS_WORKSPACE_MIGRATED_FOR_SEARCH
4. Type Cmd + K and search anything
This commit is contained in:
Marie
2024-10-03 17:18:49 +02:00
committed by GitHub
parent 4c250dd811
commit 5f9435c718
71 changed files with 1517 additions and 209 deletions
@@ -0,0 +1,100 @@
import {
GraphQLFieldConfigMap,
GraphQLInputFieldConfigMap,
GraphQLInputType,
GraphQLOutputType,
} from 'graphql';
import { WorkspaceBuildSchemaOptions } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/workspace-build-schema-optionts.interface';
import { ObjectMetadataInterface } from 'src/engine/metadata-modules/field-metadata/interfaces/object-metadata.interface';
import { InputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/input-type-definition.factory';
import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/factories/object-type-definition.factory';
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
import { isRelationFieldMetadataType } from 'src/engine/utils/is-relation-field-metadata-type.util';
type TypeFactory<T extends InputTypeDefinitionKind | ObjectTypeDefinitionKind> =
{
create: (
target: string,
fieldType: FieldMetadataType,
kind: T,
options: WorkspaceBuildSchemaOptions,
additionalOptions: {
nullable?: boolean;
defaultValue?: any;
isArray: boolean;
settings: any;
isIdField: boolean;
},
) => T extends InputTypeDefinitionKind
? GraphQLInputType
: GraphQLOutputType;
};
export const generateFields = <
T extends InputTypeDefinitionKind | ObjectTypeDefinitionKind,
>(
objectMetadata: ObjectMetadataInterface,
kind: T,
options: WorkspaceBuildSchemaOptions,
typeFactory: TypeFactory<T>,
): T extends InputTypeDefinitionKind
? GraphQLInputFieldConfigMap
: GraphQLFieldConfigMap<any, any> => {
const fields = {};
for (const fieldMetadata of objectMetadata.fields) {
if (
isRelationFieldMetadataType(fieldMetadata.type) ||
fieldMetadata.type === FieldMetadataType.TS_VECTOR
) {
continue;
}
const target = isCompositeFieldMetadataType(fieldMetadata.type)
? fieldMetadata.type.toString()
: fieldMetadata.id;
const typeFactoryOptions = isInputTypeDefinitionKind(kind)
? {
nullable: fieldMetadata.isNullable,
defaultValue: fieldMetadata.defaultValue,
isArray: fieldMetadata.type === FieldMetadataType.MULTI_SELECT,
settings: fieldMetadata.settings,
isIdField: fieldMetadata.name === 'id',
}
: {
nullable: fieldMetadata.isNullable,
isArray: fieldMetadata.type === FieldMetadataType.MULTI_SELECT,
settings: fieldMetadata.settings,
// Scalar type is already defined in the entity itself.
isIdField: false,
};
const type = typeFactory.create(
target,
fieldMetadata.type,
kind,
options,
typeFactoryOptions,
);
fields[fieldMetadata.name] = {
type,
description: fieldMetadata.description,
};
}
return fields;
};
// Type guard
const isInputTypeDefinitionKind = (
kind: InputTypeDefinitionKind | ObjectTypeDefinitionKind,
): kind is InputTypeDefinitionKind => {
return Object.values(InputTypeDefinitionKind).includes(
kind as InputTypeDefinitionKind,
);
};
@@ -137,6 +137,17 @@ export const getResolverArgs = (
isNullable: false,
},
};
case 'search':
return {
searchInput: {
type: GraphQLString,
isNullable: true,
},
limit: {
type: GraphQLInt,
isNullable: true,
},
};
default:
throw new Error(`Unknown resolver type: ${type}`);
}