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

Add ReScript support #115

Merged
merged 9 commits into from
Oct 29, 2020
5 changes: 5 additions & 0 deletions packages/reason-relay/language-plugin/src/@typings/graphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import "graphql";

declare module "graphql" {
const stripIgnoredCharacters: (source: string) => string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { DefinitionNode, DocumentNode } from "graphql";
import "relay-compiler";
import { Fragment, Parser, Root, Schema } from "relay-compiler";

declare module "relay-compiler" {
const convertASTDocuments: (
extendedSchema: Schema,
ast: DocumentNode[],
parser: (
schema: Schema,
documents: DefinitionNode[]
) => readonly (Root | Fragment)[]
) => readonly (Fragment | Root)[];
}
23 changes: 18 additions & 5 deletions packages/reason-relay/language-plugin/src/FindGraphQLTags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { GraphQLTag } from "relay-compiler/lib/language/RelayLanguagePluginInter
const invariant = require("invariant");

function parseFile(text: string, file: string) {
if (!text.includes("[%relay.")) {
if (!text.includes("[%relay.") && !text.includes("%relay.")) {
return [];
}

invariant(
text.indexOf("[%relay.") >= 0,
text.indexOf("[%relay.") >= 0 || text.indexOf("%relay.") >= 0,
sorenhoyer marked this conversation as resolved.
Show resolved Hide resolved
"RelayFileIRParser: Files should be filtered before passed to the " +
"parser, got unfiltered file `%s`.",
file
Expand All @@ -19,19 +19,32 @@ function parseFile(text: string, file: string) {
* regexp, but this will do just to get things working.
*/

const matched = text.match(
const matchedReason = text.match(
/(?<=\[%relay\.(query|fragment|mutation|subscription))([\s\S]*?)(?=];)/g
);

if (matched) {
if (matchedReason) {
// Removes {||} used in multiline Reason strings
return matched.map(text => ({
return matchedReason.map(text => ({
template: text.replace(/({\||\|})/g, ""),
keyName: null,
sourceLocationOffset: { line: 1, column: 1 }
}));
}

const matchedReScript = text.match(
/(?<=%relay\.(query|fragment|mutation|subscription)\()([\s\S]*?)(?=(\`\s*)\))(\`)/g
);

if (matchedReScript) {
// Removes `` used in multiline ReScript strings
return matchedReScript.map(text => ({
template: text.replace(/`/g, ""),
keyName: null,
sourceLocationOffset: { line: 1, column: 1 }
}));
}

return [];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { stripIgnoredCharacters } from "graphql";
import { join, resolve } from "path";
import { SourceLocation } from "relay-compiler/lib/core/IR";
import { find } from "../FindGraphQLTags";
import {
generateRelaySchema,
generateSchema,
parseGraphQLText,
} from "../test-utils";

const relaySchema = generateRelaySchema(
generateSchema(
resolve(join(__dirname, "..", "test-utils", "testSchema.graphql"))
)
);

const fragment = `
fragment SomeComponent_user on User {
id
}
`;

const query = `
query appQuery($userId: ID!) {
user(id: $userId) {
id
firstName
}
}
`;

describe("Language plugin tests", () => {
describe("RelayFindGraphQLTags", () => {
describe("ReScript Syntax", () => {
it("parses graphql templates", () => {
const graphqlTags = find(
`
module Fragment = %relay.fragment(
\`
${fragment}
\`
)

module Query = %relay.query(
\`
${query}
\`
)
`,
"test"
);

const parsedBodies = graphqlTags.map((tag) => {
const { definitions, schema } = parseGraphQLText(
relaySchema,
tag.template
);

return definitions && definitions.length && schema
? stripIgnoredCharacters(
((definitions[0] as any).loc as SourceLocation).source.body
)
: undefined;
});

expect(parsedBodies).toEqual([
stripIgnoredCharacters(fragment),
stripIgnoredCharacters(query),
]);
});
// describe("ReScript Syntax", () => {});
});
});
});
Loading