Skip to content
This repository was archived by the owner on Dec 25, 2025. It is now read-only.

Commit 607a842

Browse files
authored
Use graphql-codegen in example app (#170)
1 parent d433fe0 commit 607a842

8 files changed

Lines changed: 2706 additions & 191 deletions

File tree

examples/vite-todoapp/codegen.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { CodegenConfig } from "@graphql-codegen/cli";
2+
3+
const config: CodegenConfig = {
4+
schema: "http://localhost:8001/query",
5+
documents: ["src/**/*.tsx"],
6+
generates: {
7+
"./src/graphql/": {
8+
preset: "client-preset",
9+
plugins: [],
10+
},
11+
},
12+
};
13+
export default config;

examples/vite-todoapp/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@emotion/react": "^11.14.0",
1616
"@fabrix-framework/chakra-ui": "workspace:*",
1717
"@fabrix-framework/fabrix": "workspace:*",
18+
"graphql": "^16.9.0",
1819
"graphql-tag": "^2.12.6",
1920
"next-themes": "^0.4.4",
2021
"react": "^19.0.0",
@@ -25,6 +26,9 @@
2526
"@eslint/js": "^9.15.0",
2627
"@fabrix-framework/eslint-config": "workspace:*",
2728
"@fabrix-framework/prettier-config": "workspace:*",
29+
"@graphql-codegen/cli": "^5.0.4",
30+
"@graphql-codegen/client-preset": "^4.6.0",
31+
"@graphql-typed-document-node/core": "^3.2.0",
2832
"@types/react": "^19.0.7",
2933
"@types/react-dom": "^19.0.3",
3034
"@vitejs/plugin-react": "^4.3.3",

examples/vite-todoapp/src/App.tsx

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Heading, Stack } from "@chakra-ui/react";
2-
import { FabrixComponent, gql } from "@fabrix-framework/fabrix";
2+
import { FabrixComponent } from "@fabrix-framework/fabrix";
33
import { css } from "@emotion/css";
4+
import { graphql } from "./graphql";
45

56
const containerClassName = css`
67
padding: 15px 0;
@@ -14,29 +15,17 @@ function App() {
1415
</Heading>
1516
<FabrixComponent
1617
containerClassName={containerClassName}
17-
query={gql`
18+
query={graphql(`
1819
mutation createTodo($input: TodoInput!) {
19-
addTodo(input: $input)
20-
@fabrixForm(
21-
input: [
22-
{ field: "id", config: { hidden: true } }
23-
{ field: "hasDone", config: { hidden: true } }
24-
{
25-
field: "name"
26-
config: { gridCol: 9 }
27-
constraint: { maxLength: 50 }
28-
}
29-
{ field: "priority", config: { gridCol: 3 } }
30-
]
31-
) {
20+
addTodo(input: $input) {
3221
id
3322
}
3423
}
35-
`}
24+
`)}
3625
/>
3726
<FabrixComponent
3827
containerClassName={containerClassName}
39-
query={gql`
28+
query={graphql(`
4029
query todos {
4130
allTodos
4231
@fabrixView(
@@ -69,7 +58,7 @@ function App() {
6958
}
7059
}
7160
}
72-
`}
61+
`)}
7362
/>
7463
</Stack>
7564
);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* eslint-disable */
2+
import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
3+
import { FragmentDefinitionNode } from 'graphql';
4+
import { Incremental } from './graphql';
5+
6+
7+
export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
8+
infer TType,
9+
any
10+
>
11+
? [TType] extends [{ ' $fragmentName'?: infer TKey }]
12+
? TKey extends string
13+
? { ' $fragmentRefs'?: { [key in TKey]: TType } }
14+
: never
15+
: never
16+
: never;
17+
18+
// return non-nullable if `fragmentType` is non-nullable
19+
export function useFragment<TType>(
20+
_documentNode: DocumentTypeDecoration<TType, any>,
21+
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
22+
): TType;
23+
// return nullable if `fragmentType` is undefined
24+
export function useFragment<TType>(
25+
_documentNode: DocumentTypeDecoration<TType, any>,
26+
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined
27+
): TType | undefined;
28+
// return nullable if `fragmentType` is nullable
29+
export function useFragment<TType>(
30+
_documentNode: DocumentTypeDecoration<TType, any>,
31+
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null
32+
): TType | null;
33+
// return nullable if `fragmentType` is nullable or undefined
34+
export function useFragment<TType>(
35+
_documentNode: DocumentTypeDecoration<TType, any>,
36+
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
37+
): TType | null | undefined;
38+
// return array of non-nullable if `fragmentType` is array of non-nullable
39+
export function useFragment<TType>(
40+
_documentNode: DocumentTypeDecoration<TType, any>,
41+
fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>>
42+
): Array<TType>;
43+
// return array of nullable if `fragmentType` is array of nullable
44+
export function useFragment<TType>(
45+
_documentNode: DocumentTypeDecoration<TType, any>,
46+
fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
47+
): Array<TType> | null | undefined;
48+
// return readonly array of non-nullable if `fragmentType` is array of non-nullable
49+
export function useFragment<TType>(
50+
_documentNode: DocumentTypeDecoration<TType, any>,
51+
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
52+
): ReadonlyArray<TType>;
53+
// return readonly array of nullable if `fragmentType` is array of nullable
54+
export function useFragment<TType>(
55+
_documentNode: DocumentTypeDecoration<TType, any>,
56+
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
57+
): ReadonlyArray<TType> | null | undefined;
58+
export function useFragment<TType>(
59+
_documentNode: DocumentTypeDecoration<TType, any>,
60+
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | Array<FragmentType<DocumentTypeDecoration<TType, any>>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
61+
): TType | Array<TType> | ReadonlyArray<TType> | null | undefined {
62+
return fragmentType as any;
63+
}
64+
65+
66+
export function makeFragmentData<
67+
F extends DocumentTypeDecoration<any, any>,
68+
FT extends ResultOf<F>
69+
>(data: FT, _fragment: F): FragmentType<F> {
70+
return data as FragmentType<F>;
71+
}
72+
export function isFragmentReady<TQuery, TFrag>(
73+
queryNode: DocumentTypeDecoration<TQuery, any>,
74+
fragmentNode: TypedDocumentNode<TFrag>,
75+
data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
76+
): data is FragmentType<typeof fragmentNode> {
77+
const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
78+
?.deferredFields;
79+
80+
if (!deferredFields) return true;
81+
82+
const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
83+
const fragName = fragDef?.name?.value;
84+
85+
const fields = (fragName && deferredFields[fragName]) || [];
86+
return fields.length > 0 && fields.every(field => data && field in data);
87+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* eslint-disable */
2+
import * as types from './graphql';
3+
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
4+
5+
/**
6+
* Map of all GraphQL operations in the project.
7+
*
8+
* This map has several performance disadvantages:
9+
* 1. It is not tree-shakeable, so it will include all operations in the project.
10+
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
11+
* 3. It does not support dead code elimination, so it will add unused operations.
12+
*
13+
* Therefore it is highly recommended to use the babel or swc plugin for production.
14+
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
15+
*/
16+
const documents = {
17+
"\n mutation createTodo($input: TodoInput!) {\n addTodo(input: $input) {\n id\n }\n }\n ": types.CreateTodoDocument,
18+
"\n query todos {\n allTodos\n @fabrixView(\n input: [\n { field: \"collection\", config: { label: \"Your tasks\" } }\n { field: \"collection.id\", config: { hidden: true } }\n { field: \"collection.hasDone\", config: { label: \"Status\" } }\n {\n field: \"collection.actions\"\n config: {\n label: \"Actions\"\n index: -1\n componentType: {\n name: \"IDActionCell\"\n props: [\n { name: \"label\", value: \"Done\" }\n { name: \"color\", value: \"blue\" }\n { name: \"mutation\", value: \"markTodoDone\" }\n ]\n }\n }\n }\n ]\n ) {\n collection {\n id\n name\n priority\n hasDone\n }\n }\n }\n ": types.TodosDocument,
19+
"\n mutation markTodoDone($input: MarkTodoDoneInput!) {\n markTodoDone(input: $input) {\n id\n }\n }\n ": types.MarkTodoDoneDocument,
20+
};
21+
22+
/**
23+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
24+
*
25+
*
26+
* @example
27+
* ```ts
28+
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
29+
* ```
30+
*
31+
* The query argument is unknown!
32+
* Please regenerate the types.
33+
*/
34+
export function graphql(source: string): unknown;
35+
36+
/**
37+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
38+
*/
39+
export function graphql(source: "\n mutation createTodo($input: TodoInput!) {\n addTodo(input: $input) {\n id\n }\n }\n "): (typeof documents)["\n mutation createTodo($input: TodoInput!) {\n addTodo(input: $input) {\n id\n }\n }\n "];
40+
/**
41+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
42+
*/
43+
export function graphql(source: "\n query todos {\n allTodos\n @fabrixView(\n input: [\n { field: \"collection\", config: { label: \"Your tasks\" } }\n { field: \"collection.id\", config: { hidden: true } }\n { field: \"collection.hasDone\", config: { label: \"Status\" } }\n {\n field: \"collection.actions\"\n config: {\n label: \"Actions\"\n index: -1\n componentType: {\n name: \"IDActionCell\"\n props: [\n { name: \"label\", value: \"Done\" }\n { name: \"color\", value: \"blue\" }\n { name: \"mutation\", value: \"markTodoDone\" }\n ]\n }\n }\n }\n ]\n ) {\n collection {\n id\n name\n priority\n hasDone\n }\n }\n }\n "): (typeof documents)["\n query todos {\n allTodos\n @fabrixView(\n input: [\n { field: \"collection\", config: { label: \"Your tasks\" } }\n { field: \"collection.id\", config: { hidden: true } }\n { field: \"collection.hasDone\", config: { label: \"Status\" } }\n {\n field: \"collection.actions\"\n config: {\n label: \"Actions\"\n index: -1\n componentType: {\n name: \"IDActionCell\"\n props: [\n { name: \"label\", value: \"Done\" }\n { name: \"color\", value: \"blue\" }\n { name: \"mutation\", value: \"markTodoDone\" }\n ]\n }\n }\n }\n ]\n ) {\n collection {\n id\n name\n priority\n hasDone\n }\n }\n }\n "];
44+
/**
45+
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
46+
*/
47+
export function graphql(source: "\n mutation markTodoDone($input: MarkTodoDoneInput!) {\n markTodoDone(input: $input) {\n id\n }\n }\n "): (typeof documents)["\n mutation markTodoDone($input: MarkTodoDoneInput!) {\n markTodoDone(input: $input) {\n id\n }\n }\n "];
48+
49+
export function graphql(source: string) {
50+
return (documents as any)[source] ?? {};
51+
}
52+
53+
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;

0 commit comments

Comments
 (0)