Skip to content

Commit

Permalink
Squashed 'apollo-ios-codegen/' changes from af0e5402..7b7b81bc
Browse files Browse the repository at this point in the history
7b7b81bc Add @import directive (#228)

git-subtree-dir: apollo-ios-codegen
git-subtree-split: 7b7b81bcdc99489465a98395c6b04ce1df50fcd5
  • Loading branch information
gh-action-runner authored and gh-action-runner committed Jan 8, 2024
1 parent f5373f6 commit 740f866
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 49 deletions.
2 changes: 1 addition & 1 deletion Sources/GraphQLCompiler/ApolloCodegenFrontendBundle.swift

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Sources/GraphQLCompiler/JavaScript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@types/jest": "29.5.11",
"common-tags": "1.8.2",
"jest": "29.7.0",
"rollup": "4.9.2",
"rollup": "4.9.4",
"@rollup/plugin-terser": "0.4.4",
"ts-jest": "29.1.1",
"typescript": "5.3.3"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@

import {
import {
compileDocument,
parseOperationDocument,
loadSchemaFromSources,
} from "../index"
import {
import {
CompilationResult
} from "../compiler/index"
import {
import {
Source,
GraphQLSchema,
DocumentNode
} from "graphql";
import { emptyValidationOptions } from "../__testUtils__/validationHelpers";

describe("given schema", () => {
const schemaSDL: string =
const schemaSDL: string =
`type Query {
allAnimals: [Animal!]
}
Expand All @@ -32,9 +32,9 @@ interface Pet {
const schema: GraphQLSchema = loadSchemaFromSources([new Source(schemaSDL, "Test Schema", { line: 1, column: 1 })]);

describe("given query not including __typename fields", () => {
const documentString: string =
const documentString: string =
`query Test {
allAnimals {
allAnimals {
species
... on Pet {
name
Expand All @@ -51,8 +51,8 @@ interface Pet {

it("operation definition should have source including __typename field.", () => {
const operation = compilationResult.operations[0];
const expected: string =

const expected: string =
`query Test {
allAnimals {
__typename
Expand All @@ -62,7 +62,7 @@ interface Pet {
}
}
}`;

expect(operation.source).toEqual(expected);
});
});
Expand All @@ -72,8 +72,8 @@ interface Pet {

it("operation definition should have source including __typename field in each selection set.", () => {
const operation = compilationResult.operations[0];
const expected: string =

const expected: string =
`query Test {
allAnimals {
__typename
Expand All @@ -84,17 +84,17 @@ interface Pet {
}
}
}`;

expect(operation.source).toEqual(expected);
});
});
});


describe("given query including __typename field with directive", () => {
const documentString: string =
const documentString: string =
`query Test {
allAnimals {
allAnimals {
__typename @include(if: true)
species
... on Pet {
Expand All @@ -111,7 +111,7 @@ interface Pet {
const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);
const operation = compilationResult.operations[0];

const expected: string =
const expected: string =
`query Test {
allAnimals {
__typename
Expand All @@ -121,15 +121,15 @@ interface Pet {
}
}
}`;

expect(operation.source).toEqual(expected);
});
});

describe("given query with local cache mutation directive", () => {
const documentString: string =
const documentString: string =
`query Test @apollo_client_ios_localCacheMutation {
allAnimals {
allAnimals {
species
... on Pet {
name
Expand All @@ -145,7 +145,41 @@ interface Pet {
const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);
const operation = compilationResult.operations[0];

const expected: string =
const expected: string =
`query Test {
allAnimals {
__typename
species
... on Pet {
name
}
}
}`;

expect(operation.source).toEqual(expected);
});
});

describe("given query with import directive", () => {
const documentString: string =
`query Test @import(module: "MyModuleName") {
allAnimals {
species
... on Pet {
name
}
}
}`;

const document: DocumentNode = parseOperationDocument(
new Source(documentString, "Test Query", { line: 1, column: 1 })
);

it("operation definition should have source not including import directive.", () => {
const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);
const operation = compilationResult.operations[0];

const expected: string =
`query Test {
allAnimals {
__typename
Expand All @@ -155,15 +189,15 @@ interface Pet {
}
}
}`;

expect(operation.source).toEqual(expected);
});
});

describe("given fragment not including __typename field", () => {
const documentString: string =
`fragment Test on Animal {
species
const documentString: string =
`fragment Test on Animal {
species
}`;

const document: DocumentNode = parseOperationDocument(
Expand All @@ -174,12 +208,12 @@ interface Pet {
const compilationResult: CompilationResult = compileDocument(schema, document, false, emptyValidationOptions);
const fragment = compilationResult.fragments[0];

const expected: string =
const expected: string =
`fragment Test on Animal {
__typename
species
}`;

expect(fragment.source).toEqual(expected);
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DirectiveDefinitionNode, DocumentNode, Kind, concatAST } from "graphql";
import { nameNode, stringNode } from "./nodeHelpers";
import { DirectiveDefinitionNode, DocumentNode, Kind, concatAST, GraphQLString } from "graphql";
import { nameNode, nonNullNode, stringNode, typeNode } from "./nodeHelpers";

export const directive_apollo_client_ios_localCacheMutation: DirectiveDefinitionNode = {
kind: Kind.DIRECTIVE_DEFINITION,
Expand All @@ -9,16 +9,33 @@ export const directive_apollo_client_ios_localCacheMutation: DirectiveDefinition
locations: [nameNode("QUERY"), nameNode("MUTATION"), nameNode("SUBSCRIPTION"), nameNode("FRAGMENT_DEFINITION")]
}

export const directive_import_statement: DirectiveDefinitionNode = {
kind: Kind.DIRECTIVE_DEFINITION,
description: stringNode("A directive used by the Apollo iOS code generation engine to generate custom import statements in operation or fragment definition files. An import statement to import a module with the name provided in the `module` argument will be added to the generated definition file."),
name: nameNode("import"),
arguments: [
{
kind: Kind.INPUT_VALUE_DEFINITION,
description: stringNode("The name of the module to import."),
name: nameNode("module"),
type: nonNullNode(typeNode(GraphQLString))
}
],
repeatable: true,
locations: [nameNode("QUERY"), nameNode("MUTATION"), nameNode("SUBSCRIPTION"), nameNode("FRAGMENT_DEFINITION")]
}

export const apolloCodegenSchemaExtension: DocumentNode = {
kind: Kind.DOCUMENT,
definitions: [
directive_apollo_client_ios_localCacheMutation
directive_apollo_client_ios_localCacheMutation,
directive_import_statement
]
}

export function addApolloCodegenSchemaExtensionToDocument(document: DocumentNode): DocumentNode {
return document.definitions.some(definition =>
definition.kind == Kind.DIRECTIVE_DEFINITION &&
return document.definitions.some(definition =>
definition.kind == Kind.DIRECTIVE_DEFINITION &&
definition.name.value == directive_apollo_client_ios_localCacheMutation.name.value
) ?
document :
Expand Down
40 changes: 26 additions & 14 deletions Sources/GraphQLCompiler/JavaScript/src/utilities/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import {
GraphQLError,
DocumentNode,
DirectiveNode,
DirectiveDefinitionNode
} from "graphql";
import { isNode } from "graphql/language/ast";
import { validateSDL } from "graphql/validation/validate";
import { directive_apollo_client_ios_localCacheMutation } from "./apolloCodegenSchemaExtension";
import { directive_apollo_client_ios_localCacheMutation, directive_import_statement } from "./apolloCodegenSchemaExtension";
import { addTypeNameFieldForLegacySafelisting } from "./legacySafelistingTransform";

export class GraphQLSchemaValidationError extends Error {
Expand Down Expand Up @@ -72,12 +73,12 @@ export function transformToNetworkRequestSourceDefinition(
}

return visit(ast, {
SelectionSet: {
leave(node: SelectionSetNode, _, parent) {
SelectionSet: {
leave(node: SelectionSetNode, _, parent) {
if (isNode(parent) && ![Kind.FIELD, Kind.FRAGMENT_DEFINITION].includes(parent.kind)) {
return node
return node
}
return addTypenameFieldToSelectionSetIfNeeded(node)
return addTypenameFieldToSelectionSetIfNeeded(node)
}
},
Field: {
Expand All @@ -87,23 +88,23 @@ export function transformToNetworkRequestSourceDefinition(
},
Directive: {
enter(node: DirectiveNode) {
return stripLocalCacheMutationCustomClientDirective(node)
return stripApolloClientSpecificDirectives(node)
}
}
});
}

function addTypenameFieldToSelectionSetIfNeeded(node: SelectionSetNode): SelectionSetNode {
const hasTypenameField = node.selections.find((selection) =>
function addTypenameFieldToSelectionSetIfNeeded(node: SelectionSetNode): SelectionSetNode {
const hasTypenameField = node.selections.find((selection) =>
selection.kind == typenameField.kind && selection.name.value == typenameField.name.value
);

if (hasTypenameField) {
if (hasTypenameField) {
return node
} else {
return {
...node,
selections: [typenameField, ...node.selections],
...node,
selections: [typenameField, ...node.selections],
};
}
}
Expand All @@ -113,15 +114,26 @@ function transformTypenameFieldIfNeeded(node: FieldNode): FieldNode {
return {
...node,
alias: undefined,
directives: undefined
directives: undefined
}
} else {
return node;
}
}

function stripLocalCacheMutationCustomClientDirective(node: DirectiveNode): DirectiveNode | null {
return (node.name.value == directive_apollo_client_ios_localCacheMutation.name.value) ? null : node;
function stripApolloClientSpecificDirectives(node: DirectiveNode): DirectiveNode | null {
const apolloClientSpecificDirectives: DirectiveDefinitionNode[] = [
directive_apollo_client_ios_localCacheMutation,
directive_import_statement
]

for (const directive of apolloClientSpecificDirectives) {
if (node.name.value == directive.name.value) {
return null
}
}

return node
}

// Utility functions extracted from graphql-js
Expand Down
11 changes: 9 additions & 2 deletions Sources/GraphQLCompiler/JavaScript/src/utilities/nodeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefinitionNode, GraphQLArgument, GraphQLDirective, GraphQLNamedType, InputValueDefinitionNode, Kind, NameNode, StringValueNode, TypeNode, getNamedType } from "graphql";
import { DefinitionNode, GraphQLArgument, GraphQLDirective, GraphQLNamedType, InputValueDefinitionNode, Kind, NameNode, StringValueNode, TypeNode, NamedTypeNode, ListTypeNode, getNamedType } from "graphql";

export function nameNode(name :string): NameNode {
return {
Expand Down Expand Up @@ -34,9 +34,16 @@ export function definitionNode(definition: GraphQLDirective): DefinitionNode {
}
}

function typeNode(type: GraphQLNamedType): TypeNode {
export function typeNode(type: GraphQLNamedType): NamedTypeNode {
return {
kind: Kind.NAMED_TYPE,
name: nameNode(type.name)
}
}

export function nonNullNode(node: NamedTypeNode | ListTypeNode): TypeNode {
return {
kind: Kind.NON_NULL_TYPE,
type: node
}
}

0 comments on commit 740f866

Please sign in to comment.