fix blocklist (#18332)
- The schema generator marked both the FK scalar and connect relation input as required for non-nullable `MANY_TO_ONE` relations, but the resolver rejects when both are provided making create mutations impossible - Fixed by making the connect input always optional in create input types (the FK scalar still enforces the constraint) - Added `createOne` pre-query hook for blocklist with ownership validation https://github.com/user-attachments/assets/aaae83d4-4747-4d16-a87c-8d8cad79d25d --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+4
-7
@@ -5,18 +5,15 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ArgsMetadata } from 'src/engine/api/graphql/workspace-schema-builder/interfaces/param-metadata.interface';
|
||||
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { computeObjectMetadataInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-input-type.util';
|
||||
|
||||
@Injectable()
|
||||
export class ArgsTypeGenerator {
|
||||
private readonly logger = new Logger(ArgsTypeGenerator.name);
|
||||
|
||||
constructor(
|
||||
private readonly typeMapperService: TypeMapperService,
|
||||
private readonly gqlTypesStorage: GqlTypesStorage,
|
||||
) {}
|
||||
constructor(private readonly gqlTypesStorage: GqlTypesStorage) {}
|
||||
|
||||
public generate({
|
||||
args,
|
||||
@@ -33,7 +30,7 @@ export class ArgsTypeGenerator {
|
||||
|
||||
// Argument is a scalar type
|
||||
if (isDefined(arg.type)) {
|
||||
const gqlType = this.typeMapperService.applyTypeOptions(arg.type, {
|
||||
const gqlType = applyTypeOptionsForOutputType(arg.type, {
|
||||
defaultValue: arg.defaultValue,
|
||||
nullable: arg.isNullable,
|
||||
isArray: arg.isArray,
|
||||
@@ -66,7 +63,7 @@ export class ArgsTypeGenerator {
|
||||
);
|
||||
}
|
||||
|
||||
const gqlType = this.typeMapperService.applyTypeOptions(inputType, {
|
||||
const gqlType = applyTypeOptionsForOutputType(inputType, {
|
||||
nullable: arg.isNullable,
|
||||
isArray: arg.isArray,
|
||||
});
|
||||
|
||||
+2
-4
@@ -11,6 +11,7 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
import { GqlInputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-input-type-definition-kind.enum';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForCreateInput } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-create-input.util';
|
||||
import { computeCompositeFieldTypeOptions } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-composite-field-type-options.util';
|
||||
import { computeCompositeFieldEnumTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-enum-type-key.util';
|
||||
import { computeCompositeFieldInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-input-type-key.util';
|
||||
@@ -87,10 +88,7 @@ export class CompositeFieldMetadataCreateGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForCreateInput(type, typeOptions);
|
||||
|
||||
fields[property.name] = {
|
||||
type: modifiedType,
|
||||
|
||||
+11
-13
@@ -11,12 +11,13 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
|
||||
import { GqlInputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-input-type-definition-kind.enum';
|
||||
import { RelationFieldMetadataGqlInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator';
|
||||
import {
|
||||
TypeMapperService,
|
||||
TypeOptions,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type';
|
||||
import {
|
||||
type CreateInputTypeOptions,
|
||||
applyTypeOptionsForCreateInput,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-create-input.util';
|
||||
import { computeFieldInputTypeOptions } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-field-input-type-options.util';
|
||||
import { computeCompositeFieldInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-input-type-key.util';
|
||||
import { computeEnumFieldGqlTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-enum-field-gql-type-key.util';
|
||||
@@ -116,7 +117,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
private generateEnumFieldCreateInputType(
|
||||
objectNameSingular: string,
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
typeOptions: CreateInputTypeOptions,
|
||||
) {
|
||||
const key = computeEnumFieldGqlTypeKey(
|
||||
objectNameSingular,
|
||||
@@ -135,7 +136,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedEnumType = this.typeMapperService.applyTypeOptions(
|
||||
const modifiedEnumType = applyTypeOptionsForCreateInput(
|
||||
enumType,
|
||||
typeOptions,
|
||||
);
|
||||
@@ -150,7 +151,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
|
||||
private generateCompositeFieldCreateInputType(
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
typeOptions: CreateInputTypeOptions,
|
||||
) {
|
||||
const key = computeCompositeFieldInputTypeKey(
|
||||
fieldMetadata.type,
|
||||
@@ -169,7 +170,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedCompositeType = this.typeMapperService.applyTypeOptions(
|
||||
const modifiedCompositeType = applyTypeOptionsForCreateInput(
|
||||
compositeType,
|
||||
typeOptions,
|
||||
);
|
||||
@@ -184,7 +185,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
|
||||
private generateAtomicFieldCreateInputType(
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
typeOptions: CreateInputTypeOptions,
|
||||
) {
|
||||
const type = this.typeMapperService.mapToPreBuiltGraphQLInputType({
|
||||
fieldMetadataType: fieldMetadata.type,
|
||||
@@ -201,10 +202,7 @@ export class ObjectMetadataCreateGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForCreateInput(type, typeOptions);
|
||||
|
||||
return {
|
||||
[fieldMetadata.name]: {
|
||||
|
||||
+1
-6
@@ -101,13 +101,8 @@ export class CompositeFieldMetadataFilterGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
|
||||
fields[property.name] = {
|
||||
type: modifiedType,
|
||||
type,
|
||||
description: property.description,
|
||||
};
|
||||
}
|
||||
|
||||
+8
-24
@@ -3,6 +3,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||
import {
|
||||
GraphQLInputFieldConfigMap,
|
||||
GraphQLInputObjectType,
|
||||
GraphQLList,
|
||||
isEnumType,
|
||||
isInputObjectType,
|
||||
isObjectType,
|
||||
@@ -11,10 +12,7 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
|
||||
import { GqlInputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-input-type-definition-kind.enum';
|
||||
import { RelationFieldMetadataGqlInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-field-metadata-gql-type.generator';
|
||||
import {
|
||||
TypeMapperService,
|
||||
TypeOptions,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { computeFieldInputTypeOptions } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-field-input-type-options.util';
|
||||
import { computeCompositeFieldInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-input-type-key.util';
|
||||
@@ -62,11 +60,6 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
fields: FlatFieldMetadata[],
|
||||
inputType: GraphQLInputObjectType,
|
||||
): GraphQLInputFieldConfigMap {
|
||||
const andOrType = this.typeMapperService.applyTypeOptions(inputType, {
|
||||
isArray: true,
|
||||
arrayDepth: 1,
|
||||
nullable: true,
|
||||
});
|
||||
const allGeneratedFields: GraphQLInputFieldConfigMap = {};
|
||||
|
||||
for (const fieldMetadata of fields) {
|
||||
@@ -94,13 +87,10 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
generatedFields = this.generateEnumFieldFilterInputType(
|
||||
objectNameSingular,
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
);
|
||||
} else if (isCompositeFieldMetadataType(fieldMetadata.type)) {
|
||||
generatedFields = this.generateCompositeFieldFilterInputType(
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
);
|
||||
generatedFields =
|
||||
this.generateCompositeFieldFilterInputType(fieldMetadata);
|
||||
} else {
|
||||
generatedFields = this.generateAtomicFieldFilterInputType(
|
||||
fieldMetadata,
|
||||
@@ -113,15 +103,13 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
return {
|
||||
...allGeneratedFields,
|
||||
and: {
|
||||
type: andOrType,
|
||||
type: new GraphQLList(inputType),
|
||||
},
|
||||
or: {
|
||||
type: andOrType,
|
||||
type: new GraphQLList(inputType),
|
||||
},
|
||||
not: {
|
||||
type: this.typeMapperService.applyTypeOptions(inputType, {
|
||||
nullable: true,
|
||||
}),
|
||||
type: inputType,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -129,7 +117,6 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
private generateEnumFieldFilterInputType(
|
||||
objectNameSingular: string,
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
) {
|
||||
const key = computeEnumFieldGqlTypeKey(
|
||||
objectNameSingular,
|
||||
@@ -143,7 +130,6 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
|
||||
this.logger.error(message, {
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
});
|
||||
throw new Error(message);
|
||||
}
|
||||
@@ -160,7 +146,6 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
|
||||
private generateCompositeFieldFilterInputType(
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
) {
|
||||
const key = computeCompositeFieldInputTypeKey(
|
||||
fieldMetadata.type,
|
||||
@@ -174,7 +159,6 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
|
||||
this.logger.error(message, {
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
});
|
||||
throw new Error(message);
|
||||
}
|
||||
@@ -189,7 +173,7 @@ export class ObjectMetadataFilterGqlInputTypeGenerator {
|
||||
|
||||
private generateAtomicFieldFilterInputType(
|
||||
fieldMetadata: FlatFieldMetadata,
|
||||
typeOptions: TypeOptions,
|
||||
typeOptions: { settings?: FlatFieldMetadata['settings'] },
|
||||
) {
|
||||
const type = this.typeMapperService.mapToFilterType(
|
||||
fieldMetadata.type,
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ export class CompositeFieldMetadataGroupByGqlInputTypeGenerator {
|
||||
continue;
|
||||
}
|
||||
|
||||
const type = this.typeMapperService.applyTypeOptions(GraphQLBoolean, {});
|
||||
const type = GraphQLBoolean;
|
||||
|
||||
fields[property.name] = {
|
||||
type,
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ export class ObjectMetadataGroupByGqlInputTypeGenerator {
|
||||
|
||||
type = groupByDateGranularityInputType;
|
||||
} else {
|
||||
type = this.typeMapperService.applyTypeOptions(GraphQLBoolean, {});
|
||||
type = GraphQLBoolean;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
+1
-6
@@ -76,13 +76,8 @@ export class CompositeFieldMetadataOrderByGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
|
||||
fields[property.name] = {
|
||||
type: modifiedType,
|
||||
type,
|
||||
description: property.description,
|
||||
};
|
||||
}
|
||||
|
||||
-1
@@ -58,7 +58,6 @@ export class ObjectMetadataOrderByBaseGenerator {
|
||||
this.relationFieldMetadataGqlInputTypeGenerator.generateSimpleRelationFieldOrderByInputType(
|
||||
{
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
isForGroupBy,
|
||||
context,
|
||||
},
|
||||
|
||||
-1
@@ -101,7 +101,6 @@ export class ObjectMetadataOrderByWithGroupByGqlInputTypeGenerator {
|
||||
this.relationFieldMetadataGqlInputTypeGenerator.generateSimpleRelationFieldOrderByInputType(
|
||||
{
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
context,
|
||||
},
|
||||
);
|
||||
|
||||
+18
-27
@@ -9,12 +9,13 @@ import { FieldMetadataType, RelationType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { GqlInputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-input-type-definition-kind.enum';
|
||||
import {
|
||||
TypeMapperService,
|
||||
TypeOptions,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type';
|
||||
import {
|
||||
type CreateInputTypeOptions,
|
||||
applyTypeOptionsForCreateInput,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-create-input.util';
|
||||
import { computeObjectMetadataInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-input-type.util';
|
||||
import { computeRelationConnectInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-relation-connect-input-type-key.util';
|
||||
import { extractGraphQLRelationFieldNames } from 'src/engine/api/graphql/workspace-schema-builder/utils/extract-graphql-relation-field-names.util';
|
||||
@@ -39,7 +40,7 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
fieldMetadata: FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
typeOptions: TypeOptions;
|
||||
typeOptions: CreateInputTypeOptions;
|
||||
}) {
|
||||
if (fieldMetadata.settings?.relationType === RelationType.ONE_TO_MANY)
|
||||
return {};
|
||||
@@ -61,10 +62,10 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForCreateInput(type, {
|
||||
...typeOptions,
|
||||
nullable: true,
|
||||
});
|
||||
|
||||
return {
|
||||
[joinColumnName]: {
|
||||
@@ -81,7 +82,7 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
fieldMetadata: FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
typeOptions: TypeOptions;
|
||||
typeOptions: { settings?: FlatFieldMetadata['settings'] };
|
||||
}) {
|
||||
if (fieldMetadata.settings?.relationType === RelationType.ONE_TO_MANY)
|
||||
return {};
|
||||
@@ -103,14 +104,9 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
|
||||
return {
|
||||
[joinColumnName]: {
|
||||
type: modifiedType,
|
||||
type,
|
||||
description: fieldMetadata.description,
|
||||
},
|
||||
};
|
||||
@@ -118,14 +114,12 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
|
||||
public generateSimpleRelationFieldOrderByInputType({
|
||||
fieldMetadata,
|
||||
typeOptions,
|
||||
isForGroupBy,
|
||||
context,
|
||||
}: {
|
||||
fieldMetadata: FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
typeOptions: TypeOptions;
|
||||
isForGroupBy?: boolean;
|
||||
context?: SchemaGenerationContext;
|
||||
}) {
|
||||
@@ -142,19 +136,13 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
|
||||
this.logger.error(message, {
|
||||
type,
|
||||
typeOptions,
|
||||
});
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
|
||||
const fields: GraphQLInputFieldConfigMap = {
|
||||
[joinColumnName]: {
|
||||
type: modifiedType,
|
||||
type,
|
||||
description: fieldMetadata.description,
|
||||
},
|
||||
};
|
||||
@@ -250,7 +238,7 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
fieldMetadata: FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
typeOptions: TypeOptions;
|
||||
typeOptions: CreateInputTypeOptions;
|
||||
}) {
|
||||
if (fieldMetadata.settings?.relationType === RelationType.ONE_TO_MANY) {
|
||||
return {};
|
||||
@@ -277,7 +265,10 @@ export class RelationFieldMetadataGqlInputTypeGenerator {
|
||||
|
||||
return {
|
||||
[fieldMetadataName]: {
|
||||
type: this.typeMapperService.applyTypeOptions(type, typeOptions),
|
||||
type: applyTypeOptionsForCreateInput(type, {
|
||||
...typeOptions,
|
||||
nullable: true,
|
||||
}),
|
||||
description: fieldMetadata.description,
|
||||
},
|
||||
};
|
||||
|
||||
+2
-4
@@ -11,6 +11,7 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
import { GqlInputTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-input-type-definition-kind.enum';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForUpdateInput } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-update-input.util';
|
||||
import { computeCompositeFieldTypeOptions } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-composite-field-type-options.util';
|
||||
import { computeCompositeFieldEnumTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-enum-type-key.util';
|
||||
import { computeCompositeFieldInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-input-type-key.util';
|
||||
@@ -88,10 +89,7 @@ export class CompositeFieldMetadataUpdateGqlInputTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForUpdateInput(type, typeOptions);
|
||||
|
||||
fields[property.name] = {
|
||||
type: modifiedType,
|
||||
|
||||
+2
-4
@@ -18,6 +18,7 @@ import { RelationFieldMetadataGqlInputTypeGenerator } from 'src/engine/api/graph
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type';
|
||||
import { applyTypeOptionsForUpdateInput } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-update-input.util';
|
||||
import { computeFieldInputTypeOptions } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-field-input-type-options.util';
|
||||
import { computeCompositeFieldInputTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-input-type-key.util';
|
||||
import { computeEnumFieldGqlTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-enum-field-gql-type-key.util';
|
||||
@@ -156,10 +157,7 @@ export class ObjectMetadataUpdateGqlInputTypeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForUpdateInput(type, typeOptions);
|
||||
|
||||
generatedFields = {
|
||||
[fieldMetadata.name]: {
|
||||
|
||||
+2
-4
@@ -8,6 +8,7 @@ import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schem
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { computeCompositeFieldEnumTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-enum-type-key.util';
|
||||
import { computeCompositeFieldObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-object-type-key.util';
|
||||
import { isEnumFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-enum-field-metadata-type.util';
|
||||
@@ -86,10 +87,7 @@ export class CompositeFieldMetadataGqlObjectTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForOutputType(type, typeOptions);
|
||||
|
||||
fields[property.name] = {
|
||||
type: modifiedType,
|
||||
|
||||
+3
-4
@@ -6,8 +6,8 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/object-type-definition-kind.enum';
|
||||
import { AggregationObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/aggregation-type.generator';
|
||||
import { PageInfoType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/object';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util';
|
||||
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
@@ -19,7 +19,6 @@ export class ConnectionGqlObjectTypeGenerator {
|
||||
|
||||
constructor(
|
||||
private readonly aggregationObjectTypeGenerator: AggregationObjectTypeGenerator,
|
||||
private readonly typeMapperService: TypeMapperService,
|
||||
private readonly gqlTypesStorage: GqlTypesStorage,
|
||||
) {}
|
||||
|
||||
@@ -73,7 +72,7 @@ export class ConnectionGqlObjectTypeGenerator {
|
||||
}
|
||||
|
||||
fields.edges = {
|
||||
type: this.typeMapperService.applyTypeOptions(edgeType, {
|
||||
type: applyTypeOptionsForOutputType(edgeType, {
|
||||
isArray: true,
|
||||
arrayDepth: 1,
|
||||
nullable: false,
|
||||
@@ -81,7 +80,7 @@ export class ConnectionGqlObjectTypeGenerator {
|
||||
};
|
||||
|
||||
fields.pageInfo = {
|
||||
type: this.typeMapperService.applyTypeOptions(PageInfoType, {
|
||||
type: applyTypeOptionsForOutputType(PageInfoType, {
|
||||
nullable: false,
|
||||
}),
|
||||
};
|
||||
|
||||
+5
-11
@@ -5,8 +5,8 @@ import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
|
||||
import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/object-type-definition-kind.enum';
|
||||
import { CursorScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -15,10 +15,7 @@ import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object
|
||||
export class EdgeGqlObjectTypeGenerator {
|
||||
private readonly logger = new Logger(EdgeGqlObjectTypeGenerator.name);
|
||||
|
||||
constructor(
|
||||
private readonly typeMapperService: TypeMapperService,
|
||||
private readonly gqlTypesStorage: GqlTypesStorage,
|
||||
) {}
|
||||
constructor(private readonly gqlTypesStorage: GqlTypesStorage) {}
|
||||
|
||||
public buildAndStore(flatObjectMetadata: FlatObjectMetadata) {
|
||||
const kind = ObjectTypeDefinitionKind.Edge;
|
||||
@@ -60,18 +57,15 @@ export class EdgeGqlObjectTypeGenerator {
|
||||
}
|
||||
|
||||
const typeOptions = {
|
||||
nullable: false,
|
||||
nullable: false as const,
|
||||
};
|
||||
|
||||
fields.node = {
|
||||
type: this.typeMapperService.applyTypeOptions(objectType, typeOptions),
|
||||
type: applyTypeOptionsForOutputType(objectType, typeOptions),
|
||||
};
|
||||
|
||||
fields.cursor = {
|
||||
type: this.typeMapperService.applyTypeOptions(
|
||||
CursorScalarType,
|
||||
typeOptions,
|
||||
),
|
||||
type: applyTypeOptionsForOutputType(CursorScalarType, typeOptions),
|
||||
};
|
||||
|
||||
return fields;
|
||||
|
||||
+3
-6
@@ -5,8 +5,8 @@ import GraphQLJSON from 'graphql-type-json';
|
||||
import { isDefined, pascalCase } from 'twenty-shared/utils';
|
||||
|
||||
import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/object-type-definition-kind.enum';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -17,10 +17,7 @@ export class GroupByConnectionGqlObjectTypeGenerator {
|
||||
GroupByConnectionGqlObjectTypeGenerator.name,
|
||||
);
|
||||
|
||||
constructor(
|
||||
private readonly typeMapperService: TypeMapperService,
|
||||
private readonly gqlTypesStorage: GqlTypesStorage,
|
||||
) {}
|
||||
constructor(private readonly gqlTypesStorage: GqlTypesStorage) {}
|
||||
|
||||
public buildAndStore(flatObjectMetadata: FlatObjectMetadata) {
|
||||
const kind = ObjectTypeDefinitionKind.GroupByConnection;
|
||||
@@ -65,7 +62,7 @@ export class GroupByConnectionGqlObjectTypeGenerator {
|
||||
Object.assign(fields, connection.toConfig().fields);
|
||||
|
||||
fields.groupByDimensionValues = {
|
||||
type: this.typeMapperService.applyTypeOptions(GraphQLJSON, {
|
||||
type: applyTypeOptionsForOutputType(GraphQLJSON, {
|
||||
nullable: false,
|
||||
}),
|
||||
};
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ import { RelationFieldMetadataGqlObjectTypeGenerator } from 'src/engine/api/grap
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { GraphQLOutputTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { computeCompositeFieldObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-composite-field-object-type-key.util';
|
||||
import { computeEnumFieldGqlTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-enum-field-gql-type-key.util';
|
||||
import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util';
|
||||
@@ -150,7 +151,7 @@ export class ObjectMetadataGqlObjectTypeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
const modifiedType = applyTypeOptionsForOutputType(
|
||||
type,
|
||||
typeFactoryOptions,
|
||||
);
|
||||
|
||||
+6
-8
@@ -3,10 +3,11 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||
import { FieldMetadataType, RelationType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import {
|
||||
TypeMapperService,
|
||||
TypeOptions,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
type OutputTypeOptions,
|
||||
applyTypeOptionsForOutputType,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { extractGraphQLRelationFieldNames } from 'src/engine/api/graphql/workspace-schema-builder/utils/extract-graphql-relation-field-names.util';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
|
||||
@@ -25,7 +26,7 @@ export class RelationFieldMetadataGqlObjectTypeGenerator {
|
||||
fieldMetadata: FlatFieldMetadata<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>;
|
||||
typeOptions: TypeOptions;
|
||||
typeOptions: OutputTypeOptions;
|
||||
}) {
|
||||
if (fieldMetadata.settings?.relationType === RelationType.ONE_TO_MANY)
|
||||
return {};
|
||||
@@ -47,10 +48,7 @@ export class RelationFieldMetadataGqlObjectTypeGenerator {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const modifiedType = this.typeMapperService.applyTypeOptions(
|
||||
type,
|
||||
typeOptions,
|
||||
);
|
||||
const modifiedType = applyTypeOptionsForOutputType(type, typeOptions);
|
||||
|
||||
return {
|
||||
[joinColumnName]: {
|
||||
|
||||
+4
-8
@@ -9,8 +9,8 @@ import { WorkspaceResolverBuilderService } from 'src/engine/api/graphql/workspac
|
||||
import { GqlOperation } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-operation.enum';
|
||||
import { ObjectTypeDefinitionKind } from 'src/engine/api/graphql/workspace-schema-builder/enums/object-type-definition-kind.enum';
|
||||
import { ArgsTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/args-type/args-type.generator';
|
||||
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
|
||||
import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage';
|
||||
import { applyTypeOptionsForOutputType } from 'src/engine/api/graphql/workspace-schema-builder/utils/apply-type-options-for-output-type.util';
|
||||
import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type';
|
||||
import { GraphQLRootTypeFieldConfigMap } from 'src/engine/api/graphql/workspace-schema-builder/types/graphql-field-config-map.types';
|
||||
import { computeObjectMetadataObjectTypeKey } from 'src/engine/api/graphql/workspace-schema-builder/utils/compute-stored-gql-type-key-utils/compute-object-metadata-object-type-key.util';
|
||||
@@ -24,7 +24,6 @@ export class RootTypeGenerator {
|
||||
|
||||
constructor(
|
||||
private readonly gqlTypesStorage: GqlTypesStorage,
|
||||
private readonly typeMapperService: TypeMapperService,
|
||||
private readonly argsTypeGenerator: ArgsTypeGenerator,
|
||||
private readonly workspaceResolverBuilderService: WorkspaceResolverBuilderService,
|
||||
) {}
|
||||
@@ -115,12 +114,9 @@ export class RootTypeGenerator {
|
||||
'groupBy',
|
||||
];
|
||||
|
||||
const outputType = this.typeMapperService.applyTypeOptions(
|
||||
objectType,
|
||||
{
|
||||
isArray: isMethodReturningArrayObjectType.includes(methodName),
|
||||
},
|
||||
);
|
||||
const outputType = applyTypeOptionsForOutputType(objectType, {
|
||||
isArray: isMethodReturningArrayObjectType.includes(methodName),
|
||||
});
|
||||
|
||||
fieldConfigMap[name] = {
|
||||
type: outputType,
|
||||
|
||||
+5
-50
@@ -8,21 +8,18 @@ import {
|
||||
type GraphQLInputObjectType,
|
||||
type GraphQLInputType,
|
||||
GraphQLList,
|
||||
GraphQLNonNull,
|
||||
type GraphQLOutputType,
|
||||
type GraphQLScalarType,
|
||||
GraphQLString,
|
||||
type GraphQLType,
|
||||
} from 'graphql';
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
import {
|
||||
AggregateOperations,
|
||||
type FieldMetadataDefaultValue,
|
||||
type FieldMetadataSettings,
|
||||
FieldMetadataType,
|
||||
NumberDataType,
|
||||
type FieldMetadataDefaultValue,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum';
|
||||
import {
|
||||
@@ -52,13 +49,12 @@ import { getNumberFilterType } from 'src/engine/api/graphql/workspace-schema-bui
|
||||
import { getNumberScalarType } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-number-scalar-type.util';
|
||||
|
||||
export interface TypeOptions {
|
||||
nullable?: boolean;
|
||||
isArray?: boolean;
|
||||
arrayDepth?: number;
|
||||
defaultValue?: FieldMetadataDefaultValue<FieldMetadataType>;
|
||||
settings?: FieldMetadataSettings<FieldMetadataType>;
|
||||
isIdField?: boolean;
|
||||
isRelationConnectField?: boolean;
|
||||
nullable?: boolean;
|
||||
defaultValue?: FieldMetadataDefaultValue<FieldMetadataType>;
|
||||
isArray?: boolean;
|
||||
arrayDepth?: number;
|
||||
}
|
||||
|
||||
const StringArrayScalarType = new GraphQLList(GraphQLString);
|
||||
@@ -241,45 +237,4 @@ export class TypeMapperService {
|
||||
|
||||
return typeOrderByMapping.get(aggregationType);
|
||||
}
|
||||
|
||||
applyTypeOptions<T extends GraphQLType = GraphQLType>(
|
||||
typeRef: T,
|
||||
options: TypeOptions,
|
||||
): T {
|
||||
let graphqlType: T | GraphQLList<T> | GraphQLNonNull<T> = typeRef;
|
||||
|
||||
if (options.isArray) {
|
||||
graphqlType = this.mapToGqlList(
|
||||
graphqlType,
|
||||
options.arrayDepth ?? 1,
|
||||
options.nullable ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
if (options.nullable === false && !isDefined(options.defaultValue)) {
|
||||
graphqlType = new GraphQLNonNull(graphqlType) as unknown as T;
|
||||
}
|
||||
|
||||
return graphqlType as T;
|
||||
}
|
||||
|
||||
private mapToGqlList<T extends GraphQLType = GraphQLType>(
|
||||
targetType: T,
|
||||
depth: number,
|
||||
nullable: boolean,
|
||||
): GraphQLList<T> {
|
||||
const targetTypeNonNull = nullable
|
||||
? targetType
|
||||
: new GraphQLNonNull(targetType);
|
||||
|
||||
if (depth === 0) {
|
||||
return targetType as GraphQLList<T>;
|
||||
}
|
||||
|
||||
return this.mapToGqlList<T>(
|
||||
new GraphQLList(targetTypeNonNull) as unknown as T,
|
||||
depth - 1,
|
||||
nullable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { type GraphQLList, GraphQLNonNull, type GraphQLType } from 'graphql';
|
||||
import {
|
||||
type FieldMetadataDefaultValue,
|
||||
type FieldMetadataType,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { wrapTypeInGraphQLList } from 'src/engine/api/graphql/workspace-schema-builder/utils/wrap-type-in-graphql-list.util';
|
||||
|
||||
export type CreateInputTypeOptions = {
|
||||
nullable?: boolean;
|
||||
defaultValue?: FieldMetadataDefaultValue<FieldMetadataType>;
|
||||
isArray?: boolean;
|
||||
arrayDepth?: number;
|
||||
};
|
||||
|
||||
export const applyTypeOptionsForCreateInput = <
|
||||
T extends GraphQLType = GraphQLType,
|
||||
>(
|
||||
typeRef: T,
|
||||
options: CreateInputTypeOptions,
|
||||
): T => {
|
||||
let graphqlType: T | GraphQLList<T> | GraphQLNonNull<T> = typeRef;
|
||||
|
||||
if (options.isArray) {
|
||||
graphqlType = wrapTypeInGraphQLList(
|
||||
graphqlType,
|
||||
options.arrayDepth ?? 1,
|
||||
options.nullable ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
if (options.nullable === false && !isDefined(options.defaultValue)) {
|
||||
graphqlType = new GraphQLNonNull(graphqlType) as unknown as T;
|
||||
}
|
||||
|
||||
return graphqlType as T;
|
||||
};
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { type GraphQLList, GraphQLNonNull, type GraphQLType } from 'graphql';
|
||||
import {
|
||||
type FieldMetadataDefaultValue,
|
||||
type FieldMetadataType,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { wrapTypeInGraphQLList } from 'src/engine/api/graphql/workspace-schema-builder/utils/wrap-type-in-graphql-list.util';
|
||||
|
||||
export type OutputTypeOptions = {
|
||||
nullable?: boolean;
|
||||
defaultValue?: FieldMetadataDefaultValue<FieldMetadataType>;
|
||||
isArray?: boolean;
|
||||
arrayDepth?: number;
|
||||
};
|
||||
|
||||
export const applyTypeOptionsForOutputType = <
|
||||
T extends GraphQLType = GraphQLType,
|
||||
>(
|
||||
typeRef: T,
|
||||
options: OutputTypeOptions,
|
||||
): T => {
|
||||
let graphqlType: T | GraphQLList<T> | GraphQLNonNull<T> = typeRef;
|
||||
|
||||
if (options.isArray) {
|
||||
graphqlType = wrapTypeInGraphQLList(
|
||||
graphqlType,
|
||||
options.arrayDepth ?? 1,
|
||||
options.nullable ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
if (options.nullable === false && !isDefined(options.defaultValue)) {
|
||||
graphqlType = new GraphQLNonNull(graphqlType) as unknown as T;
|
||||
}
|
||||
|
||||
return graphqlType as T;
|
||||
};
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { type GraphQLType } from 'graphql';
|
||||
|
||||
import { wrapTypeInGraphQLList } from 'src/engine/api/graphql/workspace-schema-builder/utils/wrap-type-in-graphql-list.util';
|
||||
|
||||
export type UpdateInputTypeOptions = {
|
||||
isArray?: boolean;
|
||||
arrayDepth?: number;
|
||||
};
|
||||
|
||||
// Update inputs are always nullable — only array wrapping is needed
|
||||
export const applyTypeOptionsForUpdateInput = <
|
||||
T extends GraphQLType = GraphQLType,
|
||||
>(
|
||||
typeRef: T,
|
||||
options: UpdateInputTypeOptions,
|
||||
): T => {
|
||||
if (options.isArray) {
|
||||
return wrapTypeInGraphQLList(
|
||||
typeRef,
|
||||
options.arrayDepth ?? 1,
|
||||
true,
|
||||
) as unknown as T;
|
||||
}
|
||||
|
||||
return typeRef;
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import { GraphQLList, GraphQLNonNull, type GraphQLType } from 'graphql';
|
||||
|
||||
export const wrapTypeInGraphQLList = <T extends GraphQLType = GraphQLType>(
|
||||
targetType: T,
|
||||
depth: number,
|
||||
nullable: boolean,
|
||||
): GraphQLList<T> => {
|
||||
const targetTypeNonNull = nullable
|
||||
? targetType
|
||||
: new GraphQLNonNull(targetType);
|
||||
|
||||
if (depth === 0) {
|
||||
return targetType as GraphQLList<T>;
|
||||
}
|
||||
|
||||
return wrapTypeInGraphQLList<T>(
|
||||
new GraphQLList(targetTypeNonNull) as unknown as T,
|
||||
depth - 1,
|
||||
nullable,
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user