Skip to content

Commit 33ec2be

Browse files
committed
Initial commit
0 parents  commit 33ec2be

15 files changed

+1538
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
lib

.prettierrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plugins": ["./node_modules/prettier-plugin-import-sort"]
3+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Dotan Simha
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "apollo-typed-documents",
3+
"version": "0.0.1",
4+
"description": "Get type safety for your apollo documents.",
5+
"keywords": [
6+
"apollo",
7+
"graphql",
8+
"codegen"
9+
],
10+
"homepage": "https://github.com/rubengrill/apollo-typed-documents",
11+
"repository": {
12+
"url": "https://github.com/rubengrill/apollo-typed-documents",
13+
"type": "git"
14+
},
15+
"author": "Ruben Grill <[email protected]>",
16+
"license": "MIT",
17+
"main": "lib/index.js",
18+
"files": [
19+
"src",
20+
"lib"
21+
],
22+
"scripts": {
23+
"build": "tsc",
24+
"prepare": "yarn run build",
25+
"postversion": "git push && git push --tags"
26+
},
27+
"peerDependencies": {
28+
"graphql": "^14.6.0",
29+
"pascal-case": "^3.1.1"
30+
},
31+
"devDependencies": {
32+
"@apollo/react-common": "^3.1.4",
33+
"@apollo/react-hooks": "^3.1.4",
34+
"@graphql-codegen/plugin-helpers": "^1.13.2",
35+
"@types/node": "^13.11.1",
36+
"@types/react": "^16.9.34",
37+
"apollo-boost": "^0.4.7",
38+
"graphql": "^14.6.0",
39+
"import-sort-style-module": "^6.0.0",
40+
"pascal-case": "^3.1.1",
41+
"prettier": "^2.0.4",
42+
"prettier-plugin-import-sort": "^0.0.4",
43+
"typescript": "^3.8.3"
44+
},
45+
"importSort": {
46+
".ts": {
47+
"style": "module",
48+
"parser": "typescript"
49+
}
50+
}
51+
}

src/codegenApolloMock.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { PluginFunction } from "@graphql-codegen/plugin-helpers";
2+
import { visit } from "graphql";
3+
4+
import MockVisitor from "./visitors/MockVisitor";
5+
import TypedVisitor from "./visitors/TypedVisitor";
6+
7+
export const plugin: PluginFunction = (schema, documents) => {
8+
const documentNodes = documents.map((document) => document.document!);
9+
const output: String[] = [];
10+
11+
output.push('import { createApolloMock } from "apollo-typed-documents";');
12+
output.push("const operations = {};");
13+
output.push("export default createApolloMock(operations);");
14+
15+
documentNodes.forEach((documentNode) => {
16+
const typedVisitor = new TypedVisitor(schema);
17+
const mockVisitor = new MockVisitor(output);
18+
const typedDocumentNode = visit(documentNode, typedVisitor);
19+
20+
visit(typedDocumentNode, mockVisitor);
21+
});
22+
23+
return output.join("\n\n");
24+
};

src/codegenTypedDocuments.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import path from "path";
2+
3+
import {
4+
PluginFunction,
5+
PluginValidateFn,
6+
} from "@graphql-codegen/plugin-helpers";
7+
import { visit } from "graphql";
8+
9+
import TypedDocumentVisitor from "./visitors/TypedDocumentVisitor";
10+
import TypedVisitor from "./visitors/TypedVisitor";
11+
12+
export type Config = { typesModule: string };
13+
14+
export const plugin: PluginFunction<Config> = (schema, documents, config) => {
15+
const output: String[] = [];
16+
17+
documents.forEach((document) => {
18+
const basename = path.basename(document.location!);
19+
const typedVisitor = new TypedVisitor(schema);
20+
const typedDocumentVisitor = new TypedDocumentVisitor(
21+
output,
22+
basename,
23+
config
24+
);
25+
const typedDocumentNode = visit(document.document!, typedVisitor);
26+
27+
visit(typedDocumentNode, typedDocumentVisitor);
28+
});
29+
30+
return output.join("\n\n");
31+
};
32+
33+
export const validate: PluginValidateFn<Config> = (
34+
_schema,
35+
_documents,
36+
config
37+
) => {
38+
if (!config.typesModule) {
39+
throw new Error(`You must specify "typesModule"!`);
40+
}
41+
42+
if (
43+
config.typesModule.startsWith("./") ||
44+
config.typesModule.startsWith("../")
45+
) {
46+
throw new Error(
47+
`You must specify a non relative module for "typesModule"!`
48+
);
49+
}
50+
};

src/createApolloMock.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { OperationDefinitionNode } from "graphql";
2+
3+
import { OperationVariables, TypedDocumentNode } from "./types";
4+
5+
export interface ApolloMock<TVariables extends OperationVariables, TData> {
6+
request: {
7+
query: TypedDocumentNode<TVariables, TData>;
8+
variables: TVariables;
9+
};
10+
result: {
11+
data: TData;
12+
};
13+
}
14+
15+
export default (operations: any) => <
16+
TVariables extends OperationVariables,
17+
TData,
18+
TInput extends TVariables = TVariables,
19+
TOutput extends TData = TData
20+
>(
21+
documentNode: TypedDocumentNode<TVariables, TData>,
22+
variables: TInput,
23+
data: TOutput
24+
): ApolloMock<TVariables, TData> => {
25+
const definitionNode = documentNode.definitions[0];
26+
const operationNode = definitionNode as OperationDefinitionNode;
27+
const operationName = operationNode.name!.value;
28+
const operation = operations[operationName];
29+
30+
if (!operation) {
31+
throw new Error(`Couldn't find operation "${operationName}"`);
32+
}
33+
34+
return {
35+
request: {
36+
query: documentNode,
37+
variables,
38+
},
39+
result: {
40+
data: operation(data),
41+
},
42+
};
43+
};

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./types";
2+
export { default as createApolloMock } from "./createApolloMock";

src/reactHooks.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
declare module "@apollo/react-hooks" {
2+
import {
3+
OperationVariables,
4+
TypedDocumentNode,
5+
} from "apollo-typed-documents";
6+
import { QueryResult } from "@apollo/react-common";
7+
import {
8+
MutationHookOptions,
9+
MutationTuple,
10+
QueryHookOptions,
11+
} from "@apollo/react-hooks/lib/types";
12+
13+
export * from "@apollo/react-hooks/lib/index";
14+
15+
export function useQuery<
16+
TData,
17+
TVariables extends OperationVariables,
18+
TOptions extends QueryHookOptions<TData, TVariables>
19+
>(
20+
query: TypedDocumentNode<TVariables, TData>,
21+
options?: TOptions
22+
): QueryResult<TData, TVariables>;
23+
24+
export function useMutation<
25+
TData,
26+
TVariables extends OperationVariables,
27+
TOptions extends MutationHookOptions<TData, TVariables>
28+
>(
29+
mutation: TypedDocumentNode<TVariables, TData>,
30+
options?: TOptions
31+
): MutationTuple<TData, TVariables>;
32+
}

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { DocumentNode } from "graphql";
2+
3+
export type OperationVariables = Record<string, any>;
4+
5+
export interface TypedDocumentNode<
6+
TVariables extends OperationVariables,
7+
TData
8+
> extends DocumentNode {}

0 commit comments

Comments
 (0)