Skip to content
Draft
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
31 changes: 31 additions & 0 deletions packages/ts-transform-graphql-js-tag/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,5 +262,36 @@ describe("transformer tests", () => {
"
`);
});

it("should convert to imports in relay mode", () => {
expect.assertions(1);
const transformer = new Transformer()
.addTransformer((program: ts.Program) =>
getTransformer({
graphqlTagModule: "graphql-tag",
graphqlTagModuleExport: "gql",
relayMode: true,
}),
)
.addMock({
name: "graphql-tag",
content: `export const gql:any = () => {}`,
})
.setFilePath("/index.tsx");

const actual = transformer.transform(`
import { gql } from "graphql-tag"

export const query = gql\`
query Foo {
foo
}
\`
`);
expect(actual).toMatchInlineSnapshot(`
"export const query = require("./__generated__/Foo.graphql.ts").default;
"
`);
});
});
});
55 changes: 49 additions & 6 deletions packages/ts-transform-graphql-js-tag/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
OperationDefinitionNode,
parse,
Kind,
DefinitionNode,
} from "graphql";

interface GraphQLTagTransformContext {
Expand All @@ -12,18 +13,21 @@ interface GraphQLTagTransformContext {
transformer?: (
node: FragmentDefinitionNode | OperationDefinitionNode,
) => unknown;
relayMode: boolean;
}
export interface GraphQLTagTransformOptions {
graphqlTagModule?: string;
graphqlTagModuleExport?: "default" | string;
transformer?: (
node: FragmentDefinitionNode | OperationDefinitionNode,
) => unknown;
relayMode?: boolean;
}

const DefaultContext: GraphQLTagTransformContext = {
graphqlTagModuleRegexp: new RegExp(/^['"]@graphitation\/graphql-js-tag['"]$/),
graphqlTagModuleExport: "graphql",
relayMode: false,
};

export function getTransformer(
Expand Down Expand Up @@ -59,6 +63,10 @@ export function createTransformerContext(

context.transformer = options.transformer;

if (options.relayMode) {
context.relayMode = options.relayMode;
}

return context;
}

Expand Down Expand Up @@ -169,12 +177,16 @@ function getVisitor(
source = source.replace(/\$\{(.*)\}/g, "");
}

let definitions = getDefinitions(
source,
transformerContext.transformer,
);

return createDocument(definitions, interpolations);
if (transformerContext.relayMode) {
let definitions = getDefinitions(source, undefined);
return createRelayImport(definitions as DefinitionNode[]);
} else {
let definitions = getDefinitions(
source,
transformerContext.transformer,
);
return createDocument(definitions, interpolations);
}
}
}

Expand Down Expand Up @@ -278,6 +290,37 @@ function createDocument(
]);
}

function createRelayImport(definitions: Array<DefinitionNode>) {
if (definitions.length > 1) {
throw new Error("In relay mode you can only have one definition.");
}
const definition = definitions[0];
if (definition) {
if (
(definition.kind === "OperationDefinition" ||
definition.kind === "FragmentDefinition") &&
definition.name
) {
return ts.factory.createPropertyAccessExpression(
ts.factory.createCallExpression(
ts.factory.createIdentifier("require"),
undefined,
[
ts.factory.createStringLiteral(
`./__generated__/${definition.name.value}.graphql.ts`,
),
],
),
ts.factory.createIdentifier("default"),
);
} else {
throw new Error(
"In relay mode for each graphql tag, you can only have one definition, it must be named and be either operation of fragment.",
);
}
}
}

function toAst(literal: any): ts.Expression {
if (literal === null) {
return ts.factory.createNull();
Expand Down