10 |
11 | ## Type parameters
12 |
13 | | Name |
14 | | :------ |
15 | | `TData` |
16 | | `TArgs` |
17 |
18 | ## Properties
19 |
20 | ### existingArgs
21 |
22 | • **existingArgs**: TArgs
23 |
24 | Defined in: [react/src/query/usePaginatedQuery.ts:167](https://github.com/gqless/gqless/blob/master/packages/react/src/query/usePaginatedQuery.ts#L167)
25 |
26 | ---
27 |
28 | ### existingData
29 |
30 | • **existingData**: _undefined_ \| TData
31 |
32 | Defined in: [react/src/query/usePaginatedQuery.ts:166](https://github.com/gqless/gqless/blob/master/packages/react/src/query/usePaginatedQuery.ts#L166)
33 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/graphqlhoc.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'graphqlhoc'
3 | title: 'Interface: GraphQLHOC'
4 | sidebar_label: 'GraphQLHOC'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: GraphQLHOC
10 |
11 | ## Callable
12 |
13 | ▸ **GraphQLHOC**(`component`: (`props`: P) => `null` \| _ReactElement_\>, `options?`: [_GraphQLHOCOptions_](graphqlhocoptions.md)): _function_
14 |
15 | #### Type parameters:
16 |
17 | | Name |
18 | | :--- |
19 | | `P` |
20 |
21 | #### Parameters:
22 |
23 | | Name | Type |
24 | | :---------- | :------------------------------------------------------------------------------------ |
25 | | `component` | (`props`: P) => `null` \| _ReactElement_\> |
26 | | `options?` | [_GraphQLHOCOptions_](graphqlhocoptions.md) |
27 |
28 | **Returns:** (`props`: P) => `null` \| _ReactElement_\>
29 |
30 | Defined in: [react/src/query/hoc.tsx:18](https://github.com/gqless/gqless/blob/master/packages/react/src/query/hoc.tsx#L18)
31 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/graphqlhocoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'graphqlhocoptions'
3 | title: 'Interface: GraphQLHOCOptions'
4 | sidebar_label: 'GraphQLHOCOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: GraphQLHOCOptions
10 |
11 | ## Properties
12 |
13 | ### onError
14 |
15 | • `Optional` **onError**: [_OnErrorHandler_](../modules.md#onerrorhandler)
16 |
17 | Defined in: [react/src/query/hoc.tsx:15](https://github.com/gqless/gqless/blob/master/packages/react/src/query/hoc.tsx#L15)
18 |
19 | ---
20 |
21 | ### staleWhileRevalidate
22 |
23 | • `Optional` **staleWhileRevalidate**: _boolean_
24 |
25 | Defined in: [react/src/query/hoc.tsx:14](https://github.com/gqless/gqless/blob/master/packages/react/src/query/hoc.tsx#L14)
26 |
27 | ---
28 |
29 | ### suspense
30 |
31 | • `Optional` **suspense**: _boolean_ \| { `fallback`: `null` \| _boolean_ \| ReactChild \| ReactFragment \| _ReactPortal_ }
32 |
33 | Defined in: [react/src/query/hoc.tsx:9](https://github.com/gqless/gqless/blob/master/packages/react/src/query/hoc.tsx#L9)
34 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/metastate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'metastate'
3 | title: 'Interface: MetaState'
4 | sidebar_label: 'MetaState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: MetaState
10 |
11 | ## Properties
12 |
13 | ### errors
14 |
15 | • `Optional` **errors**: _GQlessError_[]
16 |
17 | Defined in: [react/src/meta/useMetaState.ts:32](https://github.com/gqless/gqless/blob/master/packages/react/src/meta/useMetaState.ts#L32)
18 |
19 | ---
20 |
21 | ### isFetching
22 |
23 | • **isFetching**: _boolean_
24 |
25 | Defined in: [react/src/meta/useMetaState.ts:31](https://github.com/gqless/gqless/blob/master/packages/react/src/meta/useMetaState.ts#L31)
26 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/preparequery.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'preparequery'
3 | title: 'Interface: PrepareQuery'
4 | sidebar_label: 'PrepareQuery'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: PrepareQuery
10 |
11 | ## Type parameters
12 |
13 | | Name | Type |
14 | | :---------------------- | :------- |
15 | | `GeneratedSchema` | _object_ |
16 | | `GeneratedSchema.query` | _object_ |
17 |
18 | ## Callable
19 |
20 | ▸ **PrepareQuery**(`fn`: TFunction): [_PreparedQuery_](preparedquery.md)
21 |
22 | #### Type parameters:
23 |
24 | | Name | Type |
25 | | :---------- | :-------------------------------------------------------------- |
26 | | `TFunction` | (`query`: GeneratedSchema[``"query"``], `args`: _any_) => _any_ |
27 |
28 | #### Parameters:
29 |
30 | | Name | Type |
31 | | :--- | :-------- |
32 | | `fn` | TFunction |
33 |
34 | **Returns:** [_PreparedQuery_](preparedquery.md)
35 |
36 | Defined in: [react/src/query/preparedQuery.ts:47](https://github.com/gqless/gqless/blob/master/packages/react/src/query/preparedQuery.ts#L47)
37 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/preparereactrender.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'preparereactrender'
3 | title: 'Interface: PrepareReactRender'
4 | sidebar_label: 'PrepareReactRender'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: PrepareReactRender
10 |
11 | ## Callable
12 |
13 | ▸ **PrepareReactRender**(`element`: ReactNode): _Promise_<{ `cacheSnapshot`: _string_ }\>
14 |
15 | #### Parameters:
16 |
17 | | Name | Type |
18 | | :-------- | :-------- |
19 | | `element` | ReactNode |
20 |
21 | **Returns:** _Promise_<{ `cacheSnapshot`: _string_ }\>
22 |
23 | Defined in: [react/src/ssr/ssr.ts:38](https://github.com/gqless/gqless/blob/master/packages/react/src/ssr/ssr.ts#L38)
24 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usehydratecache.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usehydratecache'
3 | title: 'Interface: UseHydrateCache'
4 | sidebar_label: 'UseHydrateCache'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseHydrateCache
10 |
11 | ## Callable
12 |
13 | ▸ **UseHydrateCache**(`__namedParameters`: [_UseHydrateCacheOptions_](usehydratecacheoptions.md)): _void_
14 |
15 | #### Parameters:
16 |
17 | | Name | Type |
18 | | :------------------ | :---------------------------------------------------- |
19 | | `__namedParameters` | [_UseHydrateCacheOptions_](usehydratecacheoptions.md) |
20 |
21 | **Returns:** _void_
22 |
23 | Defined in: [react/src/ssr/ssr.ts:34](https://github.com/gqless/gqless/blob/master/packages/react/src/ssr/ssr.ts#L34)
24 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usehydratecacheoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usehydratecacheoptions'
3 | title: 'Interface: UseHydrateCacheOptions'
4 | sidebar_label: 'UseHydrateCacheOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseHydrateCacheOptions
10 |
11 | ## Hierarchy
12 |
13 | - _Partial_
14 |
15 | ↳ **UseHydrateCacheOptions**
16 |
17 | ## Properties
18 |
19 | ### cacheSnapshot
20 |
21 | • **cacheSnapshot**: _undefined_ \| _string_
22 |
23 | Cache snapshot, returned from `prepareReactRender`
24 |
25 | Overrides: Partial.cacheSnapshot
26 |
27 | Defined in: [react/src/ssr/ssr.ts:12](https://github.com/gqless/gqless/blob/master/packages/react/src/ssr/ssr.ts#L12)
28 |
29 | ---
30 |
31 | ### shouldRefetch
32 |
33 | • `Optional` **shouldRefetch**: _boolean_
34 |
35 | If it should refetch everything after the component is mounted
36 |
37 | **`default`**
38 | false
39 |
40 | Overrides: Partial.shouldRefetch
41 |
42 | Defined in: [react/src/ssr/ssr.ts:19](https://github.com/gqless/gqless/blob/master/packages/react/src/ssr/ssr.ts#L19)
43 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/uselazyqueryoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'uselazyqueryoptions'
3 | title: 'Interface: UseLazyQueryOptions'
4 | sidebar_label: 'UseLazyQueryOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseLazyQueryOptions
10 |
11 | ## Type parameters
12 |
13 | | Name |
14 | | :------ |
15 | | `TData` |
16 |
17 | ## Properties
18 |
19 | ### fetchPolicy
20 |
21 | • `Optional` **fetchPolicy**: [_LazyFetchPolicy_](../modules.md#lazyfetchpolicy)
22 |
23 | Defined in: [react/src/query/useLazyQuery.ts:18](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L18)
24 |
25 | ---
26 |
27 | ### onCompleted
28 |
29 | • `Optional` **onCompleted**: (`data`: TData) => _void_
30 |
31 | #### Type declaration:
32 |
33 | ▸ (`data`: TData): _void_
34 |
35 | #### Parameters:
36 |
37 | | Name | Type |
38 | | :----- | :---- |
39 | | `data` | TData |
40 |
41 | **Returns:** _void_
42 |
43 | Defined in: [react/src/query/useLazyQuery.ts:16](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L16)
44 |
45 | ---
46 |
47 | ### onError
48 |
49 | • `Optional` **onError**: [_OnErrorHandler_](../modules.md#onerrorhandler)
50 |
51 | Defined in: [react/src/query/useLazyQuery.ts:17](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L17)
52 |
53 | ---
54 |
55 | ### retry
56 |
57 | • `Optional` **retry**: RetryOptions
58 |
59 | Defined in: [react/src/query/useLazyQuery.ts:19](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L19)
60 |
61 | ---
62 |
63 | ### suspense
64 |
65 | • `Optional` **suspense**: _boolean_
66 |
67 | Defined in: [react/src/query/useLazyQuery.ts:20](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L20)
68 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/uselazyquerystate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'uselazyquerystate'
3 | title: 'Interface: UseLazyQueryState'
4 | sidebar_label: 'UseLazyQueryState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseLazyQueryState
10 |
11 | ## Type parameters
12 |
13 | | Name |
14 | | :------ |
15 | | `TData` |
16 |
17 | ## Properties
18 |
19 | ### data
20 |
21 | • **data**: _undefined_ \| TData
22 |
23 | Defined in: [react/src/query/useLazyQuery.ts:24](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L24)
24 |
25 | ---
26 |
27 | ### error
28 |
29 | • `Optional` **error**: _GQlessError_
30 |
31 | Defined in: [react/src/query/useLazyQuery.ts:25](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L25)
32 |
33 | ---
34 |
35 | ### isCalled
36 |
37 | • **isCalled**: _boolean_
38 |
39 | Defined in: [react/src/query/useLazyQuery.ts:27](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L27)
40 |
41 | ---
42 |
43 | ### isLoading
44 |
45 | • **isLoading**: _boolean_
46 |
47 | Defined in: [react/src/query/useLazyQuery.ts:26](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useLazyQuery.ts#L26)
48 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usemetastate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usemetastate'
3 | title: 'Interface: UseMetaState'
4 | sidebar_label: 'UseMetaState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseMetaState
10 |
11 | ## Callable
12 |
13 | ▸ **UseMetaState**(`opts?`: [_UseMetaStateOptions_](usemetastateoptions.md)): [_MetaState_](metastate.md)
14 |
15 | #### Type parameters:
16 |
17 | | Name |
18 | | :--- |
19 | | `T` |
20 |
21 | #### Parameters:
22 |
23 | | Name | Type |
24 | | :------ | :-------------------------------------------------- |
25 | | `opts?` | [_UseMetaStateOptions_](usemetastateoptions.md) |
26 |
27 | **Returns:** [_MetaState_](metastate.md)
28 |
29 | Defined in: [react/src/meta/useMetaState.ts:35](https://github.com/gqless/gqless/blob/master/packages/react/src/meta/useMetaState.ts#L35)
30 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usemutation.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usemutation'
3 | title: 'Interface: UseMutation'
4 | sidebar_label: 'UseMutation'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseMutation
10 |
11 | ## Type parameters
12 |
13 | | Name | Type |
14 | | :------------------------- | :------- |
15 | | `GeneratedSchema` | _object_ |
16 | | `GeneratedSchema.mutation` | _object_ |
17 |
18 | ## Callable
19 |
20 | ▸ **UseMutation**(`mutationFn?`: (`mutation`: GeneratedSchema[``"mutation"``], `args`: TArgs) => TData, `options?`: [_UseMutationOptions_](usemutationoptions.md)): readonly [(...`opts`: _undefined_ _extends_ TArgs ? [object?] : [{ `args`: TArgs ; `fn?`: (`mutation`: GeneratedSchema[``"mutation"``], `args`: TArgs) => TData }]) => _Promise_, [_UseMutationState_](usemutationstate.md)]
21 |
22 | #### Type parameters:
23 |
24 | | Name | Default |
25 | | :------ | :---------- |
26 | | `TData` | _unknown_ |
27 | | `TArgs` | _undefined_ |
28 |
29 | #### Parameters:
30 |
31 | | Name | Type |
32 | | :------------ | :-------------------------------------------------------------------- |
33 | | `mutationFn?` | (`mutation`: GeneratedSchema[``"mutation"``], `args`: TArgs) => TData |
34 | | `options?` | [_UseMutationOptions_](usemutationoptions.md) |
35 |
36 | **Returns:** readonly [(...`opts`: _undefined_ _extends_ TArgs ? [object?] : [{ `args`: TArgs ; `fn?`: (`mutation`: GeneratedSchema[``"mutation"``], `args`: TArgs) => TData }]) => _Promise_, [_UseMutationState_](usemutationstate.md)]
37 |
38 | Defined in: [react/src/mutation/useMutation.ts:94](https://github.com/gqless/gqless/blob/master/packages/react/src/mutation/useMutation.ts#L94)
39 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usemutationstate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usemutationstate'
3 | title: 'Interface: UseMutationState'
4 | sidebar_label: 'UseMutationState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseMutationState
10 |
11 | ## Type parameters
12 |
13 | | Name |
14 | | :------ |
15 | | `TData` |
16 |
17 | ## Properties
18 |
19 | ### data
20 |
21 | • **data**: _undefined_ \| TData
22 |
23 | Defined in: [react/src/mutation/useMutation.ts:45](https://github.com/gqless/gqless/blob/master/packages/react/src/mutation/useMutation.ts#L45)
24 |
25 | ---
26 |
27 | ### error
28 |
29 | • `Optional` **error**: _GQlessError_
30 |
31 | Defined in: [react/src/mutation/useMutation.ts:46](https://github.com/gqless/gqless/blob/master/packages/react/src/mutation/useMutation.ts#L46)
32 |
33 | ---
34 |
35 | ### isLoading
36 |
37 | • **isLoading**: _boolean_
38 |
39 | Defined in: [react/src/mutation/useMutation.ts:47](https://github.com/gqless/gqless/blob/master/packages/react/src/mutation/useMutation.ts#L47)
40 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usepreparedqueryoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usepreparedqueryoptions'
3 | title: 'Interface: UsePreparedQueryOptions'
4 | sidebar_label: 'UsePreparedQueryOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UsePreparedQueryOptions
10 |
11 | ## Properties
12 |
13 | ### suspense
14 |
15 | • `Optional` **suspense**: _boolean_
16 |
17 | Defined in: [react/src/query/preparedQuery.ts:12](https://github.com/gqless/gqless/blob/master/packages/react/src/query/preparedQuery.ts#L12)
18 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usequery.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usequery'
3 | title: 'Interface: UseQuery'
4 | sidebar_label: 'UseQuery'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseQuery
10 |
11 | ## Type parameters
12 |
13 | | Name | Type |
14 | | :---------------------- | :------- |
15 | | `GeneratedSchema` | _object_ |
16 | | `GeneratedSchema.query` | _object_ |
17 |
18 | ## Callable
19 |
20 | ▸ **UseQuery**(`options?`: [_UseQueryOptions_](usequeryoptions.md)): [_UseQueryReturnValue_](../modules.md#usequeryreturnvalue)
21 |
22 | #### Parameters:
23 |
24 | | Name | Type |
25 | | :--------- | :-------------------------------------------------------- |
26 | | `options?` | [_UseQueryOptions_](usequeryoptions.md) |
27 |
28 | **Returns:** [_UseQueryReturnValue_](../modules.md#usequeryreturnvalue)
29 |
30 | Defined in: [react/src/query/useQuery.ts:42](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L42)
31 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usequeryoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usequeryoptions'
3 | title: 'Interface: UseQueryOptions'
4 | sidebar_label: 'UseQueryOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseQueryOptions
10 |
11 | ## Type parameters
12 |
13 | | Name | Type | Default |
14 | | :---------------------- | :------- | :------ |
15 | | `GeneratedSchema` | _object_ | _never_ |
16 | | `GeneratedSchema.query` | _object_ | - |
17 |
18 | ## Properties
19 |
20 | ### onError
21 |
22 | • `Optional` **onError**: [_OnErrorHandler_](../modules.md#onerrorhandler)
23 |
24 | Defined in: [react/src/query/useQuery.ts:26](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L26)
25 |
26 | ---
27 |
28 | ### prepare
29 |
30 | • `Optional` **prepare**: (`helpers`: _UseQueryPrepareHelpers_) => _void_
31 |
32 | #### Type declaration:
33 |
34 | ▸ (`helpers`: _UseQueryPrepareHelpers_): _void_
35 |
36 | #### Parameters:
37 |
38 | | Name | Type |
39 | | :-------- | :----------------------------------------- |
40 | | `helpers` | _UseQueryPrepareHelpers_ |
41 |
42 | **Returns:** _void_
43 |
44 | Defined in: [react/src/query/useQuery.ts:27](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L27)
45 |
46 | ---
47 |
48 | ### staleWhileRevalidate
49 |
50 | • `Optional` **staleWhileRevalidate**: `null` \| _string_ \| _number_ \| _boolean_ \| _object_
51 |
52 | Defined in: [react/src/query/useQuery.ts:25](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L25)
53 |
54 | ---
55 |
56 | ### suspense
57 |
58 | • `Optional` **suspense**: _boolean_
59 |
60 | Defined in: [react/src/query/useQuery.ts:24](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L24)
61 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usequerystate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usequerystate'
3 | title: 'Interface: UseQueryState'
4 | sidebar_label: 'UseQueryState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseQueryState
10 |
11 | ## Properties
12 |
13 | ### isLoading
14 |
15 | • `Readonly` **isLoading**: _boolean_
16 |
17 | Useful for `Non-Suspense` usage.
18 |
19 | Defined in: [react/src/query/useQuery.ts:34](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useQuery.ts#L34)
20 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/userefetch.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'userefetch'
3 | title: 'Interface: UseRefetch'
4 | sidebar_label: 'UseRefetch'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseRefetch
10 |
11 | ## Callable
12 |
13 | ▸ **UseRefetch**(`refetchOptions?`: [_UseRefetchOptions_](userefetchoptions.md)): (`refetchArg?`: T \| () => T) => _Promise_ & [_UseRefetchState_](userefetchstate.md)
14 |
15 | #### Parameters:
16 |
17 | | Name | Type |
18 | | :---------------- | :------------------------------------------ |
19 | | `refetchOptions?` | [_UseRefetchOptions_](userefetchoptions.md) |
20 |
21 | **Returns:** (`refetchArg?`: T \| () => T) => _Promise_ & [_UseRefetchState_](userefetchstate.md)
22 |
23 | Defined in: [react/src/query/useRefetch.ts:77](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L77)
24 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/userefetchoptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'userefetchoptions'
3 | title: 'Interface: UseRefetchOptions'
4 | sidebar_label: 'UseRefetchOptions'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseRefetchOptions
10 |
11 | ## Properties
12 |
13 | ### notifyOnNetworkStatusChange
14 |
15 | • `Optional` **notifyOnNetworkStatusChange**: _boolean_
16 |
17 | Defined in: [react/src/query/useRefetch.ts:72](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L72)
18 |
19 | ---
20 |
21 | ### retry
22 |
23 | • `Optional` **retry**: RetryOptions
24 |
25 | Defined in: [react/src/query/useRefetch.ts:74](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L74)
26 |
27 | ---
28 |
29 | ### startWatching
30 |
31 | • `Optional` **startWatching**: _boolean_
32 |
33 | Defined in: [react/src/query/useRefetch.ts:73](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L73)
34 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/userefetchstate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'userefetchstate'
3 | title: 'Interface: UseRefetchState'
4 | sidebar_label: 'UseRefetchState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseRefetchState
10 |
11 | ## Hierarchy
12 |
13 | - _UseRefetchReducerState_
14 |
15 | ↳ **UseRefetchState**
16 |
17 | ## Properties
18 |
19 | ### error
20 |
21 | • `Optional` **error**: _GQlessError_
22 |
23 | Inherited from: UseRefetchReducerState.error
24 |
25 | Defined in: [react/src/query/useRefetch.ts:20](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L20)
26 |
27 | ---
28 |
29 | ### isLoading
30 |
31 | • **isLoading**: _boolean_
32 |
33 | Inherited from: UseRefetchReducerState.isLoading
34 |
35 | Defined in: [react/src/query/useRefetch.ts:19](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L19)
36 |
37 | ---
38 |
39 | ### startWatching
40 |
41 | • **startWatching**: () => _void_
42 |
43 | #### Type declaration:
44 |
45 | ▸ (): _void_
46 |
47 | **Returns:** _void_
48 |
49 | Defined in: [react/src/query/useRefetch.ts:67](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L67)
50 |
51 | ---
52 |
53 | ### stopWatching
54 |
55 | • **stopWatching**: () => _void_
56 |
57 | #### Type declaration:
58 |
59 | ▸ (): _void_
60 |
61 | **Returns:** _void_
62 |
63 | Defined in: [react/src/query/useRefetch.ts:68](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useRefetch.ts#L68)
64 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usesubscription.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usesubscription'
3 | title: 'Interface: UseSubscription'
4 | sidebar_label: 'UseSubscription'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseSubscription
10 |
11 | ## Type parameters
12 |
13 | | Name | Type |
14 | | :----------------------------- | :------- |
15 | | `GeneratedSchema` | _object_ |
16 | | `GeneratedSchema.subscription` | _object_ |
17 |
18 | ## Callable
19 |
20 | ▸ **UseSubscription**(): GeneratedSchema[``"subscription"``]
21 |
22 | **Returns:** GeneratedSchema[``"subscription"``]
23 |
24 | Defined in: [react/src/subscription/useSubscription.ts:15](https://github.com/gqless/gqless/blob/master/packages/react/src/subscription/useSubscription.ts#L15)
25 |
--------------------------------------------------------------------------------
/docs/react/api/interfaces/usetransactionquerystate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 'usetransactionquerystate'
3 | title: 'Interface: UseTransactionQueryState'
4 | sidebar_label: 'UseTransactionQueryState'
5 | custom_edit_url: null
6 | hide_title: true
7 | ---
8 |
9 | # Interface: UseTransactionQueryState
10 |
11 | ## Type parameters
12 |
13 | | Name |
14 | | :------ |
15 | | `TData` |
16 |
17 | ## Properties
18 |
19 | ### data
20 |
21 | • **data**: _undefined_ \| TData
22 |
23 | Defined in: [react/src/query/useTransactionQuery.ts:30](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useTransactionQuery.ts#L30)
24 |
25 | ---
26 |
27 | ### error
28 |
29 | • `Optional` **error**: _GQlessError_
30 |
31 | Defined in: [react/src/query/useTransactionQuery.ts:31](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useTransactionQuery.ts#L31)
32 |
33 | ---
34 |
35 | ### isCalled
36 |
37 | • **isCalled**: _boolean_
38 |
39 | Defined in: [react/src/query/useTransactionQuery.ts:33](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useTransactionQuery.ts#L33)
40 |
41 | ---
42 |
43 | ### isLoading
44 |
45 | • **isLoading**: _boolean_
46 |
47 | Defined in: [react/src/query/useTransactionQuery.ts:32](https://github.com/gqless/gqless/blob/master/packages/react/src/query/useTransactionQuery.ts#L32)
48 |
--------------------------------------------------------------------------------
/docs/react/subscriptions.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: subscriptions
3 | title: Using Subscriptions with React
4 | sidebar_label: Subscriptions
5 | ---
6 |
7 | ## `useSubscription`
8 |
9 | Hook designed to be used for [GraphQL Subscriptions](https://github.com/graphql/graphql-spec/blob/main/rfcs/Subscriptions.md).
10 |
11 | For more configuration of Subscriptions [check here](/client/subscriptions).
12 |
13 | ### Features:
14 |
15 | - Subscribe on-demand
16 | - Automatic unsubscribe on component unmount
17 | - Automatic updates on cache changes
18 |
19 | ### Example
20 |
21 | ```tsx
22 | import { useSubscription } from '../gqless';
23 |
24 | export function Example() {
25 | const { newNotification } = useSubscription();
26 |
27 | if (newNotification) {
28 | return (
29 |
30 | New Notification: {newNotification}
31 |
32 | );
33 | }
34 | return Waiting for new notifications...
;
35 | }
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/react/suspense.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: suspense
3 | title: Using React Suspense
4 | sidebar_label: Suspense & usage without
5 | ---
6 |
7 | ## How to enable it
8 |
9 | One of the goals of GQless is to embrace React [Suspense](https://reactjs.org/docs/concurrent-mode-suspense.html) & [Concurrent Mode](https://reactjs.org/docs/concurrent-mode-intro.html), however these features are still in development by the React team.
10 |
11 | Until these features become widespread enough, you will need to **opt-in** for Suspense support via configuration. This can be done directly in hook, or via the [defaults of the client](/react/config#defaults).
12 |
13 | ```ts
14 | // Enabling support with hooks
15 | const query = useQuery({ suspense: true });
16 |
17 | // Enabling support with HoC
18 | const Component = graphql(() => , { suspense: true });
19 | ```
20 |
21 | ## Usage without Suspense
22 |
23 | All hooks return a `$state` object, when suspense support is not enabled.
24 |
25 | ```tsx
26 | function Example() {
27 | const query = useQuery({ suspense: false });
28 |
29 | if (query.$state.isLoading) return Loading...
;
30 |
31 | return {helloWorld}
;
32 | }
33 | ```
34 |
35 | ## Suspense & SSR
36 |
37 | React doesn't yet support suspense whilst rendering on the server, so [react-ssr-prepass](https://github.com/FormidableLabs/react-ssr-prepass) is used in our SSR functions:
38 |
39 | 
40 |
41 | And for that, reason we suggest using a slighty modified `Suspense` component:
42 |
43 | ```tsx
44 | import { Suspense as ReactSuspense, SuspenseProps } from 'react';
45 |
46 | export const Suspense =
47 | typeof window !== 'undefined'
48 | ? ReactSuspense
49 | : function SuspenseSSR({ children }: SuspenseProps) {
50 | return <>{children}>;
51 | };
52 | ```
53 |
54 | And everything should work as you might expect.
55 |
--------------------------------------------------------------------------------
/examples/cra/.env.local:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/examples/cra/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/examples/cra/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": false
3 | }
4 |
--------------------------------------------------------------------------------
/examples/cra/gqless.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import("@gqless/cli").GQlessConfig}
3 | */
4 | const config = {
5 | enumsAsStrings: true,
6 | react: true,
7 | scalarTypes: {
8 | DateTime: "string",
9 | NonNegativeInt: "number",
10 | NonEmptyString: "string",
11 | EmailAddress: "string",
12 | },
13 | preImport: "",
14 | introspection: {
15 | endpoint: "https://examples-api.gqless.com/graphql",
16 | headers: {},
17 | },
18 | destination: "./src/gqless/index.ts",
19 | subscriptions: true,
20 | javascriptOutput: false,
21 | };
22 |
23 | module.exports = config;
24 |
--------------------------------------------------------------------------------
/examples/cra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cra-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "react-scripts build",
7 | "dev": "react-scripts start",
8 | "eject": "react-scripts eject",
9 | "generate": "gqless generate",
10 | "prepare": "react-scripts build",
11 | "prepare-lock": "npm install --package-lock-only",
12 | "start": "react-scripts start"
13 | },
14 | "browserslist": {
15 | "production": [
16 | ">0.2%",
17 | "not dead",
18 | "not op_mini all"
19 | ],
20 | "development": [
21 | "last 1 chrome version",
22 | "last 1 firefox version",
23 | "last 1 safari version"
24 | ]
25 | },
26 | "eslintConfig": {
27 | "extends": [
28 | "react-app",
29 | "react-app/jest"
30 | ]
31 | },
32 | "dependencies": {
33 | "@babel/core": "^7.13.15",
34 | "@emotion/css": "^11.1.3",
35 | "@emotion/react": "^11.1.5",
36 | "@emotion/styled": "^11.3.0",
37 | "@gqless/cli": "workspace:^2.0.16",
38 | "@gqless/logger": "workspace:^2.0.11",
39 | "@gqless/react": "workspace:^2.0.15",
40 | "@gqless/subscriptions": "workspace:^1.0.11",
41 | "@testing-library/jest-dom": "^5.11.10",
42 | "@testing-library/react": "^11.2.6",
43 | "@testing-library/user-event": "^13.1.5",
44 | "@types/jest": "^26.0.22",
45 | "@types/node": "^14.14.41",
46 | "@types/react": "^17.0.3",
47 | "@types/react-dom": "^17.0.3",
48 | "@types/react-router-dom": "^5.1.7",
49 | "framer-motion": "^4.1.5",
50 | "gqless": "workspace:^2.0.14",
51 | "graphql": "^15.5.0",
52 | "prop-types": "^15.7.2",
53 | "react": "^17.0.2",
54 | "react-dom": "^17.0.2",
55 | "react-router-dom": "^5.2.0",
56 | "react-scripts": "^4.0.3",
57 | "react-use": "^17.2.3",
58 | "typescript": "^4.2.4",
59 | "web-vitals": "^1.1.1"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/examples/cra/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/examples/cra/public/favicon.ico
--------------------------------------------------------------------------------
/examples/cra/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/examples/cra/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/examples/cra/public/logo192.png
--------------------------------------------------------------------------------
/examples/cra/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/examples/cra/public/logo512.png
--------------------------------------------------------------------------------
/examples/cra/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/cra/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/cra/sandbox.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "infiniteLoopProtection": true,
3 | "hardReloadOnChange": false,
4 | "view": "browser"
5 | }
6 |
--------------------------------------------------------------------------------
/examples/cra/src/components/CreatePost.tsx:
--------------------------------------------------------------------------------
1 | /** @jsxImportSource @emotion/react */
2 |
3 | import { getFields } from "gqless";
4 | import { useRef } from "react";
5 |
6 | import { CursorConnectionArgs, useMutation } from "../gqless";
7 |
8 | export function CreatePost({
9 | fetchMore,
10 | }: {
11 | fetchMore: (args: CursorConnectionArgs) => void;
12 | }) {
13 | const inputRef = useRef(null);
14 | const [createPost, { isLoading }] = useMutation(
15 | (mutation, title: string) => {
16 | return getFields(
17 | mutation.createPost({
18 | post: {
19 | title,
20 | },
21 | })
22 | );
23 | },
24 | {
25 | onCompleted(_data) {
26 | fetchMore({
27 | first: 5,
28 | });
29 | },
30 | }
31 | );
32 |
33 | return (
34 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/examples/cra/src/components/Hello.tsx:
--------------------------------------------------------------------------------
1 | /** @jsxImportSource @emotion/react */
2 |
3 | import { Fragment, Suspense, useState } from "react";
4 |
5 | import { useQuery, graphql, query } from "../gqless";
6 |
7 | function NamesList({ n }: { n: number }) {
8 | const { namesList } = useQuery();
9 |
10 | return (
11 |
12 | {namesList({
13 | n,
14 | }).map((name, index) => {
15 | return - {name}
;
16 | })}
17 |
18 | );
19 | }
20 |
21 | function Names() {
22 | const [n, setN] = useState(10);
23 | return (
24 |
25 |
26 | setN(Math.max(ev.target.valueAsNumber, 0))}
29 | css={{
30 | width: "100px",
31 | }}
32 | type="number"
33 | />
34 |
35 | Names Loading...
}>
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | const HelloWorld = graphql(
43 | function HelloWorld() {
44 | return (
45 |
50 | {query.hello}
51 |
52 | );
53 | },
54 | {
55 | suspense: {
56 | fallback: Hello Loading...
,
57 | },
58 | }
59 | );
60 |
61 | export function Hello() {
62 | return (
63 |
64 |
65 |
66 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/examples/cra/src/components/Login.tsx:
--------------------------------------------------------------------------------
1 | /** @jsxImportSource @emotion/react */
2 |
3 | import { prepass } from "gqless";
4 | import { useRef } from "react";
5 |
6 | import { useMutation } from "../gqless";
7 | import { useCurrentUser } from "../hooks/currentUser";
8 |
9 | export function Login() {
10 | const { currentUser } = useCurrentUser();
11 | const [login, { data, isLoading, error }] = useMutation(
12 | ({ login }, email: string) => {
13 | return prepass(
14 | login({
15 | input: {
16 | email,
17 | },
18 | }),
19 | "user.email",
20 | "error",
21 | "token"
22 | );
23 | }
24 | );
25 | const inputRef = useRef(null);
26 |
27 | if (currentUser.user) return Already Logged in
;
28 |
29 | const errorMessage = (data && data.error) || (error && error.message);
30 |
31 | return (
32 |
33 | {errorMessage ?
{errorMessage}
: null}
34 |
64 |
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/examples/cra/src/components/Register.tsx:
--------------------------------------------------------------------------------
1 | /** @jsxImportSource @emotion/react */
2 |
3 | import { prepass } from "gqless";
4 | import { useRef } from "react";
5 |
6 | import { useMutation } from "../gqless";
7 | import { useCurrentUser } from "../hooks/currentUser";
8 |
9 | export function Register() {
10 | const { currentUser } = useCurrentUser();
11 | const [register, { data, isLoading, error }] = useMutation(
12 | ({ register }, email: string) => {
13 | return prepass(
14 | register({
15 | input: {
16 | email,
17 | },
18 | }),
19 | "user.email",
20 | "error",
21 | "token"
22 | );
23 | }
24 | );
25 | const inputRef = useRef(null);
26 |
27 | if (currentUser.user) return Already Logged in
;
28 |
29 | const errorMessage = (data && data.error) || (error && error.message);
30 |
31 | return (
32 |
33 | {errorMessage ?
{errorMessage}
: null}
34 |
64 |
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/examples/cra/src/hooks/currentUser.ts:
--------------------------------------------------------------------------------
1 | import { setAuthorizationToken, useQuery } from "../gqless";
2 | import { useEffect } from "react";
3 |
4 | export function useCurrentUser(suspense = true) {
5 | const { currentUser } = useQuery({
6 | prepare({ prepass, query: { currentUser } }) {
7 | prepass(currentUser, "error", "token", "user.email");
8 | },
9 | suspense,
10 | });
11 |
12 | const token = currentUser.token;
13 | useEffect(() => {
14 | if (token !== undefined) setAuthorizationToken(token);
15 | }, [token]);
16 |
17 | return {
18 | currentUser,
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/examples/cra/src/index.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Lato&display=swap");
2 |
3 | body {
4 | font-family: "Lato", sans-serif;
5 | /* Used to prevent CodeSandbox embed buttons */
6 | padding-bottom: 50px;
7 | }
8 |
9 | a:link {
10 | text-decoration: inherit;
11 | color: inherit;
12 | font-weight: bold;
13 | box-shadow: 1px 1px 1px 1px;
14 | border-radius: 3px;
15 | padding: 2px;
16 | }
17 |
18 | a:visited {
19 | text-decoration: inherit;
20 | color: inherit;
21 | font-weight: bold;
22 | }
23 |
24 | a:hover {
25 | color: rgb(52, 52, 170);
26 | }
27 |
--------------------------------------------------------------------------------
/examples/cra/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/examples/cra/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from "web-vitals";
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/examples/cra/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import "@testing-library/jest-dom";
6 |
--------------------------------------------------------------------------------
/examples/cra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"]
20 | }
21 |
--------------------------------------------------------------------------------
/examples/github/gqless.config.cjs:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 | /**
4 | * @type {import("@gqless/cli").GQlessConfig}
5 | */
6 | const config = {
7 | enumsAsStrings: false,
8 | react: false,
9 | scalarTypes: {
10 | DateTime: 'string',
11 | Date: 'string',
12 | GitObjectID: 'string',
13 | GitSSHRemote: 'string',
14 | GitTimestamp: 'string',
15 | HTML: 'string',
16 | PreciseDateTime: 'string',
17 | URI: 'string',
18 | X509Certificate: 'string',
19 | },
20 | preImport: '',
21 | introspection: {
22 | endpoint: 'https://api.github.com/graphql',
23 | headers: {
24 | authorization: `bearer ${process.env.GITHUB_TOKEN}`,
25 | },
26 | },
27 | destination: './src/gqless/index.ts',
28 | subscriptions: false,
29 | javascriptOutput: false,
30 | };
31 |
32 | module.exports = config;
33 |
--------------------------------------------------------------------------------
/examples/github/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('test-utils/jest.config.js').default;
2 |
--------------------------------------------------------------------------------
/examples/github/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "github-example",
3 | "version": "1.0.0",
4 | "private": true,
5 | "description": "",
6 | "license": "MIT",
7 | "author": "GQless ",
8 | "scripts": {
9 | "generate": "gqless generate",
10 | "test:manual": "jest -u"
11 | },
12 | "dependencies": {
13 | "@gqless/cli": "workspace:^2.0.16",
14 | "dotenv": "^8.2.0",
15 | "gqless": "workspace:^2.0.14",
16 | "test-utils": "workspace:^0.1.0"
17 | },
18 | "devDependencies": {
19 | "isomorphic-unfetch": "^3.1.0",
20 | "jest": "^26.6.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/github/src/gqless/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * GQLESS: You can safely modify this file and Query Fetcher based on your needs
3 | */
4 |
5 | import 'isomorphic-unfetch';
6 | import 'dotenv/config';
7 |
8 | import { createClient, QueryFetcher } from 'gqless';
9 |
10 | import {
11 | generatedSchema,
12 | GeneratedSchema,
13 | scalarsEnumsHash,
14 | SchemaObjectTypes,
15 | SchemaObjectTypesNames,
16 | } from './schema.generated';
17 |
18 | if (!process.env.GITHUB_TOKEN) {
19 | console.error(
20 | 'You have to create a .env file with a Github Personal Access token, like this: \nGITHUB_TOKEN=your_token_here'
21 | );
22 | process.exit(1);
23 | }
24 |
25 | const queryFetcher: QueryFetcher = async function (query, variables) {
26 | const response = await fetch('https://api.github.com/graphql', {
27 | method: 'POST',
28 | headers: {
29 | 'Content-Type': 'application/json',
30 | authorization: `bearer ${process.env.GITHUB_TOKEN}`,
31 | },
32 | body: JSON.stringify({
33 | query,
34 | variables,
35 | }),
36 | mode: 'cors',
37 | });
38 |
39 | const json = await response.json();
40 |
41 | return json;
42 | };
43 |
44 | export const client = createClient<
45 | GeneratedSchema,
46 | SchemaObjectTypesNames,
47 | SchemaObjectTypes
48 | >({
49 | schema: generatedSchema,
50 | scalarsEnumsHash,
51 | queryFetcher,
52 | });
53 |
54 | export const {
55 | query,
56 | mutation,
57 | mutate,
58 | subscription,
59 | resolved,
60 | refetch,
61 | } = client;
62 |
63 | export * from './schema.generated';
64 |
--------------------------------------------------------------------------------
/examples/mercurius/.browserslistrc:
--------------------------------------------------------------------------------
1 | node 10
--------------------------------------------------------------------------------
/examples/mercurius/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | dist
5 |
--------------------------------------------------------------------------------
/examples/mercurius/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright © `2021` `GQless`
4 |
5 | Permission is hereby granted, free of charge, to any person
6 | obtaining a copy of this software and associated documentation
7 | files (the “Software”), to deal in the Software without
8 | restriction, including without limitation the rights to use,
9 | copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 | OTHER DEALINGS IN THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/examples/mercurius/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/examples/mercurius/README.md
--------------------------------------------------------------------------------
/examples/mercurius/generate.ts:
--------------------------------------------------------------------------------
1 | import { writeGenerate } from '@gqless/cli';
2 | import { app } from './src';
3 |
4 | (async () => {
5 | await app.ready();
6 |
7 | const destinationPath = await writeGenerate(
8 | app.graphql.schema,
9 | './src/generated/gqless.ts',
10 | {
11 | scalarTypes: {
12 | ExampleScalar: 'string',
13 | },
14 | }
15 | );
16 |
17 | console.log(`gqless schema generated at ${destinationPath}`);
18 | })();
19 |
--------------------------------------------------------------------------------
/examples/mercurius/gqless.config.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import("@gqless/cli").GQlessConfig}
3 | */
4 | const config = {
5 | enumsAsStrings: false,
6 | react: false,
7 | scalarTypes: { DateTime: 'string' },
8 | preImport: '',
9 | introspection: { endpoint: 'SPECIFY_ENDPOINT_OR_SCHEMA_FILE_PATH_HERE' },
10 | destination: './src/generated/graphql.ts',
11 | subscriptions: false,
12 | };
13 |
14 | module.exports = config;
15 |
--------------------------------------------------------------------------------
/examples/mercurius/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('test-utils/jest.config.js').getConfig({
2 | testTimeout: 20000,
3 | });
4 |
--------------------------------------------------------------------------------
/examples/mercurius/listen.js:
--------------------------------------------------------------------------------
1 | const { app } = require('./');
2 |
3 | app.listen(3000, (err) => {
4 | if (err) {
5 | console.error(err);
6 | process.exit(1);
7 | }
8 | console.log('Listening on http://localhost:3000');
9 | });
10 |
--------------------------------------------------------------------------------
/examples/mercurius/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mercurius-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "license": "MIT",
6 | "author": "GQless ",
7 | "main": "dist/index.js",
8 | "module": "dist/mercurius-example.esm.js",
9 | "typings": "dist/index.d.ts",
10 | "files": [
11 | "dist",
12 | "src"
13 | ],
14 | "scripts": {
15 | "analyze": "size-limit --why",
16 | "build": "build mercurius",
17 | "generate": "ts-node --skip-project generate.ts",
18 | "listen": "node listen.js",
19 | "prepare": "build mercurius",
20 | "size": "size-limit",
21 | "start": "watch mercurius",
22 | "test": "jest",
23 | "test:watch": "watch mercurius"
24 | },
25 | "dependencies": {
26 | "@gqless/cli": "workspace:^2.0.16",
27 | "@graphql-typed-document-node/core": "^3.1.0",
28 | "fastify": "^3.14.2",
29 | "gqless": "workspace:^2.0.14",
30 | "graphql": "^15.5.0",
31 | "lodash": "^4.17.21",
32 | "mercurius": "^7.4.0",
33 | "mercurius-codegen": "^1.4.3",
34 | "randomstring": "^1.1.5",
35 | "test-utils": "workspace:^0.1.0"
36 | },
37 | "devDependencies": {
38 | "@size-limit/preset-small-lib": "^4.10.2",
39 | "@types/lodash": "^4.14.168",
40 | "@types/randomstring": "^1.1.6",
41 | "build-utils": "workspace:*",
42 | "jest": "^26.6.3",
43 | "mercurius-integration-testing": "^3.1.3",
44 | "size-limit": "^4.10.2",
45 | "ts-node": "^9.1.1",
46 | "tslib": "^2.2.0",
47 | "typescript": "^4.2.4"
48 | },
49 | "engines": {
50 | "node": ">=10"
51 | },
52 | "size-limit": [
53 | {
54 | "path": "dist/mercurius-example.cjs.production.min.js",
55 | "limit": "10 KB"
56 | },
57 | {
58 | "path": "dist/mercurius-example.esm.js",
59 | "limit": "10 KB"
60 | }
61 | ]
62 | }
63 |
--------------------------------------------------------------------------------
/examples/mercurius/src/generated/gqless.ts:
--------------------------------------------------------------------------------
1 | import { createMercuriusTestClient } from 'mercurius-integration-testing';
2 |
3 | import { createClient, QueryFetcher } from 'gqless';
4 |
5 | import { app } from '../';
6 | import {
7 | GeneratedSchema,
8 | generatedSchema,
9 | scalarsEnumsHash,
10 | SchemaObjectTypes,
11 | SchemaObjectTypesNames,
12 | } from './schema.generated';
13 |
14 | const testClient = createMercuriusTestClient(app);
15 | const queryFetcher: QueryFetcher = function (query, variables) {
16 | return testClient.query(query, {
17 | variables,
18 | });
19 | };
20 |
21 | export const client = createClient<
22 | GeneratedSchema,
23 | SchemaObjectTypesNames,
24 | SchemaObjectTypes
25 | >({
26 | schema: generatedSchema,
27 | scalarsEnumsHash,
28 | queryFetcher,
29 | normalization: {
30 | identifier(obj) {
31 | switch (obj.__typename) {
32 | case 'A': {
33 | return obj.a;
34 | }
35 | default: {
36 | return;
37 | }
38 | }
39 | },
40 | keyFields: {},
41 | },
42 | });
43 |
44 | export const {
45 | query,
46 | mutation,
47 | mutate,
48 | subscription,
49 | resolved,
50 | refetch,
51 | } = client;
52 |
53 | export * from './schema.generated';
54 |
--------------------------------------------------------------------------------
/examples/mercurius/src/graphql/operations.gql:
--------------------------------------------------------------------------------
1 | query simpleString {
2 | simpleString
3 | union {
4 | __typename
5 | ... on A {
6 | a
7 | }
8 | ... on B {
9 | b
10 | }
11 | ... on C {
12 | c
13 | }
14 | }
15 | }
16 |
17 | query arrayObjectArgs {
18 | arrayObjectArgs(limit: 2) {
19 | name
20 | father {
21 | name
22 | father {
23 | name
24 | }
25 | }
26 | }
27 | }
28 |
29 | query multipleArgs {
30 | a1: objectWithArgs(who: "hello") {
31 | zxc: name
32 | abc: name
33 | }
34 | a2: objectWithArgs(who: "hello2") {
35 | name
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/mercurius/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": ["**/*.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/examples/mercurius/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
3 | "include": ["src", "types"],
4 | "compilerOptions": {
5 | "module": "esnext",
6 | "lib": ["dom", "esnext"],
7 | "importHelpers": true,
8 | // output .d.ts declaration files for consumers
9 | "declaration": true,
10 | // output .js.map sourcemap files for consumers
11 | "sourceMap": true,
12 | // match output dir to input dir. e.g. dist/index instead of dist/src/index
13 | "rootDir": "./src",
14 | // stricter type-checking for stronger correctness. Recommended by TS
15 | "strict": true,
16 | // linter checks for common issues
17 | "noImplicitReturns": true,
18 | "noFallthroughCasesInSwitch": true,
19 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | // use Node's module resolution algorithm, instead of the legacy TS one
23 | "moduleResolution": "node",
24 | // transpile JSX to React.createElement
25 | "jsx": "react",
26 | // interop between ESM and CJS modules. Recommended by TS
27 | "esModuleInterop": true,
28 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
29 | "skipLibCheck": true,
30 | // error out if import and file system have a casing mismatch. Recommended by TS
31 | "forceConsistentCasingInFileNames": true,
32 | "noEmit": true,
33 | "preserveWatchOutput": true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/examples/react/api/server.ts:
--------------------------------------------------------------------------------
1 | import Fastify from 'fastify';
2 | import ms from 'ms';
3 | import FastifyNext from 'fastify-nextjs';
4 | import { resolve } from 'path';
5 | import mercuriusUpload from 'mercurius-upload';
6 | import AltairFastify from 'altair-fastify-plugin';
7 |
8 | import { register } from './graphql';
9 |
10 | const app = Fastify({
11 | logger: true,
12 | pluginTimeout: ms('60 seconds'),
13 | });
14 |
15 | app.register(AltairFastify);
16 |
17 | app.register(mercuriusUpload, {});
18 |
19 | register(app).catch(console.error);
20 |
21 | console.log('> React example API server started.');
22 |
23 | app
24 | .register(FastifyNext, {
25 | logLevel: 'error',
26 | dir: resolve(__dirname, '../'),
27 | })
28 | .after(() => {
29 | try {
30 | app.next('/*');
31 | } catch (err) {
32 | console.error(err);
33 | }
34 | });
35 |
36 | app.listen(4141, '0.0.0.0', (err) => {
37 | if (err) throw err;
38 | });
39 |
--------------------------------------------------------------------------------
/examples/react/gqless.config.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import("@gqless/cli").GQlessConfig}
3 | */
4 | const config = {
5 | enumsAsStrings: false,
6 | react: false,
7 | scalarTypes: { DateTime: 'string', Upload: 'File' },
8 | preImport: '',
9 | introspection: { endpoint: 'SPECIFY_ENDPOINT_OR_SCHEMA_FILE_PATH_HERE' },
10 | destination: './src/generated/graphql.ts',
11 | };
12 |
13 | module.exports = config;
14 |
--------------------------------------------------------------------------------
/examples/react/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/examples/react/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // experimental: {
3 | // reactMode: 'concurrent',
4 | // },
5 |
6 | // Set to `true` to test consistency.
7 | // Set to `false` to test minimal renders possible.
8 | reactStrictMode: false,
9 |
10 | future: {
11 | webpack5: true,
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/examples/react/open-browser.mjs:
--------------------------------------------------------------------------------
1 | import { differenceInMinutes } from 'date-fns';
2 | import { existsSync, readFileSync, writeFileSync } from 'fs';
3 | import open from 'open';
4 |
5 | const lastOpenBrowserDateFile = './last-browser-open';
6 |
7 | if (existsSync(lastOpenBrowserDateFile)) {
8 | const date = new Date(
9 | readFileSync(lastOpenBrowserDateFile, {
10 | encoding: 'utf-8',
11 | })
12 | );
13 |
14 | if (Math.abs(differenceInMinutes(date, new Date())) > 30) {
15 | open('http://localhost:4141', {}).catch(console.error);
16 | }
17 | } else {
18 | open('http://localhost:4141', {}).catch(console.error);
19 | }
20 |
21 | writeFileSync(lastOpenBrowserDateFile, new Date().toISOString(), {
22 | encoding: 'utf-8',
23 | });
24 |
--------------------------------------------------------------------------------
/examples/react/src/components/NoSSR.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from 'next/dynamic';
2 | import { ReactNode } from 'react';
3 |
4 | export const NoSSR = dynamic(
5 | () =>
6 | Promise.resolve(function NoSSR({ children }: { children: ReactNode }) {
7 | return <>{children}>;
8 | }),
9 | {
10 | ssr: false,
11 | }
12 | );
13 |
--------------------------------------------------------------------------------
/examples/react/src/components/client.ts:
--------------------------------------------------------------------------------
1 | import { createLogger } from '@gqless/logger';
2 |
3 | import { createReactClient } from '@gqless/react';
4 | import { client, GeneratedSchema } from '../graphql/gqless';
5 |
6 | export const {
7 | useTransactionQuery,
8 | useQuery,
9 | state,
10 | graphql,
11 | useRefetch,
12 | useLazyQuery,
13 | prepareReactRender,
14 | useHydrateCache,
15 | useMutation,
16 | useMetaState,
17 | useSubscription,
18 | prepareQuery,
19 | usePaginatedQuery,
20 | } = createReactClient(client, {
21 | defaults: {
22 | suspense: true,
23 | staleWhileRevalidate: false,
24 | transactionQuerySuspense: false,
25 | },
26 | });
27 |
28 | if (typeof window !== 'undefined') {
29 | const logger = createLogger(client, {});
30 | logger.start();
31 | }
32 |
33 | export const { refetch, buildSelection } = client;
34 |
--------------------------------------------------------------------------------
/examples/react/src/components/common.ts:
--------------------------------------------------------------------------------
1 | import {
2 | MutableRefObject,
3 | useCallback,
4 | useEffect,
5 | useLayoutEffect,
6 | useReducer,
7 | useRef,
8 | } from 'react';
9 |
10 | export const useIsomorphicLayoutEffect =
11 | typeof window !== 'undefined' ? useLayoutEffect : useEffect;
12 |
13 | const updateReducer = (num: number): number => (num + 1) % 1_000_000;
14 |
15 | export const useBatchUpdate = () => {
16 | const isMounted = useIsMounted();
17 |
18 | const isRendering = useRef(true);
19 | isRendering.current = true;
20 |
21 | const [, update] = useReducer(updateReducer, 0);
22 |
23 | useEffect(() => {
24 | isRendering.current = false;
25 | });
26 |
27 | return useCallback(() => {
28 | if (!isMounted.current) return;
29 |
30 | if (isRendering.current) {
31 | setTimeout(() => {
32 | if (isMounted.current) update();
33 | }, 0);
34 | } else {
35 | update();
36 | }
37 | }, [update, isRendering, isMounted]);
38 | };
39 |
40 | export const useIsMounted = () => {
41 | const isMounted = useRef(true);
42 |
43 | useIsomorphicLayoutEffect(() => {
44 | isMounted.current = true;
45 | return () => {
46 | isMounted.current = false;
47 | };
48 | }, []);
49 |
50 | return isMounted;
51 | };
52 |
53 | const InitSymbol: any = Symbol();
54 |
55 | export const useLazyRef = (initialValFunc: () => T) => {
56 | const ref: MutableRefObject = useRef(InitSymbol);
57 | if (ref.current === InitSymbol) {
58 | ref.current = initialValFunc();
59 | }
60 | return ref;
61 | };
62 |
--------------------------------------------------------------------------------
/examples/react/src/components/meta.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link';
2 |
3 | import { Button, Stack, Text } from '@chakra-ui/react';
4 |
5 | import { useMetaState } from './client';
6 |
7 | const NavigationList = [
8 | '/',
9 | '/normalized',
10 | '/refetch',
11 | '/stringArray',
12 | '/ssr',
13 | '/polling',
14 | '/error',
15 | '/playground',
16 | '/pagination',
17 | '/pagination_infinite_scroll',
18 | '/cache',
19 | '/emptyArrays',
20 | '/subscriptions',
21 | '/preparedQuery',
22 | '/useQueryTest',
23 | '/prepass',
24 | '/uploadFile',
25 | '/transactionQuery1',
26 | '/transactionQuery2',
27 | ];
28 |
29 | export const MetaClient = () => {
30 | const { isFetching, errors } = useMetaState({
31 | onStartFetching() {},
32 | onDoneFetching() {},
33 | onError() {},
34 | });
35 |
36 | return (
37 |
46 |
47 | {isFetching ? 'Fetching...' : 'Done'}
48 |
49 | {errors && (
50 | {JSON.stringify(errors, null, 2)}
51 | )}
52 |
53 |
54 | {NavigationList.map((href, key) => {
55 | return (
56 |
57 |
60 |
61 | );
62 | })}
63 |
64 |
65 | );
66 | };
67 |
--------------------------------------------------------------------------------
/examples/react/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import type { AppProps } from 'next/app';
2 | import { Suspense } from 'react';
3 |
4 | import { ChakraProvider, Stack } from '@chakra-ui/react';
5 |
6 | import { MetaClient } from '../components/meta';
7 | import { NoSSR } from '../components/NoSSR';
8 | import SSRPage from './ssr';
9 |
10 | function MyApp({ Component, pageProps }: AppProps) {
11 | const commonComponents = (
12 |
13 |
14 |
15 |
16 | );
17 | if (Component === SSRPage) {
18 | return {commonComponents};
19 | }
20 | return (
21 |
22 |
23 | {commonComponents}
24 |
25 |
26 | );
27 | }
28 |
29 | export default MyApp;
30 |
--------------------------------------------------------------------------------
/examples/react/src/pages/emptyArrays.tsx:
--------------------------------------------------------------------------------
1 | import { ListItem, OrderedList, Stack } from '@chakra-ui/react';
2 | import { graphql } from '../components/client';
3 | import { query } from '../graphql/gqless';
4 |
5 | export default graphql(
6 | function EmptyArrays() {
7 | query.time;
8 | return (
9 |
10 |
11 | {query.emptyScalarArray.map((value = 0) => {
12 | return {value};
13 | })}
14 |
15 |
16 | {query.emptyHumanArray.map(({ id = 0, name }) => {
17 | return (
18 |
19 | ID: {id}
20 |
21 | Name: {name}
22 |
23 | );
24 | })}
25 |
26 |
27 | );
28 | },
29 | {
30 | suspense: {
31 | fallback: 'Loadingasd...',
32 | },
33 | }
34 | );
35 |
--------------------------------------------------------------------------------
/examples/react/src/pages/error.tsx:
--------------------------------------------------------------------------------
1 | import { useQuery, useTransactionQuery } from '../components/client';
2 | import { NoSSR } from '../components/NoSSR';
3 | import { Suspense, useState } from 'react';
4 | import { serializeError } from 'serialize-error';
5 | import { GQlessError } from 'gqless';
6 | import { Stack, Text } from '@chakra-ui/react';
7 |
8 | const ExpectedErrorComponent = () => {
9 | const { data, error } = useTransactionQuery(
10 | (query) => {
11 | return {
12 | a: query.thirdTry,
13 | b: query.__typename,
14 | };
15 | },
16 | {
17 | suspense: true,
18 | retry: true,
19 | fetchPolicy: 'no-cache',
20 | }
21 | );
22 |
23 | const [inlineError, setError] = useState();
24 |
25 | const query = useQuery({
26 | suspense: true,
27 | onError: setError,
28 | });
29 |
30 | return (
31 | <>
32 |
33 | {HOOK DATA:{JSON.stringify(data)}}
34 | {error && (
35 | HOOK ERROR: {JSON.stringify(serializeError(error))}
36 | )}
37 |
38 |
39 | INLINE DATA:{' '}
40 | {JSON.stringify({
41 | a: query.expectedError,
42 | b: query.__typename,
43 | })}
44 | {inlineError && (
45 |
46 | INLINE ERROR: {JSON.stringify(serializeError(inlineError))}
47 |
48 | )}
49 |
50 | >
51 | );
52 | };
53 |
54 | export default function ErrorPage() {
55 | return (
56 |
57 | Loading Here...}>
58 |
59 |
60 |
61 | );
62 | }
63 |
--------------------------------------------------------------------------------
/examples/react/src/pages/normalized.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Stack, Text } from '@chakra-ui/react';
2 | import { selectFields } from 'gqless';
3 | import { useMutation, useQuery } from '../components/client';
4 |
5 | export default function NormalizedPage() {
6 | const query = useQuery({
7 | suspense: true,
8 | staleWhileRevalidate: true,
9 | });
10 |
11 | const [renameDog] = useMutation((mutation) => {
12 | const dog = mutation.renameDog({
13 | id: '1',
14 | name: 'z',
15 | });
16 |
17 | dog?.id;
18 | dog?.name;
19 | });
20 |
21 | const [renameHuman] = useMutation((mutation) => {
22 | const human = mutation.renameHuman({
23 | id: '1',
24 | name: 'x',
25 | });
26 |
27 | human?.id;
28 | human?.name;
29 | });
30 |
31 | return (
32 |
33 | {query.time}
34 |
35 |
36 |
37 | {JSON.stringify(selectFields(query.humans, '*', 2), null, 2)}
38 |
39 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/examples/react/src/pages/preparedQuery.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Stack, Text } from '@chakra-ui/react';
2 | import { useState } from 'react';
3 | import { prepareQuery } from '../components/client';
4 |
5 | const { usePrepared, preload, refetch } = prepareQuery((query) => {
6 | return query.time!;
7 | });
8 |
9 | function TimeComponent() {
10 | const { data, isRefetching } = usePrepared({
11 | suspense: true,
12 | });
13 |
14 | return (
15 |
16 | Time: {data}
17 |
20 |
21 | );
22 | }
23 |
24 | export default function PreparedQueryPage() {
25 | const [showTimeComponent, setShowTimeComponent] = useState(false);
26 | const [isLoading, setIsLoading] = useState(false);
27 |
28 | return (
29 |
30 |
43 | {showTimeComponent && }
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/examples/react/src/pages/prepass.tsx:
--------------------------------------------------------------------------------
1 | import { ListItem, OrderedList, Stack, Text } from '@chakra-ui/react';
2 | import { useQuery } from '../components/client';
3 |
4 | let renderCount = 0;
5 | export default function PrepassPage() {
6 | const query = useQuery({
7 | suspense: false,
8 | prepare({ prepass, query }) {
9 | prepass(query, 'dogs.name');
10 | },
11 | });
12 |
13 | renderCount++;
14 |
15 | if (query.$state.isLoading) {
16 | console.log('IS LOADING');
17 | } else {
18 | console.log("IT'S NOT LOADING");
19 | }
20 |
21 | if (query.$state.isLoading) return Loading...;
22 |
23 | return (
24 |
25 | Render Count: {renderCount}
26 | {query.dogs.map((dog) => {
27 | return (
28 |
29 |
30 |
31 | ID: {dog.id}
32 |
33 |
34 | Name: {dog.name}
35 |
36 |
37 |
38 |
39 | );
40 | })}
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/examples/react/src/pages/refetch.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Stack, Text } from '@chakra-ui/react';
2 | import { useQuery, useRefetch } from '../components/client';
3 |
4 | export default function RefetchPage() {
5 | const query = useQuery();
6 |
7 | const refetchTime = useRefetch();
8 |
9 | const time = query.time;
10 |
11 | refetchTime.stopWatching();
12 |
13 | const refetchQueryTypename = useRefetch();
14 |
15 | const queryTypename = query.__typename;
16 |
17 | return (
18 |
19 | {time}
20 |
23 |
24 | {queryTypename}
25 |
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/examples/react/src/pages/ssr.tsx:
--------------------------------------------------------------------------------
1 | import { RouterContext } from 'next/dist/next-server/lib/router-context';
2 |
3 | import { PropsWithServerCache } from '@gqless/react';
4 |
5 | import {
6 | graphql,
7 | prepareReactRender,
8 | useHydrateCache,
9 | } from '../components/client';
10 | import { default as RefetchPage } from './refetch';
11 |
12 | import type { GetServerSideProps } from 'next';
13 |
14 | export const getServerSideProps: GetServerSideProps = async ({}) => {
15 | const { cacheSnapshot } = await prepareReactRender(
16 |
17 |
18 |
19 | );
20 |
21 | return {
22 | props: {
23 | cacheSnapshot,
24 | },
25 | };
26 | };
27 |
28 | export default graphql(
29 | function SSRPage({ cacheSnapshot }: PropsWithServerCache) {
30 | useHydrateCache({
31 | cacheSnapshot,
32 | });
33 |
34 | return ;
35 | },
36 | {
37 | suspense: {
38 | fallback: 'Loading SSR...',
39 | },
40 | staleWhileRevalidate: false,
41 | }
42 | );
43 |
--------------------------------------------------------------------------------
/examples/react/src/pages/stringArray.tsx:
--------------------------------------------------------------------------------
1 | import { Stack, Text } from '@chakra-ui/react';
2 | import { useQuery, buildSelection } from '../components/client';
3 | import { query } from '../graphql/gqless';
4 |
5 | query.dogs;
6 |
7 | typeof window !== 'undefined' &&
8 | console.log(
9 | 'selection',
10 | buildSelection('query', 'dogs', 'owner', 'dogs', 'owner', 'name')
11 | );
12 |
13 | export default function TestingStringArray() {
14 | const query = useQuery({
15 | suspense: false,
16 | });
17 |
18 | return (
19 |
20 | {query.stringList.map((v, index) => (
21 | {v}
22 | ))}
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/react/src/pages/subscriptions.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Heading, Stack, Text } from '@chakra-ui/react';
2 | import { useMutation, useSubscription } from '../components/client';
3 |
4 | let n = 0;
5 |
6 | function SendNotification() {
7 | const [sendNotification] = useMutation((mutation, message: string) => {
8 | return mutation.sendNotification({
9 | message,
10 | });
11 | });
12 |
13 | return (
14 | <>
15 |
25 |
34 | >
35 | );
36 | }
37 |
38 | export default function SubscriptionsPage() {
39 | const subscription = useSubscription();
40 |
41 | return (
42 |
43 |
44 | Data
45 | {subscription.newNotification}
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/examples/react/src/pages/transactionQuery1.tsx:
--------------------------------------------------------------------------------
1 | import { Button, Stack, Text } from '@chakra-ui/react';
2 | import { useTransactionQuery } from '../components/client';
3 | import { mutate } from '../graphql/gqless';
4 |
5 | let nRenders = 0;
6 | export default function TransactionQuery1() {
7 | const { data } = useTransactionQuery(
8 | (query) => {
9 | return query.human1.name;
10 | },
11 | {
12 | suspense: true,
13 | fetchPolicy: 'cache-first',
14 | }
15 | );
16 |
17 | return (
18 |
19 |
20 | {++nRenders}
21 |
22 | query1 {JSON.stringify(data)}
23 |
24 |
25 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/examples/react/src/pages/transactionQuery2.tsx:
--------------------------------------------------------------------------------
1 | import { useTransactionQuery } from '../components/client';
2 |
3 | let nRenders = 0;
4 |
5 | export default function TransactionQuery2() {
6 | const { data } = useTransactionQuery(
7 | (query) => {
8 | return query.human1.name;
9 | },
10 | {
11 | suspense: false,
12 | }
13 | );
14 |
15 | return (
16 |
17 | {++nRenders}
18 | query2 {JSON.stringify(data)}
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/examples/react/src/pages/uploadFile.tsx:
--------------------------------------------------------------------------------
1 | import { Input, Stack, Text } from '@chakra-ui/react';
2 | import { ChangeEvent, useState } from 'react';
3 | import { useMutation } from '../components/client';
4 |
5 | export default function UploadFile() {
6 | const [imageb64, setImageb64] = useState('');
7 | const [uploadFile, { isLoading }] = useMutation(
8 | (mutation, file: File) => {
9 | return mutation.uploadFile({
10 | file,
11 | })!;
12 | },
13 | {
14 | onCompleted(data) {
15 | setImageb64(data);
16 | },
17 | noCache: true,
18 | nonSerializableVariables: true,
19 | }
20 | );
21 | return (
22 |
23 | ) => {
33 | files && validity.valid && uploadFile({ args: files[0] });
34 | }}
35 | />
36 | {imageb64 ?
: null}
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/examples/react/src/pages/useQueryTest.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | import { useQuery } from '../components/client';
3 |
4 | let nRender = 0;
5 | let nCommitedRender = 0;
6 |
7 | export default function UseQueryPage() {
8 | const query = useQuery({
9 | suspense: true,
10 | });
11 |
12 | useEffect(() => {
13 | console.log('Commited render:', ++nCommitedRender);
14 | });
15 |
16 | if (query.$state.isLoading) {
17 | console.log('IS LOADING!');
18 | return (
19 |
20 | Loading...
Render: {++nRender}
21 |
22 | );
23 | }
24 |
25 | return (
26 |
27 | {query.time}
28 |
29 | Render: {++nRender}
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/examples/react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
3 | "include": ["src", "api", "types"],
4 | "compilerOptions": {
5 | "target": "es2018",
6 | "module": "esnext",
7 | "lib": ["dom", "esnext"],
8 | "importHelpers": true,
9 | // output .d.ts declaration files for consumers
10 | "declaration": true,
11 | // output .js.map sourcemap files for consumers
12 | "sourceMap": true,
13 | // match output dir to input dir. e.g. dist/index instead of dist/src/index
14 | "rootDir": "../",
15 | // stricter type-checking for stronger correctness. Recommended by TS
16 | "strict": true,
17 | // linter checks for common issues
18 | "noImplicitReturns": true,
19 | "noFallthroughCasesInSwitch": true,
20 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
21 | "isolatedModules": true,
22 | "noUnusedLocals": false,
23 | "noUnusedParameters": false,
24 | // use Node's module resolution algorithm, instead of the legacy TS one
25 | "moduleResolution": "node",
26 | // transpile JSX to React.createElement
27 | "jsx": "preserve",
28 | // interop between ESM and CJS modules. Recommended by TS
29 | "esModuleInterop": true,
30 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
31 | "skipLibCheck": true,
32 | // error out if import and file system have a casing mismatch. Recommended by TS
33 | "forceConsistentCasingInFileNames": true,
34 | // "noEmit": true,
35 | "preserveWatchOutput": true,
36 | "outDir": "./dist",
37 | "incremental": true,
38 | "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo",
39 | "allowJs": true,
40 | "noEmit": true,
41 | "resolveJsonModule": true
42 | },
43 | "exclude": ["node_modules"]
44 | }
45 |
--------------------------------------------------------------------------------
/internal/build-utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "build-utils",
3 | "version": "1.0.0",
4 | "private": true,
5 | "type": "module",
6 | "bin": {
7 | "build": "./bin/build.js",
8 | "gh-release": "./bin/github-release.js",
9 | "watch": "./bin/watch.js"
10 | },
11 | "dependencies": {
12 | "@rollup/plugin-replace": "^2.4.2",
13 | "@rollup/plugin-typescript": "^8.2.1",
14 | "commander": "^7.2.0",
15 | "cross-spawn": "^7.0.3",
16 | "execa": "^5.0.0",
17 | "fs-extra": "^9.1.0",
18 | "github-release-cli": "^2.0.0",
19 | "rollup": "^2.45.2",
20 | "rollup-plugin-cleanup": "^3.2.1",
21 | "rollup-plugin-terser": "^7.0.2",
22 | "string-argv": "^0.3.1",
23 | "tree-kill": "^1.2.2"
24 | },
25 | "devDependencies": {
26 | "@types/cross-spawn": "^6.0.2",
27 | "@types/fs-extra": "^9.0.11"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/internal/build-utils/src/buildWriteTypes.js:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path';
2 | import fsExtra from 'fs-extra';
3 | import { existsSync } from 'fs';
4 |
5 | const { outputFile, remove } = fsExtra;
6 |
7 | export async function buildWriteTypes(
8 | /**
9 | * @type {import("rollup").RollupBuild}
10 | */
11 | bundle,
12 | /**
13 | * @type {() => void}
14 | */
15 | afterFileWrite = () => {},
16 | /**
17 | * @type {string}
18 | */
19 | cwd = '.'
20 | ) {
21 | const dir = resolve(cwd, 'dist');
22 | const { output } = await bundle.generate({
23 | dir,
24 | sourcemap: true,
25 | });
26 |
27 | const writingPromise = Promise.all(
28 | output.map((chunkOrAsset) => {
29 | if (chunkOrAsset.type === 'asset') {
30 | const destination = resolve(dir, chunkOrAsset.fileName);
31 |
32 | return outputFile(destination, chunkOrAsset.source).then(
33 | afterFileWrite
34 | );
35 | }
36 | })
37 | );
38 |
39 | const duplicatedTypesDist = resolve(dir, './dist');
40 |
41 | if (existsSync(duplicatedTypesDist)) {
42 | await Promise.all([writingPromise, remove(duplicatedTypesDist)]);
43 | } else {
44 | await writingPromise;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/internal/build-utils/src/index.js:
--------------------------------------------------------------------------------
1 | export * from './buildWriteTypes.js';
2 | export * from './config.js';
3 | export * from './writeIndex.js';
4 |
--------------------------------------------------------------------------------
/internal/build-utils/src/writeIndex.js:
--------------------------------------------------------------------------------
1 | import { promises } from 'fs';
2 | import { resolve } from 'path';
3 |
4 | const { writeFile } = promises;
5 |
6 | export async function writeIndex(
7 | /**
8 | * @type {string}
9 | */
10 | moduleName,
11 | /**
12 | * @type {string}
13 | */
14 | cwd = '.'
15 | ) {
16 | await writeFile(
17 | resolve(cwd, 'dist/index.js'),
18 | `'use strict'
19 | if (process.env.NODE_ENV === "production") {
20 | module.exports = require('./${moduleName}.cjs.production.min.js')
21 | } else {
22 | module.exports = require('./${moduleName}.cjs.development.js')
23 | }
24 | `
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/internal/build-utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "checkJs": true,
4 | "allowJs": true,
5 | "noEmit": true,
6 | "esModuleInterop": true
7 | },
8 | "include": ["src/**/*.js", "bin/**/*.js"],
9 | "exclude": ["node_modules"]
10 | }
11 |
--------------------------------------------------------------------------------
/internal/gqless.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/gqless.sketch
--------------------------------------------------------------------------------
/internal/test-utils/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | dist
5 |
--------------------------------------------------------------------------------
/internal/test-utils/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright © `2021` `GQless`
4 |
5 | Permission is hereby granted, free of charge, to any person
6 | obtaining a copy of this software and associated documentation
7 | files (the “Software”), to deal in the Software without
8 | restriction, including without limitation the rights to use,
9 | copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 | OTHER DEALINGS IN THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/internal/test-utils/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/test-utils/README.md
--------------------------------------------------------------------------------
/internal/test-utils/bin/jest-test.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const crossEnv = require('cross-env');
4 |
5 | crossEnv('jest'.split(' '));
6 |
--------------------------------------------------------------------------------
/internal/test-utils/jest.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import("@jest/types").Config.InitialOptions}
3 | */
4 | const defaultConfig = {
5 | globals: {
6 | 'ts-jest': {},
7 | },
8 | transform: {
9 | '.(ts|tsx)$': require.resolve('ts-jest/dist'),
10 | },
11 | transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
12 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
13 | testEnvironment: 'node',
14 | testMatch: ['**/test/**/*.test.ts', '**/test/**/*.test.tsx'],
15 | testURL: 'http://localhost',
16 | testPathIgnorePatterns: ['/node_modules/', '/test/generated'],
17 | collectCoverage: true,
18 | collectCoverageFrom: ['./src/**/*.ts', './src/**/*.tsx', '!**/*.d.ts'],
19 | testTimeout: 10000,
20 | watchPlugins: [
21 | require.resolve('jest-watch-typeahead/filename'),
22 | require.resolve('jest-watch-typeahead/testname'),
23 | ],
24 | restoreMocks: true,
25 | };
26 |
27 | exports.default = defaultConfig;
28 |
29 | exports.getConfig = function getConfig(
30 | /**
31 | * @type {import("@jest/types").Config.InitialOptions}
32 | */
33 | config = {}
34 | ) {
35 | /**
36 | * @type {import("@jest/types").Config.InitialOptions}
37 | */
38 | const newConfig = {
39 | ...defaultConfig,
40 | ...config,
41 | };
42 |
43 | return newConfig;
44 | };
45 |
--------------------------------------------------------------------------------
/internal/test-utils/jest.config.ts:
--------------------------------------------------------------------------------
1 | export default require('./jest.config.js').default;
2 |
--------------------------------------------------------------------------------
/internal/test-utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-utils",
3 | "version": "0.1.0",
4 | "private": true,
5 | "license": "MIT",
6 | "author": "GQless ",
7 | "main": "dist/index.js",
8 | "module": "dist/index.mjs",
9 | "typings": "src/index.d.ts",
10 | "bin": {
11 | "jest-test": "bin/jest-test.js"
12 | },
13 | "scripts": {
14 | "analyze": "size-limit --why",
15 | "build": "rimraf dist && tsup src/index.ts --format esm,cjs",
16 | "prepare": "pnpm build",
17 | "size": "size-limit",
18 | "start": "nodemon --exec \"concurrently pnpm:build tsc\" -w src/index.ts",
19 | "test": "jest --config jest.config.ts"
20 | },
21 | "dependencies": {
22 | "@rollup/plugin-babel": "^5.3.0",
23 | "@types/jest": "^26.0.22",
24 | "cross-env": "^7.0.3",
25 | "esbuild": "^0.11.12",
26 | "fastify": "^3.14.2",
27 | "get-port": "^5.1.1",
28 | "graphql": "^15.5.0",
29 | "jest": "^26.6.3",
30 | "jest-watch-typeahead": "^0.6.2",
31 | "mercurius": "^7.4.0",
32 | "mercurius-codegen": "^1.4.3",
33 | "mercurius-integration-testing": "^3.1.3",
34 | "nodemon": "^2.0.7",
35 | "prettier": "^2.2.1",
36 | "randomstring": "^1.1.5",
37 | "ts-jest": "^26.5.5",
38 | "wait-for-expect": "^3.0.2"
39 | },
40 | "devDependencies": {
41 | "@jest/types": "^26.6.2",
42 | "@size-limit/preset-small-lib": "^4.10.2",
43 | "@types/randomstring": "^1.1.6",
44 | "concurrently": "^6.0.2",
45 | "rimraf": "^3.0.2",
46 | "size-limit": "^4.10.2",
47 | "tslib": "^2.2.0",
48 | "tsup": "^4.9.1",
49 | "typescript": "^4.2.4"
50 | },
51 | "engines": {
52 | "node": ">=10"
53 | },
54 | "size-limit": [
55 | {
56 | "path": "dist/test-utils.cjs.production.min.js",
57 | "limit": "10 KB"
58 | },
59 | {
60 | "path": "dist/test-utils.esm.js",
61 | "limit": "10 KB"
62 | }
63 | ]
64 | }
65 |
--------------------------------------------------------------------------------
/internal/test-utils/src/app.d.ts:
--------------------------------------------------------------------------------
1 | import { FastifyInstance } from 'fastify';
2 | import { MercuriusOptions } from 'mercurius';
3 | import { createMercuriusTestClient } from 'mercurius-integration-testing';
4 | export declare function createTestApp(
5 | options: MercuriusOptions,
6 | {
7 | codegenPath,
8 | }?: {
9 | codegenPath?: string;
10 | }
11 | ): {
12 | server: FastifyInstance;
13 | client: ReturnType;
14 | isReady: Promise;
15 | };
16 | export * as mercurius from 'mercurius';
17 | export * as fastify from 'fastify';
18 | export { gql } from 'mercurius-codegen';
19 |
--------------------------------------------------------------------------------
/internal/test-utils/src/app.ts:
--------------------------------------------------------------------------------
1 | import fastify, { FastifyInstance } from 'fastify';
2 | import mercurius, { MercuriusOptions } from 'mercurius';
3 | import { createMercuriusTestClient } from 'mercurius-integration-testing';
4 |
5 | export function createTestApp(
6 | options: MercuriusOptions,
7 | {
8 | codegenPath,
9 | }: {
10 | codegenPath?: string;
11 | } = {}
12 | ): {
13 | server: FastifyInstance;
14 | client: ReturnType;
15 | isReady: Promise;
16 | } {
17 | const server = fastify();
18 |
19 | server.register(mercurius, options);
20 |
21 | let isReady = codegenPath
22 | ? new Promise((resolve, reject) => {
23 | import('mercurius-codegen')
24 | .then(({ default: mercuriusCodegen }) => {
25 | mercuriusCodegen(server, {
26 | targetPath: codegenPath,
27 | silent: true,
28 | disable: false,
29 | })
30 | .then(resolve)
31 | .catch(reject);
32 | })
33 | .catch(reject);
34 | })
35 | : ((server.ready() as unknown) as Promise);
36 |
37 | const client = createMercuriusTestClient(server, {
38 | url: options.path,
39 | });
40 |
41 | return { server, client, isReady };
42 | }
43 |
44 | export * as mercurius from 'mercurius';
45 | export * as fastify from 'fastify';
46 |
47 | export { gql } from 'mercurius-codegen';
48 |
--------------------------------------------------------------------------------
/internal/test-utils/src/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as randomstring from 'randomstring';
2 | export { default as waitForExpect } from 'wait-for-expect';
3 | export * as mercurius from 'mercurius';
4 | export * as fastify from 'fastify';
5 | export declare function assertIsDefined(
6 | value: T,
7 | message?: string
8 | ): asserts value is NonNullable;
9 | export { randomstring };
10 | export * from './app';
11 |
--------------------------------------------------------------------------------
/internal/test-utils/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as randomstring from 'randomstring';
2 |
3 | export { default as waitForExpect } from 'wait-for-expect';
4 |
5 | export * as mercurius from 'mercurius';
6 | export * as fastify from 'fastify';
7 |
8 | export function assertIsDefined(
9 | value: T,
10 | message?: string
11 | ): asserts value is NonNullable {
12 | if (value == null) {
13 | const error = new Error(message || 'value is nullable');
14 |
15 | Error.captureStackTrace(error, assertIsDefined);
16 | throw error;
17 | }
18 | }
19 |
20 | export { randomstring };
21 |
22 | export * from './app';
23 |
--------------------------------------------------------------------------------
/internal/test-utils/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "strictNullChecks": true,
5 | "rootDir": "../"
6 | },
7 | "include": ["**/*.ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/internal/test-utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
3 | "include": ["src"],
4 | "compilerOptions": {
5 | "incremental": false,
6 | "module": "esnext",
7 | "lib": ["dom", "esnext"],
8 | "importHelpers": true,
9 | // output .d.ts declaration files for consumers
10 | "declaration": true,
11 | // output .js.map sourcemap files for consumers
12 | "sourceMap": true,
13 | // match output dir to input dir. e.g. dist/index instead of dist/src/index
14 | "rootDir": "./src",
15 | // stricter type-checking for stronger correctness. Recommended by TS
16 | "strict": true,
17 | // linter checks for common issues
18 | "noImplicitReturns": true,
19 | "noFallthroughCasesInSwitch": true,
20 | "isolatedModules": true,
21 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
22 | "noUnusedLocals": true,
23 | "noUnusedParameters": true,
24 | // use Node's module resolution algorithm, instead of the legacy TS one
25 | "moduleResolution": "node",
26 | // transpile JSX to React.createElement
27 | "jsx": "react",
28 | // interop between ESM and CJS modules. Recommended by TS
29 | "esModuleInterop": true,
30 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
31 | "skipLibCheck": true,
32 | // error out if import and file system have a casing mismatch. Recommended by TS
33 | "forceConsistentCasingInFileNames": true,
34 | "preserveWatchOutput": true,
35 | "emitDeclarationOnly": true
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/internal/test-utils/types/app.d.ts:
--------------------------------------------------------------------------------
1 | import { FastifyInstance } from 'fastify';
2 | import { MercuriusOptions } from 'mercurius';
3 | import { createMercuriusTestClient } from 'mercurius-integration-testing';
4 | export declare function createTestApp(
5 | options: MercuriusOptions,
6 | {
7 | codegenPath,
8 | }?: {
9 | codegenPath?: string;
10 | }
11 | ): {
12 | server: FastifyInstance;
13 | client: ReturnType;
14 | isReady: Promise;
15 | };
16 | export * as mercurius from 'mercurius';
17 | export * as fastify from 'fastify';
18 | export { gql } from 'mercurius-codegen';
19 |
--------------------------------------------------------------------------------
/internal/test-utils/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as randomstring from 'randomstring';
2 | export { default as waitForExpect } from 'wait-for-expect';
3 | export * as mercurius from 'mercurius';
4 | export * as fastify from 'fastify';
5 | export declare function assertIsDefined(
6 | value: T,
7 | message?: string
8 | ): asserts value is NonNullable;
9 | export { randomstring };
10 | export * from './app';
11 |
--------------------------------------------------------------------------------
/internal/website/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "semi": true,
4 | "singleQuote": true,
5 | "trailingComma": "es5"
6 | }
7 |
--------------------------------------------------------------------------------
/internal/website/fix-typedoc-plugin.js:
--------------------------------------------------------------------------------
1 | module.exports = function (_context, _options) {
2 | return {
3 | name: 'Fix Typedoc',
4 | async contentLoaded() {
5 | require('./fix-typedoc');
6 | return null;
7 | },
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/internal/website/fix-typedoc.js:
--------------------------------------------------------------------------------
1 | const {
2 | promises: { readFile, writeFile },
3 | } = require('fs');
4 | const { spawnSync } = require('child_process');
5 | const globby = require('globby');
6 |
7 | spawnSync('node', ['./node_modules/pretty-quick/bin/pretty-quick.js'], {
8 | stdio: 'ignore',
9 | });
10 |
11 | const encoding = {
12 | encoding: 'utf-8',
13 | };
14 |
15 | async function main() {
16 | const docFiles = await globby([
17 | '../../docs/client/api/**/*.md',
18 | '../../docs/react/api/**/*.md',
19 | ]);
20 |
21 | await Promise.all(
22 | docFiles.map(async (docPath) => {
23 | const docContent = await readFile(docPath, encoding);
24 |
25 | const docContentSplit = docContent.split('\n');
26 |
27 | // Remove duplicated line references
28 | const filteredDocContent = docContentSplit
29 | .filter((line, index) => {
30 | const isLineReference = !!line.match(/Defined in\: \[(.*?)\)/);
31 |
32 | if (
33 | isLineReference &&
34 | docContentSplit.indexOf(line, Math.max(0, index - 2)) !== index
35 | ) {
36 | return false;
37 | }
38 |
39 | return true;
40 | })
41 | .join('\n');
42 |
43 | await writeFile(
44 | docPath,
45 | filteredDocContent.replace(/\/blob\/(.*?)\//g, '/blob/master/'),
46 | encoding
47 | );
48 | })
49 | );
50 |
51 | spawnSync('node', ['./node_modules/pretty-quick/bin/pretty-quick.js'], {
52 | stdio: 'ignore',
53 | });
54 | }
55 |
56 | main().catch((err) => {
57 | console.error(err);
58 | process.exit(1);
59 | });
60 |
--------------------------------------------------------------------------------
/internal/website/sidebars.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | docs: [
3 | {
4 | type: 'category',
5 | label: 'Introduction',
6 | collapsed: false,
7 | items: [
8 | 'intro',
9 | 'intro/how-it-works',
10 | // 'introduction/features',
11 | 'intro/new-in-2',
12 | 'contributing',
13 | ],
14 | },
15 | { type: 'doc', id: 'getting-started' },
16 | {
17 | type: 'category',
18 | label: 'Usage with React',
19 | collapsed: false,
20 | items: [
21 | 'react/fetching-data',
22 | 'react/mutations',
23 | 'react/subscriptions',
24 | 'react/config',
25 | 'react/suspense',
26 | 'react/ssr',
27 | 'react/meta',
28 | {
29 | type: 'category',
30 | label: 'API Reference',
31 | items: require('./sidebars/react.js'),
32 | },
33 | ],
34 | },
35 | {
36 | type: 'category',
37 | label: 'Core Client',
38 | collapsed: false,
39 | items: [
40 | 'client/fetching-data',
41 | 'client/mutations',
42 | 'client/subscriptions',
43 | 'client/config',
44 | 'client/persistence',
45 | 'client/helper-functions',
46 | 'client/graphql-upload',
47 | {
48 | type: 'category',
49 | label: 'API Reference',
50 | items: require('./sidebars/client.js'),
51 | },
52 | ],
53 | },
54 | {
55 | type: 'category',
56 | label: 'CLI',
57 | collapsed: false,
58 | items: [
59 | 'cli/config',
60 | 'cli/codegen',
61 | 'cli/javascript',
62 | 'cli/programmatic',
63 | ],
64 | },
65 | {
66 | type: 'category',
67 | label: 'Development Tools',
68 | collapsed: false,
69 | items: ['development/logger'],
70 | },
71 | ],
72 | };
73 |
--------------------------------------------------------------------------------
/internal/website/src/components/Example.tsx:
--------------------------------------------------------------------------------
1 | import { AnimationProps, motion } from 'framer-motion';
2 | import * as React from 'react';
3 |
4 | import styled from '@emotion/styled';
5 |
6 | const easeInOutCubic = [0.645, 0.045, 0.355, 1];
7 |
8 | const StyledExample = styled(motion.div)`
9 | overflow: hidden;
10 | display: flex;
11 | flex-wrap: wrap;
12 | justify-content: center;
13 | flex-direction: column;
14 |
15 | .prism-code {
16 | padding: 0;
17 | background: none !important;
18 | }
19 | `;
20 |
21 | const Title = styled(motion.h3)`
22 | font-weight: 500;
23 | margin-bottom: 0.8rem;
24 | font-size: 1.2rem;
25 | color: #e976c3;
26 | margin-bottom: 0.8rem;
27 | `;
28 |
29 | const Content = styled(motion.div)``;
30 |
31 | export const Example = ({
32 | title,
33 | children,
34 | animate = 'visible',
35 | initial = 'hidden',
36 | }: {
37 | title: string;
38 | children: React.ReactNode;
39 | animate: AnimationProps['animate'];
40 | initial?: 'hidden' | 'visible';
41 | }) => (
42 |
43 |
57 | {title}
58 |
59 |
60 |
75 | {children}
76 |
77 |
78 | );
79 |
--------------------------------------------------------------------------------
/internal/website/src/components/Examples/NavLink.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import {
4 | HStack,
5 | Icon,
6 | Link,
7 | LinkProps,
8 | Text,
9 | useColorModeValue as mode,
10 | } from '@chakra-ui/react';
11 | import DocusaurusLink from '@docusaurus/Link';
12 | import { useLocation } from '@docusaurus/router';
13 |
14 | interface NavLinkProps extends LinkProps {
15 | label: string;
16 | icon?: any;
17 | }
18 |
19 | export const NavLink = (props: NavLinkProps) => {
20 | const { icon, label, href, ...rest } = props;
21 | const { pathname } = useLocation();
22 |
23 | const isActive = pathname === href;
24 |
25 | return (
26 |
50 |
51 |
52 |
53 | {label}
54 |
55 |
56 |
57 | );
58 | };
59 |
--------------------------------------------------------------------------------
/internal/website/src/components/Examples/Sidebar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FaAngleRight, FaReact } from 'react-icons/fa';
3 |
4 | import { Flex, FlexProps, Spacer, Stack } from '@chakra-ui/react';
5 |
6 | import { NavLink } from './NavLink';
7 |
8 | export const Sidebar = (props: FlexProps) => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
20 |
25 |
26 |
27 |
28 |
29 |
30 | );
31 | };
32 |
--------------------------------------------------------------------------------
/internal/website/src/components/Overflow.tsx:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled';
2 |
3 | export const Overflow = styled.div`
4 | overflow: hidden;
5 | `;
6 |
--------------------------------------------------------------------------------
/internal/website/src/components/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './Feature';
2 | export * from './Arrow';
3 | export * from './Example';
4 | export * from './Overflow';
5 |
--------------------------------------------------------------------------------
/internal/website/src/pages/examples/suspense/query.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Heading, Text } from '@chakra-ui/react';
4 | import Link from '@docusaurus/Link';
5 |
6 | import { ExamplesPage } from '../../../components/Examples/App';
7 | import { CodeSandboxEmbed } from '../../../components/Examples/Embed';
8 |
9 | export default function Page() {
10 | return (
11 |
12 | GraphQL Queries in React Suspense
13 |
14 | In this example you can see some usage examples of{' '}
15 | useQuery and{' '}
16 | graphql HOC.
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/internal/website/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/favicon.ico
--------------------------------------------------------------------------------
/internal/website/static/fonts.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: Colfax;
3 | font-weight: 300;
4 | src: url('/fonts/ColfaxWebLight.woff2') format('woff2');
5 | }
6 |
7 | @font-face {
8 | font-family: 'Operator Mono';
9 | src: url('/fonts/OperatorMono.otf');
10 | }
11 |
12 | @font-face {
13 | font-family: Colfax;
14 | font-weight: 400;
15 | src: url('/fonts/ColfaxWebRegular.woff2') format('woff2');
16 | }
17 | @font-face {
18 | font-family: Colfax;
19 | font-weight: 500;
20 | src: url('/fonts/ColfaxWebMedium.woff2') format('woff2');
21 | }
22 | @font-face {
23 | font-family: Colfax;
24 | font-weight: 600;
25 | src: url('/fonts/ColfaxWebBold.woff2') format('woff2');
26 | }
27 |
--------------------------------------------------------------------------------
/internal/website/static/fonts/ColfaxWebBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/fonts/ColfaxWebBold.woff2
--------------------------------------------------------------------------------
/internal/website/static/fonts/ColfaxWebLight.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/fonts/ColfaxWebLight.woff2
--------------------------------------------------------------------------------
/internal/website/static/fonts/ColfaxWebMedium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/fonts/ColfaxWebMedium.woff2
--------------------------------------------------------------------------------
/internal/website/static/fonts/ColfaxWebRegular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/fonts/ColfaxWebRegular.woff2
--------------------------------------------------------------------------------
/internal/website/static/fonts/OperatorMono.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/fonts/OperatorMono.otf
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-144x144.png
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-192x192.png
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-36x36.png
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-48x48.png
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-72x72.png
--------------------------------------------------------------------------------
/internal/website/static/icon/android-icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/android-icon-96x96.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-114x114.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-120x120.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-144x144.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-152x152.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-180x180.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-57x57.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-60x60.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-72x72.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-76x76.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon-precomposed.png
--------------------------------------------------------------------------------
/internal/website/static/icon/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/apple-icon.png
--------------------------------------------------------------------------------
/internal/website/static/icon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
--------------------------------------------------------------------------------
/internal/website/static/icon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/favicon-16x16.png
--------------------------------------------------------------------------------
/internal/website/static/icon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/favicon-32x32.png
--------------------------------------------------------------------------------
/internal/website/static/icon/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/favicon-96x96.png
--------------------------------------------------------------------------------
/internal/website/static/icon/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "App",
3 | "icons": [
4 | {
5 | "src": "/android-icon-36x36.png",
6 | "sizes": "36x36",
7 | "type": "image/png",
8 | "density": "0.75"
9 | },
10 | {
11 | "src": "/android-icon-48x48.png",
12 | "sizes": "48x48",
13 | "type": "image/png",
14 | "density": "1.0"
15 | },
16 | {
17 | "src": "/android-icon-72x72.png",
18 | "sizes": "72x72",
19 | "type": "image/png",
20 | "density": "1.5"
21 | },
22 | {
23 | "src": "/android-icon-96x96.png",
24 | "sizes": "96x96",
25 | "type": "image/png",
26 | "density": "2.0"
27 | },
28 | {
29 | "src": "/android-icon-144x144.png",
30 | "sizes": "144x144",
31 | "type": "image/png",
32 | "density": "3.0"
33 | },
34 | {
35 | "src": "/android-icon-192x192.png",
36 | "sizes": "192x192",
37 | "type": "image/png",
38 | "density": "4.0"
39 | }
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/internal/website/static/icon/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/ms-icon-144x144.png
--------------------------------------------------------------------------------
/internal/website/static/icon/ms-icon-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/ms-icon-150x150.png
--------------------------------------------------------------------------------
/internal/website/static/icon/ms-icon-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/ms-icon-310x310.png
--------------------------------------------------------------------------------
/internal/website/static/icon/ms-icon-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/icon/ms-icon-70x70.png
--------------------------------------------------------------------------------
/internal/website/static/img/gqless-logo.square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/gqless-logo.square.png
--------------------------------------------------------------------------------
/internal/website/static/img/graphql.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/internal/website/static/img/intro/client-only_fields.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/intro/client-only_fields.png
--------------------------------------------------------------------------------
/internal/website/static/img/intro/intellisense.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/intro/intellisense.png
--------------------------------------------------------------------------------
/internal/website/static/img/javascript-output-type-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/javascript-output-type-error.png
--------------------------------------------------------------------------------
/internal/website/static/img/logger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logger.png
--------------------------------------------------------------------------------
/internal/website/static/img/logger/devtools_query.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logger/devtools_query.png
--------------------------------------------------------------------------------
/internal/website/static/img/logger/devtools_verbose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logger/devtools_verbose.png
--------------------------------------------------------------------------------
/internal/website/static/img/logo-1080p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logo-1080p.png
--------------------------------------------------------------------------------
/internal/website/static/img/logo-200x85.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logo-200x85.png
--------------------------------------------------------------------------------
/internal/website/static/img/logo-436p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logo-436p.png
--------------------------------------------------------------------------------
/internal/website/static/img/logo-full-size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logo-full-size.png
--------------------------------------------------------------------------------
/internal/website/static/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/logo.png
--------------------------------------------------------------------------------
/internal/website/static/img/production_ready.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/production_ready.png
--------------------------------------------------------------------------------
/internal/website/static/img/react-key-warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/react-key-warning.png
--------------------------------------------------------------------------------
/internal/website/static/img/react.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/internal/website/static/img/suspense-ssr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/suspense-ssr.png
--------------------------------------------------------------------------------
/internal/website/static/img/typescript.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/img/typescript.png
--------------------------------------------------------------------------------
/internal/website/static/video/invisible-data-fetching.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samdenty/gqless/27e289932cf45536c4e91190b96a4c9ce3d95063/internal/website/static/video/invisible-data-fetching.mp4
--------------------------------------------------------------------------------
/internal/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/docusaurus/tsconfig.json",
3 | "include": ["src/"]
4 | }
5 |
--------------------------------------------------------------------------------
/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/nodemon",
3 | "watch": ["packages/**/*", "./package.json"],
4 | "ext": "ts",
5 | "exec": "pnpm dev:nodemon",
6 | "ignore": ["**/node_modules", "**/generated", "**/dist"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/cli/.browserslistrc:
--------------------------------------------------------------------------------
1 | node 10
--------------------------------------------------------------------------------
/packages/cli/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | dist
5 |
--------------------------------------------------------------------------------
/packages/cli/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright © `2021` `GQless`
4 |
5 | Permission is hereby granted, free of charge, to any person
6 | obtaining a copy of this software and associated documentation
7 | files (the “Software”), to deal in the Software without
8 | restriction, including without limitation the rights to use,
9 | copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following
12 | conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 | OTHER DEALINGS IN THE SOFTWARE.
25 |
--------------------------------------------------------------------------------
/packages/cli/README.md:
--------------------------------------------------------------------------------
1 | # @gqless/cli
2 |
3 | ## Visit [https://gqless.com/cli/codegen](https://gqless.com/cli/codegen)
4 |
--------------------------------------------------------------------------------
/packages/cli/bin/gqless.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const { program } = require('commander');
4 |
5 | const {
6 | inspectWriteGenerate,
7 | defaultConfig,
8 | __innerState,
9 | } = require('../dist/index');
10 |
11 | __innerState.isCLI = true;
12 |
13 | program
14 | .version(require('../package.json').version)
15 | .description('CLI for gqless');
16 |
17 | program
18 | .command('generate [endpoint] [destination]')
19 | .option('--react', 'Create React client')
20 | .description(
21 | `Inspect or read from a file a GraphQL Schema and generate the gqless client in the specified directory (./src/generated/graphql.ts by default).
22 | EXAMPLE 1: "gqless generate ./schema.gql --react"
23 | EXAMPLE 2: "gqless generate http://localhost:3000/graphql src/gqless/index.ts"
24 | EXAMPLE 3 (Configuration file): "gqless generate"`
25 | )
26 | .action(async (endpoint, destination, opts) => {
27 | let react;
28 | if (opts.react != null) {
29 | react = defaultConfig.react =
30 | typeof opts.react === 'boolean' ? opts.react : !!opts.react;
31 | }
32 |
33 | await inspectWriteGenerate({
34 | endpoint,
35 | destination,
36 | cli: true,
37 | generateOptions: {
38 | react,
39 | },
40 | }).catch((err) => {
41 | if (err instanceof Error) delete err.stack;
42 | console.error(err);
43 | process.exit(1);
44 | });
45 | process.exit(0);
46 | });
47 |
48 | program.parse(process.argv);
49 |
--------------------------------------------------------------------------------
/packages/cli/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('test-utils/jest.config.js').default;
2 |
--------------------------------------------------------------------------------
/packages/cli/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './generate';
2 | export * from './inspectWriteGenerate';
3 | export * from './introspection';
4 | export * from './writeGenerate';
5 | export type { GQlessConfig as gqlessConfig, GQlessConfig } from './config';
6 | export { defaultConfig, gqlessConfigPromise } from './config';
7 | export { __innerState } from './innerState';
8 |
--------------------------------------------------------------------------------
/packages/cli/src/innerState.ts:
--------------------------------------------------------------------------------
1 | export const __innerState = {
2 | isCLI: false,
3 | };
4 |
--------------------------------------------------------------------------------
/packages/cli/src/introspection.ts:
--------------------------------------------------------------------------------
1 | import { fetch } from 'cross-fetch';
2 | import { print } from 'graphql';
3 |
4 | import { introspectSchema, wrapSchema } from '@graphql-tools/wrap';
5 |
6 | import { gqlessConfigPromise, defaultConfig } from './config';
7 |
8 | import type { AsyncExecutor } from '@graphql-tools/delegate';
9 | export interface IntrospectionOptions {
10 | /**
11 | * Endpoint of the remote GraphQL API or schema file
12 | */
13 | endpoint?: string;
14 | /**
15 | * Specify headers for the introspection
16 | */
17 | headers?: Record;
18 | }
19 |
20 | export const getRemoteSchema = async (
21 | /**
22 | * Endpoint of the remote GraphQL API
23 | */
24 | endpoint: string,
25 | /**
26 | * Specify options for the introspection
27 | */
28 | { headers }: Pick = {}
29 | ) => {
30 | const executor: AsyncExecutor = async ({ document, variables }) => {
31 | headers ||=
32 | (await gqlessConfigPromise).config.introspection?.headers ||
33 | defaultConfig.introspection.headers;
34 | const query = print(document);
35 | const fetchResult = await fetch(endpoint, {
36 | method: 'POST',
37 | headers: {
38 | 'Content-Type': 'application/json',
39 | ...headers,
40 | },
41 | body: JSON.stringify({ query, variables }),
42 | });
43 | return fetchResult.json();
44 | };
45 |
46 | const schema = wrapSchema({
47 | schema: await introspectSchema(executor, {
48 | endpoint,
49 | }),
50 | executor,
51 | });
52 |
53 | return schema;
54 | };
55 |
--------------------------------------------------------------------------------
/packages/cli/src/prettier.ts:
--------------------------------------------------------------------------------
1 | import {
2 | format as prettierFormat,
3 | Options as PrettierOptions,
4 | resolveConfig,
5 | } from 'prettier';
6 |
7 | const commonConfig = resolveConfig(process.cwd());
8 |
9 | export function formatPrettier(
10 | defaultOptions: Omit &
11 | Required>
12 | ) {
13 | const configPromise = commonConfig.then((config) =>
14 | Object.assign({}, config, defaultOptions)
15 | );
16 |
17 | return {
18 | async format(input: string) {
19 | return prettierFormat(input, await configPromise);
20 | },
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/packages/cli/test/introspection.test.ts:
--------------------------------------------------------------------------------
1 | import { GraphQLObjectType, GraphQLSchema } from 'graphql';
2 | import { assertIsDefined, createTestApp } from 'test-utils';
3 |
4 | import { getRemoteSchema } from '../src';
5 |
6 | const { server, isReady } = createTestApp({
7 | schema: `
8 | type Query {
9 | hello: String!
10 | }
11 | `,
12 | resolvers: {
13 | Query: {
14 | hello() {
15 | return 'hello world';
16 | },
17 | },
18 | },
19 | });
20 |
21 | let endpoint: string;
22 | beforeAll(async () => {
23 | await isReady;
24 |
25 | endpoint = (await server.listen(0)) + '/graphql';
26 | });
27 |
28 | afterAll(async () => {
29 | server.close();
30 | });
31 |
32 | test('introspection works', async () => {
33 | const schema = await getRemoteSchema(endpoint);
34 |
35 | expect(schema).toBeInstanceOf(GraphQLSchema);
36 |
37 | const queryType = schema.getQueryType();
38 |
39 | expect(queryType).toBeInstanceOf(GraphQLObjectType);
40 |
41 | assertIsDefined(queryType);
42 |
43 | const fieldsMap = queryType.getFields();
44 |
45 | const hello = fieldsMap['hello'];
46 |
47 | assertIsDefined(hello);
48 | });
49 |
--------------------------------------------------------------------------------
/packages/cli/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "../"
5 | },
6 | "include": ["**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/packages/cli/test/utils.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import { resolve } from 'path';
3 | import tmp from 'tmp-promise';
4 |
5 | export async function getTempDir({
6 | initClientFile,
7 | initSchemaFile,
8 | clientFileName = './client.ts',
9 | }: {
10 | initClientFile?: string;
11 | initSchemaFile?: string;
12 | clientFileName?: string;
13 | } = {}) {
14 | const tempDir = await tmp.dir({
15 | unsafeCleanup: true,
16 | });
17 |
18 | const clientPath = resolve(tempDir.path, clientFileName);
19 |
20 | const schemaPath = resolve(tempDir.path, './schema.generated.ts');
21 |
22 | if (initSchemaFile != null)
23 | await fs.promises.writeFile(schemaPath, initSchemaFile);
24 |
25 | if (initClientFile != null)
26 | await fs.promises.writeFile(clientPath, initClientFile);
27 |
28 | return Object.assign(tempDir, {
29 | clientPath,
30 | schemaPath,
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
3 | "include": ["src", "types"],
4 | "compilerOptions": {
5 | "module": "esnext",
6 | "lib": ["dom", "esnext"],
7 | "importHelpers": true,
8 | // output .d.ts declaration files for consumers
9 | "declaration": true,
10 | // output .js.map sourcemap files for consumers
11 | "sourceMap": true,
12 | // match output dir to input dir. e.g. dist/index instead of dist/src/index
13 | "rootDir": "./src",
14 | // stricter type-checking for stronger correctness. Recommended by TS
15 | "strict": true,
16 | // linter checks for common issues
17 | "isolatedModules": true,
18 | "noImplicitReturns": true,
19 | "noFallthroughCasesInSwitch": true,
20 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
21 | "noUnusedLocals": true,
22 | "noUnusedParameters": true,
23 | // use Node's module resolution algorithm, instead of the legacy TS one
24 | "moduleResolution": "node",
25 | // transpile JSX to React.createElement
26 | "jsx": "react",
27 | // interop between ESM and CJS modules. Recommended by TS
28 | "esModuleInterop": true,
29 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
30 | "skipLibCheck": true,
31 | // error out if import and file system have a casing mismatch. Recommended by TS
32 | "forceConsistentCasingInFileNames": true,
33 | "noEmit": true,
34 | "allowJs": true,
35 | "checkJs": true,
36 | "preserveWatchOutput": true
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/gqless/.browserslistrc:
--------------------------------------------------------------------------------
1 | node 10
--------------------------------------------------------------------------------
/packages/gqless/README.md:
--------------------------------------------------------------------------------
1 | # [GQless](https://gqless.com/getting-started) [](https://gqless.com) [](https://twitter.com/gqlessdev)
2 |
3 | > GQless is a fully-featured GraphQL client, which lowers the barrier of entry towards using GraphQL.
4 |
5 | Data requirements within your application are picked up automatically, freeing you from having to maintain GraphQL queries by-hand. It offers a first-class TypeScript experience. See API documentation at all times within autocomplete.
6 |
7 | Make breaking changes to your API, and see type-errors exactly where things are breaking, in realtime. No more running a separate validation step.
8 |
9 | **More documentation is available at [gqless.com/getting-started](https://gqless.com/getting-started).**
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/gqless/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('test-utils/jest.config.js').default;
2 |
--------------------------------------------------------------------------------
/packages/gqless/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/nodemon",
3 | "watch": ["src", "./package.json"],
4 | "ext": "ts",
5 | "exec": "pnpm dev:nodemon",
6 | "legacyWatch": true
7 | }
8 |
--------------------------------------------------------------------------------
/packages/gqless/src/Cache/index.ts:
--------------------------------------------------------------------------------
1 | export * from './accessorCache';
2 | export * from './dataCache';
3 |
--------------------------------------------------------------------------------
/packages/gqless/src/Client/index.ts:
--------------------------------------------------------------------------------
1 | export * from './client';
2 | export type { ResolveOptions, InlineResolveOptions } from './resolvers';
3 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/casters.ts:
--------------------------------------------------------------------------------
1 | export type NotUndefined = T extends undefined ? never : T;
2 |
3 | /**
4 | * Remove all possible 'undefined' values recursively from an object
5 | */
6 | export type NotSkeletonDeep = T extends Array
7 | ? Array>>
8 | : T extends (...args: any[]) => any
9 | ? (...args: Parameters) => NotSkeletonDeep>>
10 | : T extends object
11 | ? {
12 | [P in keyof T]: NotUndefined>;
13 | }
14 | : NotUndefined;
15 |
16 | /**
17 | * Remove all possible 'undefined' types in the first level.
18 | */
19 | export type NotSkeleton = T extends Array
20 | ? Array>
21 | : T extends (...args: any[]) => any
22 | ? (...args: Parameters) => NotUndefined>
23 | : T extends object
24 | ? {
25 | [P in keyof T]: NotUndefined;
26 | }
27 | : NotUndefined;
28 |
29 | const noop = (v: any) => v;
30 |
31 | /**
32 | * Runtime no-op that removes all the undefined types recursively
33 | */
34 | export const castNotSkeletonDeep: (v: T) => NotSkeletonDeep = noop;
35 |
36 | /**
37 | * Runtime no-op that removes all the undefined types in the first level
38 | */
39 | export const castNotSkeleton: (v: T) => NotSkeleton = noop;
40 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/getFields.ts:
--------------------------------------------------------------------------------
1 | import { isObject, isPlainObject } from '../Utils';
2 |
3 | export function getFields<
4 | TAccesorData extends object | undefined | null,
5 | TAccesorKeys extends keyof NonNullable
6 | >(accessor: TAccesorData, ...keys: TAccesorKeys[]): TAccesorData {
7 | if (!isObject(accessor)) return accessor;
8 |
9 | if (keys.length) for (const key of keys) Reflect.get(accessor, key);
10 | else for (const key in accessor) Reflect.get(accessor, key);
11 |
12 | return accessor;
13 | }
14 |
15 | export function getArrayFields<
16 | TArrayValue extends object | null | undefined,
17 | TArray extends TArrayValue[] | null | undefined,
18 | TArrayValueKeys extends keyof NonNullable[number]>
19 | >(accessorArray: TArray, ...keys: TArrayValueKeys[]): TArray {
20 | if (accessorArray == null) return accessorArray;
21 |
22 | if (Array.isArray(accessorArray)) {
23 | for (const value of accessorArray) {
24 | if (isPlainObject(value)) {
25 | getFields(value, ...keys);
26 | break;
27 | }
28 | }
29 | }
30 | return accessorArray;
31 | }
32 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/index.ts:
--------------------------------------------------------------------------------
1 | export * from './selectFields';
2 | export type { HydrateCacheOptions } from './ssr';
3 | export * from './getFields';
4 | export * from './casters';
5 | export * from './prepass';
6 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/prefetch.ts:
--------------------------------------------------------------------------------
1 | import { InnerClientState } from '../Client/client';
2 | import { SchedulerPromiseValue } from '../Scheduler';
3 |
4 | export interface Prefetch<
5 | GeneratedSchema extends {
6 | query: object;
7 | }
8 | > {
9 | (fn: (query: GeneratedSchema['query']) => TData):
10 | | TData
11 | | (Promise & { schedulerPromise: Promise });
12 | }
13 |
14 | export function createPrefetch<
15 | GeneratedSchema extends {
16 | query: object;
17 | }
18 | >(
19 | query: GeneratedSchema['query'],
20 | { scheduler }: InnerClientState
21 | ): Prefetch {
22 | return function prefetch(
23 | fn: (query: GeneratedSchema['query']) => TData
24 | ):
25 | | (Promise & {
26 | schedulerPromise: Promise;
27 | })
28 | | TData {
29 | const existingData = fn(query);
30 |
31 | if (scheduler.resolving) {
32 | return Object.assign(
33 | scheduler.resolving.promise.then(() => prefetch(fn)),
34 | {
35 | schedulerPromise: scheduler.resolving.promise,
36 | }
37 | );
38 | }
39 | return existingData;
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/prepass.ts:
--------------------------------------------------------------------------------
1 | import { isObject } from '../Utils';
2 |
3 | function getFirstNonNullValue(list: T[]): T | void {
4 | for (const value of list) if (value != null) return value;
5 | }
6 |
7 | export interface PrepassObjKey {
8 | field: string;
9 | variables?: Record;
10 | }
11 |
12 | export function prepass(
13 | v: T,
14 | ...keys: Array>
15 | ): T {
16 | if (v == null) return v;
17 |
18 | for (const composedKeys of keys) {
19 | const separatedKeys =
20 | typeof composedKeys === 'string' ? composedKeys.split('.') : composedKeys;
21 |
22 | let obj: unknown = v;
23 | for (const key of separatedKeys) {
24 | if (obj && key) {
25 | let property = typeof key === 'object' ? key.field : key;
26 | let variables = typeof key === 'object' ? key.variables : undefined;
27 |
28 | if (Array.isArray(obj)) {
29 | const firstNonNull = getFirstNonNullValue(obj);
30 | if (firstNonNull) {
31 | obj = firstNonNull;
32 | } else break;
33 | }
34 |
35 | if (isObject(obj)) {
36 | if (property in obj) {
37 | const value: unknown =
38 | //@ts-expect-error
39 | obj[property];
40 |
41 | if (typeof value === 'function') {
42 | obj = value(variables);
43 | } else {
44 | obj = value;
45 | }
46 | } else break;
47 | } else break;
48 | } else break;
49 | }
50 | }
51 |
52 | return v;
53 | }
54 |
--------------------------------------------------------------------------------
/packages/gqless/src/Helpers/refetch.ts:
--------------------------------------------------------------------------------
1 | import { InnerClientState } from '../Client/client';
2 | import { InlineResolveOptions, Resolvers } from '../Client/resolvers';
3 |
4 | export function isFunction(v: T | (() => T)): v is () => T {
5 | return typeof v === 'function';
6 | }
7 |
8 | export interface Refetch {
9 | (refetchArg: T | (() => T)): Promise;
10 | }
11 |
12 | export function createRefetch(
13 | innerState: InnerClientState,
14 | resolveSelections: Resolvers['resolveSelections'],
15 | inlineResolved: Resolvers['inlineResolved']
16 | ): Refetch {
17 | const { accessorCache } = innerState;
18 |
19 | const inlineResolveRefetch: InlineResolveOptions = {
20 | refetch: true,
21 | };
22 |
23 | async function refetch(refetchArg: T | (() => T)) {
24 | if (isFunction(refetchArg))
25 | return inlineResolved(refetchArg, inlineResolveRefetch);
26 |
27 | if (accessorCache.isProxy(refetchArg)) {
28 | const selectionSet = accessorCache.getSelectionSetHistory(refetchArg);
29 |
30 | if (selectionSet) {
31 | await resolveSelections(selectionSet, undefined, {
32 | ignoreResolveCache: true,
33 | });
34 | }
35 | return refetchArg;
36 | }
37 |
38 | if (process.env.NODE_ENV !== 'production') {
39 | console.warn('gqless: Invalid proxy to refetch!', refetchArg);
40 | }
41 | return refetchArg;
42 | }
43 |
44 | return refetch;
45 | }
46 |
--------------------------------------------------------------------------------
/packages/gqless/src/QueryBuilder/index.ts:
--------------------------------------------------------------------------------
1 | export * from './buildQuery';
2 |
--------------------------------------------------------------------------------
/packages/gqless/src/Schema/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types';
2 |
--------------------------------------------------------------------------------
/packages/gqless/src/Selection/index.ts:
--------------------------------------------------------------------------------
1 | export * from './selection';
2 | export type { SelectionManager } from './SelectionManager';
3 | export type {
4 | BuildSelectionInput,
5 | BuildSelectionValue,
6 | } from './SelectionBuilder';
7 |
--------------------------------------------------------------------------------
/packages/gqless/src/Utils/cachedJSON.ts:
--------------------------------------------------------------------------------
1 | const serializedVariablesCache = new WeakMap