Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom scalars for Pure Integer type during GraphQL SDL generation #2500

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,55 @@ function meta::external::query::graphQL::binding::fromInterfaceTypeName(interfac
if($interfaceTypeName->endsWith('Interface'), | $interfaceTypeName->substring(0, $interfaceTypeName->length() - 9), | '')
}

function meta::external::query::graphQL::binding::purePrimitivesToGraphQLScalarTypes(): Pair<PrimitiveType,String>[*]
Class meta::external::query::graphQL::binding::PureTypeToGraphQLScalarOverride
{
[
pair(String, 'String'),
pair(Integer, 'Int'),
pair(Float, 'Float'),
pair(Boolean, 'Boolean')
]
integerScalarType: String[0..1];
}

function meta::external::query::graphQL::binding::purePrimitivesToCustomGraphQLScalarTypes(): Pair<PrimitiveType,String>[*]
function meta::external::query::graphQL::binding::purePrimitivesToAllGraphQLScalarTypes(pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): Pair<PrimitiveType,String>[*]
{
[
pair(Integer, if($pureTypeToGraphQLScalarOverride->isEmpty() || $pureTypeToGraphQLScalarOverride->toOne().integerScalarType->isEmpty(), | 'Int', | $pureTypeToGraphQLScalarOverride->toOne().integerScalarType->toOne())),
pair(String, 'String'),
pair(Float, 'Float'),
pair(Boolean, 'Boolean'),
pair(Date, 'Date'),
pair(StrictDate, 'StrictDate'),
pair(DateTime, 'DateTime'),
pair(Decimal, 'BigDecimal')
]
}

// Concat and invert the pure primitives to graphQL
function meta::external::query::graphQL::binding::graphQLScalarTypesToPurePrimitives(): Pair<String,PrimitiveType>[*]
function meta::external::query::graphQL::binding::builtInGraphQLScalars(): String[*]
{
['Int', 'Float', 'String', 'Boolean', 'ID'];
}

function meta::external::query::graphQL::binding::purePrimitivesToCustomGraphQLScalarTypes(pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): Pair<PrimitiveType,String>[*]
{
purePrimitivesToAllGraphQLScalarTypes($pureTypeToGraphQLScalarOverride)
// remove built in GraphQL Scalars
->filter(p | !$p.second->in(builtInGraphQLScalars()))
}

// Inversion of the pure primitives to graphQL with some extras
function meta::external::query::graphQL::binding::graphQLScalarTypesToPurePrimitives(pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): Pair<String,PrimitiveType>[*]
{
purePrimitivesToGraphQLScalarTypes()->concatenate(purePrimitivesToCustomGraphQLScalarTypes())
->map(p | pair($p.second, $p.first))
->concatenate(pair('ID', String))
if($pureTypeToGraphQLScalarOverride->isEmpty() || $pureTypeToGraphQLScalarOverride->toOne().integerScalarType->isEmpty(), | [], | [pair($pureTypeToGraphQLScalarOverride->toOne().integerScalarType->toOne(), Integer)])
->concatenate(
[
// Keep all default mappings as well
pair('String', String),
pair('Int', Integer),
pair('Float', Float),
pair('Boolean', Boolean),
pair('Date', Date),
pair('StrictDate', StrictDate),
pair('DateTime', DateTime),
pair('BigDecimal', Decimal),
pair('ID', String)
]
)
}

function meta::external::query::graphQL::binding::temporalityToDirectives(): Map<String,DirectiveDefinition>[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Class meta::external::query::graphQL::metamodel::sdl::GraphQLSDLContainer

Class meta::external::query::graphQL::binding::fromPure::sdl::ModelToGraphQLConfig extends meta::external::format::shared::transformation::fromPure::ModelToSchemaConfiguration
{
pureTypeToGraphQLScalarOverride: meta::external::query::graphQL::binding::PureTypeToGraphQLScalarOverride[0..1];
}

function meta::external::query::graphQL::binding::fromPure::sdl::pureToGraphQLSDL(modelUnit: ModelUnit[1], config: ModelToGraphQLConfig[1]): meta::external::format::shared::metamodel::SchemaSet[1]
Expand All @@ -21,7 +22,7 @@ function meta::external::query::graphQL::binding::fromPure::sdl::pureToGraphQLSD
let document =
^meta::external::query::graphQL::metamodel::sdl::Document
(
definitions = meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL($packageableElements)
definitions = meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL($packageableElements, $config)
);
let sdlcContainer =
^meta::external::query::graphQL::metamodel::sdl::GraphQLSDLContainer
Expand Down Expand Up @@ -54,9 +55,10 @@ function meta::external::query::graphQL::binding::fromPure::sdl::schemaDetailToS
->joinStrings('\n');
}

function meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL(types: meta::pure::metamodel::PackageableElement[*]): meta::external::query::graphQL::metamodel::sdl::typeSystem::TypeSystemDefinition[*]
function meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL(types: meta::pure::metamodel::PackageableElement[*], config: ModelToGraphQLConfig[1]): meta::external::query::graphQL::metamodel::sdl::typeSystem::TypeSystemDefinition[*]
{
let allTypes = $types->findTypes();
let pureTypeToGraphQLScalarOverride = $config.pureTypeToGraphQLScalarOverride;

let queryClasses = $allTypes->cast(@AnnotatedElement)->filter(t|$t.stereotypes.value->contains('Query'))->cast(@Class<Any>);
let mutationClasses = $allTypes->cast(@AnnotatedElement)->filter(t|$t.stereotypes.value->contains('Mutation'))->cast(@Class<Any>);
Expand Down Expand Up @@ -102,16 +104,16 @@ function meta::external::query::graphQL::binding::fromPure::sdl::transformPureTo
c:Class<Any>[1] |
if ($classInputTypes->contains($c),
|
buildInputObjectTypeDefinition($c)->concatenate(
buildInputObjectTypeDefinition($c, $pureTypeToGraphQLScalarOverride)->concatenate(
if ($classReturnTypes->contains($c),
// Used as both -> needs both input and output types
| buildObjectTypeDefinition($c, $extendedClasses->contains($c)),
| buildObjectTypeDefinition($c, $extendedClasses->contains($c), $pureTypeToGraphQLScalarOverride),
// Used as input -> needs input
| []
)
),
// Not used as input --> needs output (unused types will result in output types)
| buildObjectTypeDefinition($c, $extendedClasses->contains($c))
| buildObjectTypeDefinition($c, $extendedClasses->contains($c), $pureTypeToGraphQLScalarOverride)
),
e:Enumeration<Any>[1] |
^EnumTypeDefinition(
Expand All @@ -133,7 +135,7 @@ function meta::external::query::graphQL::binding::fromPure::sdl::transformPureTo
->distinct()
->map(s | temporalityToDirectives()->get($s)->toOne());

let interfaces = $extendedClasses->map(c | $c->buildInterfaceTypeDefinition());
let interfaces = $extendedClasses->map(c | $c->buildInterfaceTypeDefinition($pureTypeToGraphQLScalarOverride));

$partitioned.second.values
// Remove duplicated scalar definitions
Expand Down Expand Up @@ -178,23 +180,23 @@ function <<access.private>> meta::external::query::graphQL::binding::fromPure::s
!$p.name->in(['processingDate', 'businessDate', 'milestoning']);
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildNonBuiltInGraphQLScalars(props: AbstractProperty<Any>[*]): ScalarTypeDefinition[*]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildNonBuiltInGraphQLScalars(props: AbstractProperty<Any>[*], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): ScalarTypeDefinition[*]
{
$props
->map(p | $p.genericType.rawType->toOne())
->map(p | $p->match(
[
p : PrimitiveType[1] | purePrimitivesToCustomGraphQLScalarTypes()->newMap()->get($p),
p : PrimitiveType[1] | purePrimitivesToCustomGraphQLScalarTypes($pureTypeToGraphQLScalarOverride)->newMap()->get($p),
a : Any[1] | []
]
))
->map(customScalar | ^ScalarTypeDefinition(name = $customScalar))
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInputObjectTypeDefinition(c: Class<Any>[1]): TypeSystemDefinition[*]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInputObjectTypeDefinition(c: Class<Any>[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeSystemDefinition[*]
{
let props = $c->hierarchicalAllProperties()->filter(p | $p->isValidPropertyForGraphQL());
let nonBuiltInScalars = $props->buildNonBuiltInGraphQLScalars();
let nonBuiltInScalars = $props->buildNonBuiltInGraphQLScalars($pureTypeToGraphQLScalarOverride);

let temporalStereotypes = $c->getTemporalStereotypes();
$nonBuiltInScalars
Expand All @@ -207,15 +209,15 @@ function <<access.private>> meta::external::query::graphQL::binding::fromPure::s
^InputValueDefinition
(
name = $p.name->toOne(),
type = buildInputTypeCompatibleTypeReference($p.genericType, $p.multiplicity)
type = buildInputTypeCompatibleTypeReference($p.genericType, $p.multiplicity, $pureTypeToGraphQLScalarOverride)
))
));
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildObjectTypeDefinition(c: Class<Any>[1], isExtended: Boolean[1]): TypeSystemDefinition[*]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildObjectTypeDefinition(c: Class<Any>[1], isExtended: Boolean[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeSystemDefinition[*]
{
let props = $c->hierarchicalAllProperties()->filter(p | $p->isValidPropertyForGraphQL());
let nonBuiltInScalars = $props->buildNonBuiltInGraphQLScalars();
let nonBuiltInScalars = $props->buildNonBuiltInGraphQLScalars($pureTypeToGraphQLScalarOverride);

let temporalStereotypes = $c->getTemporalStereotypes();
$nonBuiltInScalars
Expand All @@ -229,15 +231,15 @@ function <<access.private>> meta::external::query::graphQL::binding::fromPure::s
^FieldDefinition
(
name = $p.name->toOne(),
type = buildObjectTypeCompatibleTypeReference($p->functionReturnType(), $p->functionReturnMultiplicity()),
type = buildObjectTypeCompatibleTypeReference($p->functionReturnType(), $p->functionReturnMultiplicity(), $pureTypeToGraphQLScalarOverride),
argumentDefinitions =
if ($p->instanceOf(QualifiedProperty),
|
$p->functionType().parameters->evaluateAndDeactivate()->tail()->map(pa |
^InputValueDefinition
(
name = $pa.name,
type = buildInputTypeCompatibleTypeReference($pa.genericType, $pa.multiplicity)
type = buildInputTypeCompatibleTypeReference($pa.genericType, $pa.multiplicity, $pureTypeToGraphQLScalarOverride)
)
),
|
Expand All @@ -248,7 +250,7 @@ function <<access.private>> meta::external::query::graphQL::binding::fromPure::s
));
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInterfaceTypeDefinition(c: Class<Any>[1]): TypeSystemDefinition[*]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInterfaceTypeDefinition(c: Class<Any>[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeSystemDefinition[*]
{
let props = $c->hierarchicalAllProperties()->filter(p | $p->isValidPropertyForGraphQL());

Expand All @@ -262,32 +264,32 @@ function <<access.private>> meta::external::query::graphQL::binding::fromPure::s
^FieldDefinition
(
name = $p.name->toOne(),
type = buildObjectTypeCompatibleTypeReference($p->functionReturnType(), $p->functionReturnMultiplicity()),
type = buildObjectTypeCompatibleTypeReference($p->functionReturnType(), $p->functionReturnMultiplicity(), $pureTypeToGraphQLScalarOverride),
argumentDefinitions = []
)
)
);
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildObjectTypeCompatibleTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1]): TypeReference[1]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildObjectTypeCompatibleTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeReference[1]
{
buildTypeReference($type, $mul, false)
buildTypeReference($type, $mul, false, $pureTypeToGraphQLScalarOverride)
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInputTypeCompatibleTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1]): TypeReference[1]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildInputTypeCompatibleTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeReference[1]
{
buildTypeReference($type, $mul, true)
buildTypeReference($type, $mul, true, $pureTypeToGraphQLScalarOverride)
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1], forInput: Boolean[1]): TypeReference[1]
function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::buildTypeReference(type:meta::pure::metamodel::type::generics::GenericType[1], mul:Multiplicity[1], forInput: Boolean[1], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): TypeReference[1]
{
let typeName =
if ($type.rawType->toOne()->instanceOf(Class) && $forInput,
|
// Must create reference to input type
toInputTypeName($type.rawType.name->toOne()),
|
let primitives = purePrimitivesToGraphQLScalarTypes()->concatenate(purePrimitivesToCustomGraphQLScalarTypes())->newMap();
let primitives = purePrimitivesToAllGraphQLScalarTypes($pureTypeToGraphQLScalarOverride)->newMap();
let foundPrimitiveName = $primitives->get($type.rawType->toOne());
let fName = if($foundPrimitiveName->isEmpty(), | $type.rawType.name,| $foundPrimitiveName->toOne());
)->toOne();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,33 @@ function <<test.Test>> meta::external::query::graphQL::binding::fromPure::sdl::t
'scalar StrictDate', $res);
}

function <<test.Test>> meta::external::query::graphQL::binding::fromPure::sdl::tests::testNonBuiltInPrimitiveTypesWithLongForInteger():Boolean[1]
{
let res = typesToGraphQLString([ClassWithPrimitiveTypes], ^PureTypeToGraphQLScalarOverride(integerScalarType = 'Long'));

assertEquals(
'scalar BigDecimal\n' +
'\n' +
'type ClassWithPrimitiveTypes {\n' +
' string: String!\n' +
' integer: Long!\n' +
' float: Float!\n' +
' boolean: Boolean!\n' +
' date: Date!\n' +
' datetime: DateTime!\n' +
' decimal: BigDecimal!\n' +
' strictDate: StrictDate!\n' +
'}\n' +
'\n' +
'scalar Date\n' +
'\n' +
'scalar DateTime\n' +
'\n' +
'scalar Long\n' +
'\n' +
'scalar StrictDate', $res);
}

function <<test.Test>> meta::external::query::graphQL::binding::fromPure::sdl::tests::testNonBuiltInPrimitiveTypesAreNotDuplicated():Boolean[1]
{
let res = typesToGraphQLString([ClassWithPrimitiveTypes, MutationPrimitive]);
Expand Down Expand Up @@ -433,7 +460,14 @@ function <<test.Test>> meta::external::query::graphQL::binding::fromPure::sdl::t

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::tests::typesToGraphQLString(types: PackageableElement[*]): String[1]
{
meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL($types)
typesToGraphQLString($types, []);
}

function <<access.private>> meta::external::query::graphQL::binding::fromPure::sdl::tests::typesToGraphQLString(types: PackageableElement[*], pureTypeToGraphQLScalarOverride: PureTypeToGraphQLScalarOverride[0..1]): String[1]
{
let defaultConfig = meta::external::query::graphQL::binding::fromPure::sdl::defaultConfig();
let updatedConfig = ^$defaultConfig(pureTypeToGraphQLScalarOverride = $pureTypeToGraphQLScalarOverride);
meta::external::query::graphQL::binding::fromPure::sdl::transformPureToGraphQLSDL($types, $updatedConfig)
->map(x|$x->meta::external::query::graphQL::serialization::graphQLtoString())
->joinStrings('\n\n');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function meta::external::query::graphQL::binding::toPure::introspection::buildPu
{
let pack = meta::external::query::graphQL::binding::toPure::buildTransientPackageFromString($package);

let simpleTypes = meta::external::query::graphQL::binding::graphQLScalarTypesToPurePrimitives()->newMap();
let simpleTypes = meta::external::query::graphQL::binding::graphQLScalarTypesToPurePrimitives([])->newMap();

let dispatch = [
pair(__TypeKind.OBJECT, t:__Type[1]| let no = newClass($t.name->toOne());
Expand Down
Loading
Loading