Skip to content

Commit

Permalink
fix: ignore directive replacements for consolidated types when defini…
Browse files Browse the repository at this point in the history
…tionType is input/output (#119)

* unit test

* make test pass

* improve test

* fix integration tests

* fix integration tests

* fix integration tests
  • Loading branch information
danadajian authored Oct 30, 2024
1 parent 85a3257 commit 3a8e3c1
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@expediagroup/graphql-kotlin-codegen",
"packageManager": "[email protected].17",
"packageManager": "[email protected].32",
"main": "dist/plugin.cjs",
"types": "dist/plugin.d.cts",
"files": [
Expand Down
4 changes: 4 additions & 0 deletions src/annotations/build-annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { indent } from "@graphql-codegen/visitor-plugin-common";
import {
EnumValueDefinitionNode,
FieldDefinitionNode,
GraphQLSchema,
InputValueDefinitionNode,
Kind,
TypeDefinitionNode,
Expand All @@ -31,10 +32,12 @@ export type DefinitionNode =
| EnumValueDefinitionNode;

export function buildAnnotations({
schema,
config,
definitionNode,
typeMetadata,
}: {
schema: GraphQLSchema;
config: CodegenConfigWithDefaults;
definitionNode: DefinitionNode;
typeMetadata?: TypeMetadata;
Expand All @@ -49,6 +52,7 @@ export function buildAnnotations({
const directiveAnnotations = buildDirectiveAnnotations(
definitionNode,
config,
schema,
);
const unionAnnotation = typeMetadata?.unionAnnotation
? `@${typeMetadata.unionAnnotation}\n`
Expand Down
25 changes: 21 additions & 4 deletions src/annotations/build-directive-annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ limitations under the License.
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import { DefinitionNode } from "./build-annotations";
import { ConstDirectiveNode } from "graphql/language";
import { Kind } from "graphql";
import { GraphQLSchema, isInputObjectType, Kind } from "graphql";
import { shouldConsolidateTypes } from "../utils/should-consolidate-types";
import { sanitizeName } from "../utils/sanitize-name";

export function buildDirectiveAnnotations(
definitionNode: DefinitionNode,
config: CodegenConfigWithDefaults,
schema: GraphQLSchema,
) {
const name = sanitizeName(definitionNode.name.value);
const potentialMatchingInputType = schema.getType(`${name}Input`);
const typeWillBeConsolidated =
isInputObjectType(potentialMatchingInputType) &&
potentialMatchingInputType.astNode &&
shouldConsolidateTypes(potentialMatchingInputType.astNode, schema, config);
const directives = definitionNode.directives ?? [];
return directives
.map((directive) => {
Expand All @@ -29,9 +38,17 @@ export function buildDirectiveAnnotations(
if (federationReplacement) return federationReplacement + "\n";

const directiveReplacementFromConfig = config.directiveReplacements?.find(
({ directive, definitionType }) =>
directive === directiveName &&
(!definitionType || definitionType === definitionNode.kind),
({ directive, definitionType }) => {
if (directive !== directiveName) return false;
if (!definitionType) return true;
if (definitionType !== definitionNode.kind) return false;
if (
definitionType !== Kind.INPUT_OBJECT_TYPE_DEFINITION &&
definitionType !== Kind.OBJECT_TYPE_DEFINITION
)
return true;
return !typeWillBeConsolidated;
},
);
if (!directiveReplacementFromConfig) return "";
const kotlinAnnotations = buildKotlinAnnotations(
Expand Down
7 changes: 6 additions & 1 deletion src/definitions/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ import { buildAnnotations } from "../annotations/build-annotations";
import { shouldExcludeTypeDefinition } from "../config/should-exclude-type-definition";
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import { sanitizeName } from "../utils/sanitize-name";
import { GraphQLSchema } from "graphql";

export function buildEnumTypeDefinition(
node: EnumTypeDefinitionNode,
schema: GraphQLSchema,
config: CodegenConfigWithDefaults,
) {
if (shouldExcludeTypeDefinition(node, config)) {
Expand All @@ -29,10 +31,11 @@ export function buildEnumTypeDefinition(
const enumName = sanitizeName(node.name.value);
const enumValues =
node.values?.map((valueNode) => {
return buildEnumValueDefinition(valueNode, config);
return buildEnumValueDefinition(valueNode, schema, config);
}) ?? [];

const annotations = buildAnnotations({
schema,
config,
definitionNode: node,
});
Expand All @@ -47,10 +50,12 @@ ${indentMultiline(enumValues.join(",\n") + ";", 2)}

function buildEnumValueDefinition(
node: EnumValueDefinitionNode,
schema: GraphQLSchema,
config: CodegenConfigWithDefaults,
) {
const annotations = buildAnnotations({
config,
schema,
definitionNode: node,
});
if (!config.convert) {
Expand Down
3 changes: 3 additions & 0 deletions src/definitions/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export function buildObjectFieldDefinition({
typeMetadata,
);
const annotations = buildAnnotations({
schema,
config,
definitionNode: fieldNode,
typeMetadata,
Expand Down Expand Up @@ -112,6 +113,7 @@ export function buildConstructorFieldDefinition({
typeMetadata,
);
const annotations = buildAnnotations({
schema,
config,
definitionNode: fieldNode,
typeMetadata,
Expand Down Expand Up @@ -156,6 +158,7 @@ export function buildInterfaceFieldDefinition({
typeMetadata,
);
const annotations = buildAnnotations({
schema,
config,
definitionNode: fieldNode,
typeMetadata,
Expand Down
2 changes: 2 additions & 0 deletions src/definitions/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function buildInputObjectDefinition(
const initial = typeToUse.isNullable ? " = null" : "";

const annotations = buildAnnotations({
schema,
config,
definitionNode: field,
});
Expand All @@ -53,6 +54,7 @@ export function buildInputObjectDefinition(
.join(",\n");

const annotations = buildAnnotations({
schema,
config,
definitionNode: node,
});
Expand Down
1 change: 1 addition & 0 deletions src/definitions/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function buildInterfaceDefinition(
.join("\n");

const annotations = buildAnnotations({
schema,
config,
definitionNode: node,
});
Expand Down
3 changes: 2 additions & 1 deletion src/definitions/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export function buildObjectTypeDefinition(
}

const annotations = buildAnnotations({
schema,
config,
definitionNode: node,
});
const name = sanitizeName(node.name.value);
const dependentInterfaces = getDependentInterfaceNames(node);
const dependentUnions = getDependentUnionsForType(schema, node);
const interfacesToInherit =
Expand All @@ -57,6 +57,7 @@ export function buildObjectTypeDefinition(
);
const interfaceInheritance = `${interfacesToInherit.length ? ` : ${sanitizedInterfaceNames.join(", ")}` : ""}`;

const name = sanitizeName(node.name.value);
const potentialMatchingInputType = schema.getType(`${name}Input`);
const typeWillBeConsolidated =
isInputObjectType(potentialMatchingInputType) &&
Expand Down
4 changes: 3 additions & 1 deletion src/definitions/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { UnionTypeDefinitionNode } from "graphql";
import { GraphQLSchema, UnionTypeDefinitionNode } from "graphql";
import { shouldExcludeTypeDefinition } from "../config/should-exclude-type-definition";
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import {
Expand All @@ -22,12 +22,14 @@ import { sanitizeName } from "../utils/sanitize-name";

export function buildUnionTypeDefinition(
node: UnionTypeDefinitionNode,
schema: GraphQLSchema,
config: CodegenConfigWithDefaults,
) {
if (shouldExcludeTypeDefinition(node, config)) {
return "";
}
const annotations = buildAnnotations({
schema,
config,
definitionNode: node,
});
Expand Down
4 changes: 2 additions & 2 deletions src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class KotlinVisitor extends BaseVisitor<
}

EnumTypeDefinition(node: EnumTypeDefinitionNode): string {
return buildEnumTypeDefinition(node, this.config);
return buildEnumTypeDefinition(node, this._schema, this.config);
}

InterfaceTypeDefinition(node: InterfaceTypeDefinitionNode): string {
Expand All @@ -56,6 +56,6 @@ export class KotlinVisitor extends BaseVisitor<
}

UnionTypeDefinition(node: UnionTypeDefinitionNode): string {
return buildUnionTypeDefinition(node, this.config);
return buildUnionTypeDefinition(node, this._schema, this.config);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { GraphQLKotlinCodegenConfig } from "../../../src/plugin";
import { Kind } from "graphql/index";

export default {
extraImports: ["should_honor_directiveReplacements_config.*"],
directiveReplacements: [
{
directive: "directive1",
kotlinAnnotations: ["@SomeAnnotation1"],
definitionType: Kind.OBJECT_TYPE_DEFINITION,
},
{
directive: "directive2",
kotlinAnnotations: ["@SomeAnnotation2"],
},
],
classConsolidationEnabled: true,
} satisfies GraphQLKotlinCodegenConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.kotlin.generated

import com.expediagroup.graphql.generator.annotations.*
import should_honor_directiveReplacements_config.*

@SomeAnnotation1
@SomeAnnotation2
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
data class TypeThatShouldGetDirectiveReplacement(
val field: String? = null
)

@SomeAnnotation2
@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT])
data class InputTypeThatShouldNotGetDirectiveReplacement(
val field: String? = null
)

data class MyConsolidatedTypeWithDirectives(
val field: String? = null
)

@SomeAnnotation2
data class MyConsolidatedTypeWithDirectives2(
val field: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
directive @directive1 on INPUT_OBJECT | OBJECT
directive @directive2 on INPUT_OBJECT | OBJECT

type TypeThatShouldGetDirectiveReplacement @directive1 @directive2 {
field: String
}

input InputTypeThatShouldNotGetDirectiveReplacement @directive1 @directive2 {
field: String
}

type MyConsolidatedTypeWithDirectives @directive1 {
field: String
}

input MyConsolidatedTypeWithDirectivesInput @directive1 {
field: String
}

type MyConsolidatedTypeWithDirectives2 @directive2 {
field: String
}

input MyConsolidatedTypeWithDirectives2Input @directive2 {
field: String
}

0 comments on commit 3a8e3c1

Please sign in to comment.