Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

major(core/graphcache): Remove graphql imports by default (#3097)

authored by

Phil Pluckthun and committed by
GitHub
f182601c 4ad1967a

+274 -173
+6
.changeset/fluffy-tools-marry.md
··· 1 + --- 2 + '@urql/exchange-graphcache': major 3 + '@urql/core': major 4 + --- 5 + 6 + Remove dependence on `graphql` package and replace it with `@0no-co/graphql.web`, which reduces the default bundlesize impact of `urql` packages to a minimum. All types should remain compatible, even if you use `graphql` elsewhere in your app, and if other dependencies are using `graphql` you may alias it to `graphql-web-lite`.
+5
.changeset/tame-pumas-promise.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Remove dependence on `import { visit } from 'graphql';` with smaller but functionally equivalent alternative.
-3
exchanges/auth/package.json
··· 51 51 "@urql/core": ">=3.2.2", 52 52 "wonka": "^6.0.0" 53 53 }, 54 - "peerDependencies": { 55 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 56 - }, 57 54 "devDependencies": { 58 55 "@urql/core": "workspace:*", 59 56 "graphql": "^16.0.0"
+3 -5
exchanges/auth/src/authExchange.ts
··· 18 18 OperationResult, 19 19 CombinedError, 20 20 Exchange, 21 - TypedDocumentNode, 21 + DocumentInput, 22 22 AnyVariables, 23 23 } from '@urql/core'; 24 - 25 - import { DocumentNode } from 'graphql'; 26 24 27 25 /** Utilities to use while refreshing authentication tokens. */ 28 26 export interface AuthUtilities { ··· 43 41 * options, so you may have to pass them again, if needed. 44 42 */ 45 43 mutate<Data = any, Variables extends AnyVariables = AnyVariables>( 46 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string, 44 + query: DocumentInput<Data, Variables>, 47 45 variables: Variables, 48 46 context?: Partial<OperationContext> 49 47 ): Promise<OperationResult<Data>>; ··· 222 220 .then(() => 223 221 init({ 224 222 mutate<Data = any, Variables extends AnyVariables = AnyVariables>( 225 - query: DocumentNode | string, 223 + query: DocumentInput<Data, Variables>, 226 224 variables: Variables, 227 225 context?: Partial<OperationContext> 228 226 ): Promise<OperationResult<Data>> {
-3
exchanges/context/package.json
··· 50 50 "@urql/core": ">=3.2.2", 51 51 "wonka": "^6.0.0" 52 52 }, 53 - "peerDependencies": { 54 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 55 - }, 56 53 "devDependencies": { 57 54 "@urql/core": "workspace:*", 58 55 "graphql": "^16.0.0"
+1 -3
exchanges/graphcache/package.json
··· 62 62 "prepublishOnly": "run-s clean build" 63 63 }, 64 64 "dependencies": { 65 + "@0no-co/graphql.web": "^1.0.0", 65 66 "@urql/core": ">=3.2.2", 66 67 "wonka": "^6.0.0" 67 - }, 68 - "peerDependencies": { 69 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 70 68 }, 71 69 "devDependencies": { 72 70 "@cypress/react": "^7.0.2",
+55
exchanges/graphcache/src/ast/graphql.ts
··· 1 + import type * as GraphQL from 'graphql'; 2 + 3 + type OrNever<T> = 0 extends 1 & T ? never : T; 4 + 5 + export type IntrospectionQuery = 6 + | { 7 + readonly __schema: { 8 + queryType: { name: string; kind?: any }; 9 + mutationType?: { name: string; kind?: any } | null; 10 + subscriptionType?: { name: string; kind?: any } | null; 11 + types?: readonly IntrospectionType[]; 12 + }; 13 + } 14 + | OrNever<GraphQL.IntrospectionQuery>; 15 + 16 + export type IntrospectionTypeRef = 17 + | { 18 + readonly kind: 19 + | 'SCALAR' 20 + | 'OBJECT' 21 + | 'INTERFACE' 22 + | 'ENUM' 23 + | 'UNION' 24 + | 'INPUT_OBJECT'; 25 + readonly name?: string; 26 + readonly ofType?: IntrospectionTypeRef; 27 + } 28 + | OrNever<GraphQL.IntrospectionTypeRef>; 29 + 30 + export type IntrospectionInputTypeRef = 31 + | { 32 + readonly kind: 'SCALAR' | 'ENUM' | 'INPUT_OBJECT'; 33 + readonly name?: string; 34 + readonly ofType?: IntrospectionInputTypeRef; 35 + } 36 + | OrNever<GraphQL.IntrospectionInputTypeRef>; 37 + 38 + export type IntrospectionInputValue = 39 + | { 40 + readonly name: string; 41 + readonly description?: string | null; 42 + readonly defaultValue?: string | null; 43 + readonly type: IntrospectionInputTypeRef; 44 + } 45 + | OrNever<GraphQL.IntrospectionInputValue>; 46 + 47 + export type IntrospectionType = 48 + | { 49 + readonly kind: string; 50 + readonly name: string; 51 + readonly fields?: readonly any[]; 52 + readonly interfaces?: readonly any[]; 53 + readonly possibleTypes?: readonly any[]; 54 + } 55 + | OrNever<GraphQL.IntrospectionType>;
+1 -1
exchanges/graphcache/src/ast/node.ts
··· 7 7 FieldNode, 8 8 FragmentDefinitionNode, 9 9 Kind, 10 - } from 'graphql'; 10 + } from '@0no-co/graphql.web'; 11 11 12 12 export type SelectionSet = ReadonlyArray<SelectionNode>; 13 13
+5 -6
exchanges/graphcache/src/ast/schema.ts
··· 1 - import { 1 + import type { 2 2 IntrospectionQuery, 3 - IntrospectionSchema, 4 - IntrospectionInputValue, 5 3 IntrospectionTypeRef, 4 + IntrospectionInputValue, 6 5 IntrospectionType, 7 - } from 'graphql'; 6 + } from './graphql'; 8 7 9 8 export interface SchemaField { 10 9 name: string; ··· 37 36 queryType: { name: string; kind?: any }; 38 37 mutationType?: { name: string; kind?: any } | null; 39 38 subscriptionType?: { name: string; kind?: any } | null; 40 - types?: IntrospectionSchema['types']; 39 + types?: readonly any[]; 41 40 } 42 41 43 42 export type IntrospectionData = ··· 73 72 kind: type.kind as 'OBJECT' | 'INTERFACE', 74 73 interfaces: buildNameMap(type.interfaces || []), 75 74 fields: buildNameMap( 76 - type.fields.map(field => ({ 75 + type.fields!.map((field: any) => ({ 77 76 name: field.name, 78 77 type: field.type, 79 78 args: buildNameMap(field.args),
+4 -1
exchanges/graphcache/src/ast/schemaPredicates.ts
··· 1 - import { InlineFragmentNode, FragmentDefinitionNode } from 'graphql'; 1 + import { 2 + InlineFragmentNode, 3 + FragmentDefinitionNode, 4 + } from '@0no-co/graphql.web'; 2 5 3 6 import { warn, invariant } from '../helpers/help'; 4 7 import { getTypeCondition } from './node';
+1 -1
exchanges/graphcache/src/ast/traversal.ts
··· 6 6 InlineFragmentNode, 7 7 valueFromASTUntyped, 8 8 Kind, 9 - } from 'graphql'; 9 + } from '@0no-co/graphql.web'; 10 10 11 11 import { getName } from './node'; 12 12
+1 -1
exchanges/graphcache/src/ast/variables.ts
··· 2 2 FieldNode, 3 3 OperationDefinitionNode, 4 4 valueFromASTUntyped, 5 - } from 'graphql'; 5 + } from '@0no-co/graphql.web'; 6 6 7 7 import { getName } from './node'; 8 8
+5 -1
exchanges/graphcache/src/helpers/help.ts
··· 3 3 // Every warning and error comes with a number that uniquely identifies them. 4 4 // You can read more about the messages themselves in `docs/graphcache/errors.md` 5 5 6 - import { Kind, ExecutableDefinitionNode, InlineFragmentNode } from 'graphql'; 6 + import { 7 + Kind, 8 + ExecutableDefinitionNode, 9 + InlineFragmentNode, 10 + } from '@0no-co/graphql.web'; 7 11 8 12 export type ErrorCode = 9 13 | 1
+1 -1
exchanges/graphcache/src/offlineExchange.ts
··· 1 1 import { pipe, merge, makeSubject, filter } from 'wonka'; 2 - import { SelectionNode } from 'graphql'; 2 + import { SelectionNode } from '@0no-co/graphql.web'; 3 3 4 4 import { 5 5 Operation,
+6 -1
exchanges/graphcache/src/operations/query.ts
··· 1 - import { FieldNode, DocumentNode, FragmentDefinitionNode } from 'graphql'; 2 1 import { CombinedError } from '@urql/core'; 2 + 3 + import { 4 + FieldNode, 5 + DocumentNode, 6 + FragmentDefinitionNode, 7 + } from '@0no-co/graphql.web'; 3 8 4 9 import { 5 10 getSelectionSet,
+6 -6
exchanges/graphcache/src/operations/shared.ts
··· 1 - import { CombinedError } from '@urql/core'; 1 + import { CombinedError, ErrorLike } from '@urql/core'; 2 + 2 3 import { 3 - GraphQLError, 4 4 FieldNode, 5 5 InlineFragmentNode, 6 6 FragmentDefinitionNode, 7 - } from 'graphql'; 7 + } from '@0no-co/graphql.web'; 8 8 9 9 import { 10 10 isDeferred, ··· 41 41 parentFieldKey: string; 42 42 parent: Data; 43 43 fieldName: string; 44 - error: GraphQLError | undefined; 44 + error: ErrorLike | undefined; 45 45 partial: boolean; 46 46 optimistic: boolean; 47 47 __internal: { 48 48 path: Array<string | number>; 49 - errorMap: { [path: string]: GraphQLError } | undefined; 49 + errorMap: { [path: string]: ErrorLike } | undefined; 50 50 }; 51 51 } 52 52 ··· 54 54 export const deferRef: { current: boolean } = { current: false }; 55 55 56 56 // Checks whether the current data field is a cache miss because of a GraphQLError 57 - export const getFieldError = (ctx: Context): GraphQLError | undefined => 57 + export const getFieldError = (ctx: Context): ErrorLike | undefined => 58 58 ctx.__internal.path.length > 0 && ctx.__internal.errorMap 59 59 ? ctx.__internal.errorMap[ctx.__internal.path.join('.')] 60 60 : undefined;
+6 -1
exchanges/graphcache/src/operations/write.ts
··· 1 - import { FieldNode, DocumentNode, FragmentDefinitionNode } from 'graphql'; 2 1 import { CombinedError } from '@urql/core'; 2 + 3 + import { 4 + FieldNode, 5 + DocumentNode, 6 + FragmentDefinitionNode, 7 + } from '@0no-co/graphql.web'; 3 8 4 9 import { 5 10 getFragments,
+1 -1
exchanges/graphcache/src/store/store.ts
··· 1 - import { DocumentNode } from 'graphql'; 2 1 import { TypedDocumentNode, formatDocument, createRequest } from '@urql/core'; 3 2 4 3 import { ··· 35 34 expectValidOptimisticMutationsConfig, 36 35 } from '../ast'; 37 36 37 + type DocumentNode = TypedDocumentNode<any, any>; 38 38 type RootField = 'query' | 'mutation' | 'subscription'; 39 39 40 40 /** Implementation of the {@link Cache} interface as created internally by the {@link cacheExchange}.
+15 -8
exchanges/graphcache/src/types.ts
··· 1 - import { AnyVariables, TypedDocumentNode, RequestExtensions } from '@urql/core'; 2 - import { GraphQLError, DocumentNode, FragmentDefinitionNode } from 'graphql'; 1 + import { 2 + AnyVariables, 3 + DocumentInput, 4 + RequestExtensions, 5 + TypedDocumentNode, 6 + ErrorLike, 7 + } from '@urql/core'; 8 + 9 + import { FragmentDefinitionNode } from '@0no-co/graphql.web'; 3 10 import { IntrospectionData } from './ast'; 4 11 5 12 /** Nullable GraphQL list types of `T`. ··· 177 184 * GraphQL operation: its query document and variables. 178 185 */ 179 186 export interface OperationRequest { 180 - query: DocumentNode | TypedDocumentNode<any, any>; 187 + query: Exclude<DocumentInput<any, any>, string>; 181 188 variables?: any; 182 189 } 183 190 ··· 209 216 parentFieldKey: string; 210 217 /** Current field that the resolver has been called on. */ 211 218 fieldName: string; 212 - /** Map of fragment definitions from the {@link DocumentNode}. */ 219 + /** Map of fragment definitions from the query document. */ 213 220 fragments: Fragments; 214 221 /** Full original {@link Variables} object on the {@link OperationRequest}. */ 215 222 variables: Variables; ··· 220 227 * will be set and provided here. This can be useful to recover from an 221 228 * error on a specific field. 222 229 */ 223 - error: GraphQLError | undefined; 230 + error: ErrorLike | undefined; 224 231 /** Flag used to indicate whether the current GraphQL query is only partially cached. 225 232 * 226 233 * @remarks ··· 257 264 * cached data, as accepted by {@link cache.readQuery}. 258 265 */ 259 266 export interface QueryInput<T = Data, V = Variables> { 260 - query: string | DocumentNode | TypedDocumentNode<T, V>; 267 + query: DocumentInput<T, V>; 261 268 variables?: V; 262 269 } 263 270 ··· 443 450 * ``` 444 451 */ 445 452 readFragment<T = Data, V = Variables>( 446 - fragment: DocumentNode | TypedDocumentNode<T, V>, 453 + fragment: TypedDocumentNode<any, any> | TypedDocumentNode<T, V>, 447 454 entity: string | Data | T, 448 455 variables?: V 449 456 ): T | null; ··· 473 480 * ``` 474 481 */ 475 482 writeFragment<T = Data, V = Variables>( 476 - fragment: DocumentNode | TypedDocumentNode<T, V>, 483 + fragment: TypedDocumentNode<any, any> | TypedDocumentNode<T, V>, 477 484 data: T, 478 485 variables?: V 479 486 ): void;
-3
exchanges/multipart-fetch/package.json
··· 50 50 "extract-files": "^11.0.0", 51 51 "wonka": "^6.0.0" 52 52 }, 53 - "peerDependencies": { 54 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 55 - }, 56 53 "devDependencies": { 57 54 "@urql/core": "workspace:*", 58 55 "graphql": "^16.0.0"
-3
exchanges/persisted/package.json
··· 49 49 "@urql/core": ">=3.2.2", 50 50 "wonka": "^6.0.0" 51 51 }, 52 - "peerDependencies": { 53 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 54 - }, 55 52 "devDependencies": { 56 53 "@urql/core": "workspace:*", 57 54 "graphql": "^16.0.0"
+5 -3
exchanges/persisted/src/persistedExchange.ts
··· 12 12 makeOperation, 13 13 stringifyDocument, 14 14 PersistedRequestExtensions, 15 + TypedDocumentNode, 15 16 OperationResult, 16 17 CombinedError, 17 18 Exchange, 18 19 Operation, 19 20 } from '@urql/core'; 20 - 21 - import type { DocumentNode } from 'graphql'; 22 21 23 22 import { hash } from './sha256'; 24 23 ··· 67 66 * API is unavailable on React Native, which may require you to 68 67 * pass a custom function here. 69 68 */ 70 - generateHash?(query: string, document: DocumentNode): Promise<string>; 69 + generateHash?( 70 + query: string, 71 + document: TypedDocumentNode<any, any> 72 + ): Promise<string>; 71 73 /** Enables persisted queries to be used for mutations. 72 74 * 73 75 * @remarks
-3
exchanges/refocus/package.json
··· 52 52 "@types/react": "^17.0.4", 53 53 "graphql": "^16.0.0" 54 54 }, 55 - "peerDependencies": { 56 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 57 - }, 58 55 "dependencies": { 59 56 "@urql/core": ">=3.2.2", 60 57 "wonka": "^6.0.0"
-3
exchanges/request-policy/package.json
··· 50 50 "@urql/core": "workspace:*", 51 51 "graphql": "^16.0.0" 52 52 }, 53 - "peerDependencies": { 54 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 55 - }, 56 53 "dependencies": { 57 54 "@urql/core": ">=3.2.2", 58 55 "wonka": "^6.0.0"
-3
exchanges/retry/package.json
··· 50 50 "@urql/core": "workspace:*", 51 51 "graphql": "^16.0.0" 52 52 }, 53 - "peerDependencies": { 54 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 55 - }, 56 53 "dependencies": { 57 54 "@urql/core": ">=3.2.2", 58 55 "wonka": "^6.0.0"
+1
package.json
··· 55 55 } 56 56 }, 57 57 "devDependencies": { 58 + "@0no-co/graphql.web": "^1.0.0", 58 59 "@actions/artifact": "^1.1.1", 59 60 "@actions/core": "^1.10.0", 60 61 "@babel/core": "^7.21.3",
+1 -6
packages/core/package.json
··· 52 52 "prepare": "node ../../scripts/prepare/index.js", 53 53 "prepublishOnly": "run-s clean build" 54 54 }, 55 - "devDependencies": { 56 - "graphql": "^16.0.0" 57 - }, 58 - "peerDependencies": { 59 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" 60 - }, 61 55 "dependencies": { 56 + "@0no-co/graphql.web": "^1.0.0", 62 57 "wonka": "^6.1.2" 63 58 }, 64 59 "publishConfig": {
+1 -1
packages/core/src/client.test.ts
··· 1 - import { print } from 'graphql'; 1 + import { print } from '@0no-co/graphql.web'; 2 2 import { vi, expect, it, beforeEach, describe, afterEach } from 'vitest'; 3 3 4 4 /** NOTE: Testing in this file is designed to test both the client and its interaction with default Exchanges */
+5 -7
packages/core/src/client.ts
··· 22 22 Subscription, 23 23 } from 'wonka'; 24 24 25 - import { DocumentNode } from 'graphql'; 26 - 27 25 import { composeExchanges } from './exchanges'; 28 26 import { fallbackExchange } from './exchanges/fallback'; 29 27 30 28 import { 31 - TypedDocumentNode, 29 + DocumentInput, 32 30 AnyVariables, 33 31 Exchange, 34 32 ExchangeInput, ··· 358 356 * ``` 359 357 */ 360 358 query<Data = any, Variables extends AnyVariables = AnyVariables>( 361 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string, 359 + query: DocumentInput<Data, Variables>, 362 360 variables: Variables, 363 361 context?: Partial<OperationContext> 364 362 ): OperationResultSource<OperationResult<Data, Variables>>; ··· 384 382 * or asynchronously. 385 383 */ 386 384 readQuery<Data = any, Variables extends AnyVariables = AnyVariables>( 387 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string, 385 + query: DocumentInput<Data, Variables>, 388 386 variables: Variables, 389 387 context?: Partial<OperationContext> 390 388 ): OperationResult<Data, Variables> | null; ··· 450 448 * ``` 451 449 */ 452 450 subscription<Data = any, Variables extends AnyVariables = AnyVariables>( 453 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string, 451 + query: DocumentInput<Data, Variables>, 454 452 variables: Variables, 455 453 context?: Partial<OperationContext> 456 454 ): OperationResultSource<OperationResult<Data, Variables>>; ··· 519 517 * ``` 520 518 */ 521 519 mutation<Data = any, Variables extends AnyVariables = AnyVariables>( 522 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string, 520 + query: DocumentInput<Data, Variables>, 523 521 variables: Variables, 524 522 context?: Partial<OperationContext> 525 523 ): OperationResultSource<OperationResult<Data, Variables>>;
+1 -1
packages/core/src/exchanges/ssr.ts
··· 1 - import { GraphQLError } from 'graphql'; 1 + import type { GraphQLError } from '../utils/graphql'; 2 2 import { pipe, filter, merge, map, tap } from 'wonka'; 3 3 import { Exchange, OperationResult, Operation } from '../types'; 4 4 import { addMetadata, CombinedError } from '../utils';
+1 -1
packages/core/src/gql.test.ts
··· 1 - import { parse, print } from 'graphql'; 1 + import { parse, print } from '@0no-co/graphql.web'; 2 2 import { vi, expect, it, beforeEach, SpyInstance } from 'vitest'; 3 3 4 4 import { gql } from './gql';
+2 -1
packages/core/src/gql.ts
··· 1 1 /* eslint-disable prefer-rest-params */ 2 - import { DocumentNode, DefinitionNode, Kind } from 'graphql'; 2 + import { Kind } from '@0no-co/graphql.web'; 3 + import type { DocumentNode, DefinitionNode } from './utils/graphql'; 3 4 import { AnyVariables, TypedDocumentNode } from './types'; 4 5 import { keyDocument, stringifyDocument } from './utils'; 5 6
+19 -9
packages/core/src/types.ts
··· 1 - import type { GraphQLError, DocumentNode, DefinitionNode } from 'graphql'; 1 + import type { GraphQLError, DocumentNode } from './utils/graphql'; 2 2 import { Subscription, Source } from 'wonka'; 3 3 import { Client } from './client'; 4 4 import { CombinedError } from './utils/error'; ··· 22 22 * 23 23 * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information. 24 24 */ 25 - export interface TypedDocumentNode< 25 + export type TypedDocumentNode< 26 26 Result = { [key: string]: any }, 27 27 Variables = { [key: string]: any } 28 - > extends DocumentNode { 29 - /** GraphQL.js Definition Nodes of the `DocumentNode`. */ 30 - readonly definitions: ReadonlyArray<DefinitionNode>; 28 + > = DocumentNode & { 31 29 /** Type to support `@graphql-typed-document-node/core` 32 30 * @internal 33 31 */ ··· 36 34 * @internal 37 35 */ 38 36 __ensureTypesOfVariablesAndResultMatching?: (variables: Variables) => Result; 39 - } 37 + }; 38 + 39 + /** Any GraphQL `DocumentNode` or query string input. 40 + * 41 + * @remarks 42 + * Wherever any `urql` bindings or API expect a query, it accepts either a query string, 43 + * a `DocumentNode`, or a {@link TypedDocumentNode}. 44 + */ 45 + export type DocumentInput< 46 + Result = { [key: string]: any }, 47 + Variables = { [key: string]: any } 48 + > = string | DocumentNode | TypedDocumentNode<Result, Variables>; 40 49 41 50 /** A list of errors on {@link ExecutionResult | ExecutionResults}. 42 51 * @see {@link https://spec.graphql.org/draft/#sec-Errors.Error-Result-Format} for the GraphQL Error Result format spec. 43 52 */ 44 - type ErrorLike = Partial<GraphQLError> | Error; 53 + export type ErrorLike = Partial<GraphQLError> | Error; 54 + 45 55 /** Extensions which may be placed on {@link ExecutionResult | ExecutionResults}. 46 56 * @see {@link https://spec.graphql.org/draft/#sel-EAPHJCAACCoGu9J} for the GraphQL Error Result format spec. 47 57 */ ··· 301 311 Variables extends AnyVariables = AnyVariables 302 312 > = 303 313 | ({ 304 - query: string | DocumentNode | TypedDocumentNode<Data, Variables>; 314 + query: DocumentInput<Data, Variables>; 305 315 } & (Variables extends void 306 316 ? { 307 317 variables?: Variables; ··· 322 332 variables?: Variables; 323 333 })) 324 334 | { 325 - query: string | DocumentNode | TypedDocumentNode<Data, Variables>; 335 + query: DocumentInput<Data, Variables>; 326 336 variables: Variables; 327 337 }; 328 338
+3 -2
packages/core/src/utils/error.ts
··· 1 - import { GraphQLError } from 'graphql'; 1 + import { GraphQLError } from '@0no-co/graphql.web'; 2 + import { ErrorLike } from '../types'; 2 3 3 4 const generateErrorMessage = ( 4 5 networkErr?: Error, ··· 93 94 94 95 constructor(input: { 95 96 networkError?: Error; 96 - graphQLErrors?: Array<string | Partial<GraphQLError> | Error>; 97 + graphQLErrors?: Array<string | ErrorLike>; 97 98 response?: any; 98 99 }) { 99 100 const normalizedGraphQLErrors = (input.graphQLErrors || []).map(
+16
packages/core/src/utils/graphql.ts
··· 1 + import type * as GraphQLWeb from '@0no-co/graphql.web'; 2 + import type * as GraphQL from 'graphql'; 3 + 4 + type OrNever<T> = 0 extends 1 & T ? never : T; 5 + 6 + export type GraphQLError = 7 + | GraphQLWeb.GraphQLError 8 + | OrNever<GraphQL.GraphQLError>; 9 + 10 + export type DocumentNode = 11 + | GraphQLWeb.DocumentNode 12 + | OrNever<GraphQL.DocumentNode>; 13 + 14 + export type DefinitionNode = 15 + | GraphQLWeb.DefinitionNode 16 + | OrNever<GraphQL.DefinitionNode>;
+1 -1
packages/core/src/utils/request.test.ts
··· 1 1 import { expect, it, describe } from 'vitest'; 2 2 3 - import { parse, print } from 'graphql'; 3 + import { parse, print } from '@0no-co/graphql.web'; 4 4 import { gql } from '../gql'; 5 5 import { createRequest, stringifyDocument } from './request'; 6 6 import { formatDocument } from './typenames';
+8 -18
packages/core/src/utils/request.ts
··· 1 - import { 2 - Location, 3 - DefinitionNode, 4 - DocumentNode, 5 - Kind, 6 - parse, 7 - print, 8 - } from 'graphql'; 9 - 1 + import { Kind, parse, print } from '@0no-co/graphql.web'; 2 + import type { DocumentNode, DefinitionNode } from './graphql'; 10 3 import { HashValue, phash } from './hash'; 11 4 import { stringifyVariables } from './variables'; 12 5 13 6 import type { 7 + DocumentInput, 14 8 TypedDocumentNode, 15 9 AnyVariables, 16 10 GraphQLRequest, 17 11 RequestExtensions, 18 12 } from '../types'; 19 13 20 - interface WritableLocation { 21 - loc: Location | undefined; 22 - } 23 - 24 14 /** A `DocumentNode` annotated with its hashed key. 25 15 * @internal 26 16 */ 27 - export interface KeyedDocumentNode extends DocumentNode { 17 + export type KeyedDocumentNode = TypedDocumentNode & { 28 18 __key: HashValue; 29 - } 19 + }; 30 20 31 21 const SOURCE_NAME = 'gql'; 32 22 const GRAPHQL_STRING_RE = /("{3}[\s\S]*"{3}|"(?:\\.|[^"])*")/g; ··· 70 60 } 71 61 72 62 if (typeof node !== 'string' && !node.loc) { 73 - (node as WritableLocation).loc = { 63 + (node as any).loc = { 74 64 start: 0, 75 65 end: printed.length, 76 66 source: { ··· 78 68 name: SOURCE_NAME, 79 69 locationOffset: { line: 1, column: 1 }, 80 70 }, 81 - } as Location; 71 + }; 82 72 } 83 73 84 74 return printed; ··· 157 147 Data = any, 158 148 Variables extends AnyVariables = AnyVariables 159 149 >( 160 - _query: string | DocumentNode | TypedDocumentNode<Data, Variables>, 150 + _query: DocumentInput<Data, Variables>, 161 151 _variables: Variables, 162 152 extensions?: RequestExtensions | undefined 163 153 ): GraphQLRequest<Data, Variables> => {
+1 -1
packages/core/src/utils/typenames.test.ts
··· 1 - import { parse, print } from 'graphql'; 1 + import { parse, print } from '@0no-co/graphql.web'; 2 2 import { describe, it, expect } from 'vitest'; 3 3 import { collectTypesFromResponse, formatDocument } from './typenames'; 4 4 import { createRequest } from './request';
+48 -36
packages/core/src/utils/typenames.ts
··· 1 - import { 2 - DocumentNode, 3 - FieldNode, 4 - InlineFragmentNode, 5 - Kind, 6 - visit, 7 - } from 'graphql'; 8 - 1 + import { Kind, SelectionNode, DefinitionNode } from '@0no-co/graphql.web'; 9 2 import { KeyedDocumentNode, keyDocument } from './request'; 3 + import { TypedDocumentNode } from '../types'; 10 4 11 5 interface EntityLike { 12 6 [key: string]: EntityLike | EntityLike[] | any; ··· 39 33 ...collectTypes(response as EntityLike, new Set()), 40 34 ]; 41 35 42 - const formatNode = (node: FieldNode | InlineFragmentNode) => { 43 - if (!node.selectionSet) return node; 44 - for (const selection of node.selectionSet.selections) 45 - if ( 46 - selection.kind === Kind.FIELD && 47 - selection.name.value === '__typename' && 48 - !selection.alias 49 - ) 50 - return node; 36 + const formatNode = < 37 + T extends SelectionNode | DefinitionNode | TypedDocumentNode<any, any> 38 + >( 39 + node: T 40 + ): T => { 41 + let hasChanged = false; 51 42 52 - return { 53 - ...node, 54 - selectionSet: { 55 - ...node.selectionSet, 56 - selections: [ 57 - ...node.selectionSet.selections, 58 - { 43 + if ('definitions' in node) { 44 + const definitions: DefinitionNode[] = []; 45 + for (const definition of node.definitions) { 46 + const newDefinition = formatNode(definition); 47 + hasChanged = hasChanged || newDefinition !== definition; 48 + definitions.push(newDefinition); 49 + } 50 + if (hasChanged) return { ...node, definitions }; 51 + } else if ('selectionSet' in node) { 52 + const selections: SelectionNode[] = []; 53 + let hasTypename = node.kind === Kind.OPERATION_DEFINITION; 54 + if (node.selectionSet) { 55 + for (const selection of node.selectionSet.selections || []) { 56 + hasTypename = 57 + hasTypename || 58 + (selection.kind === Kind.FIELD && 59 + selection.name.value === '__typename' && 60 + !selection.alias); 61 + const newSelection = formatNode(selection); 62 + hasChanged = hasChanged || newSelection !== selection; 63 + selections.push(newSelection); 64 + } 65 + if (!hasTypename) { 66 + hasChanged = true; 67 + selections.push({ 59 68 kind: Kind.FIELD, 60 69 name: { 61 70 kind: Kind.NAME, 62 71 value: '__typename', 63 72 }, 64 - }, 65 - ], 66 - }, 67 - }; 73 + }); 74 + } 75 + if (hasChanged) 76 + return { ...node, selectionSet: { ...node.selectionSet, selections } }; 77 + } 78 + } 79 + 80 + return node; 68 81 }; 69 82 70 83 const formattedDocs = new Map<number, KeyedDocumentNode>(); ··· 87 100 * @see {@link https://spec.graphql.org/October2021/#sec-Type-Name-Introspection} for more information 88 101 * on typename introspection via the `__typename` field. 89 102 */ 90 - export const formatDocument = <T extends DocumentNode>(node: T): T => { 103 + export const formatDocument = <T extends TypedDocumentNode<any, any>>( 104 + node: T 105 + ): T => { 91 106 const query = keyDocument(node); 92 107 93 108 let result = formattedDocs.get(query.__key); 94 109 if (!result) { 95 - result = visit(query, { 96 - Field: formatNode, 97 - InlineFragment: formatNode, 98 - }) as KeyedDocumentNode; 99 - 110 + formattedDocs.set( 111 + query.__key, 112 + (result = formatNode(query) as KeyedDocumentNode) 113 + ); 100 114 // Ensure that the hash of the resulting document won't suddenly change 101 115 // we are marking __key as non-enumerable so when external exchanges use visit 102 116 // to manipulate a document we won't restore the previous query due to the __key ··· 105 119 value: query.__key, 106 120 enumerable: false, 107 121 }); 108 - 109 - formattedDocs.set(query.__key, result); 110 122 } 111 123 112 124 return result as unknown as T;
-1
packages/preact-urql/package.json
··· 54 54 "preact": "^10.13.0" 55 55 }, 56 56 "peerDependencies": { 57 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", 58 57 "preact": ">= 10.0.0" 59 58 }, 60 59 "dependencies": {
+2 -3
packages/preact-urql/src/components/Mutation.ts
··· 1 1 import { VNode } from 'preact'; 2 - import { DocumentNode } from 'graphql'; 3 - import { AnyVariables, TypedDocumentNode } from '@urql/core'; 2 + import { AnyVariables, DocumentInput } from '@urql/core'; 4 3 5 4 import { useMutation, UseMutationState, UseMutationExecute } from '../hooks'; 6 5 ··· 18 17 Variables extends AnyVariables = AnyVariables 19 18 > { 20 19 /* The GraphQL mutation document that {@link useMutation} will execute. */ 21 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string; 20 + query: DocumentInput<Data, Variables>; 22 21 children(arg: MutationState<Data, Variables>): VNode<any>; 23 22 } 24 23
+2 -5
packages/preact-urql/src/hooks/useMutation.ts
··· 1 - import { DocumentNode } from 'graphql'; 2 1 import { useState, useCallback, useRef, useEffect } from 'preact/hooks'; 3 2 import { pipe, toPromise } from 'wonka'; 4 3 5 4 import { 6 5 AnyVariables, 7 - TypedDocumentNode, 6 + DocumentInput, 8 7 OperationResult, 9 8 OperationContext, 10 9 CombinedError, ··· 144 143 export function useMutation< 145 144 Data = any, 146 145 Variables extends AnyVariables = AnyVariables 147 - >( 148 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string 149 - ): UseMutationResponse<Data, Variables> { 146 + >(query: DocumentInput<Data, Variables>): UseMutationResponse<Data, Variables> { 150 147 const isMounted = useRef(true); 151 148 const client = useClient(); 152 149
-1
packages/react-urql/package.json
··· 57 57 "vite": "^3.2.4" 58 58 }, 59 59 "peerDependencies": { 60 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", 61 60 "react": ">= 16.8.0" 62 61 }, 63 62 "dependencies": {
+2 -3
packages/react-urql/src/components/Mutation.ts
··· 1 - import { DocumentNode } from 'graphql'; 2 1 import { ReactElement } from 'react'; 3 - import { AnyVariables, TypedDocumentNode } from '@urql/core'; 2 + import { AnyVariables, DocumentInput } from '@urql/core'; 4 3 5 4 import { useMutation, UseMutationState, UseMutationExecute } from '../hooks'; 6 5 ··· 18 17 Variables extends AnyVariables = AnyVariables 19 18 > { 20 19 /* The GraphQL mutation document that {@link useMutation} will execute. */ 21 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string; 20 + query: DocumentInput<Data, Variables>; 22 21 children(arg: MutationState<Data, Variables>): ReactElement<any>; 23 22 } 24 23
+2 -5
packages/react-urql/src/hooks/useMutation.ts
··· 1 - import { DocumentNode } from 'graphql'; 2 1 import { useState, useCallback, useRef, useEffect } from 'react'; 3 2 import { pipe, toPromise } from 'wonka'; 4 3 5 4 import { 6 5 AnyVariables, 7 - TypedDocumentNode, 6 + DocumentInput, 8 7 OperationResult, 9 8 OperationContext, 10 9 CombinedError, ··· 144 143 export function useMutation< 145 144 Data = any, 146 145 Variables extends AnyVariables = AnyVariables 147 - >( 148 - query: DocumentNode | TypedDocumentNode<Data, Variables> | string 149 - ): UseMutationResponse<Data, Variables> { 146 + >(query: DocumentInput<Data, Variables>): UseMutationResponse<Data, Variables> { 150 147 const isMounted = useRef(true); 151 148 const client = useClient(); 152 149
+2 -3
packages/react-urql/src/hooks/useRequest.ts
··· 1 - import { DocumentNode } from 'graphql'; 2 1 import { useRef, useMemo } from 'react'; 3 2 import { 4 3 AnyVariables, 5 - TypedDocumentNode, 4 + DocumentInput, 6 5 GraphQLRequest, 7 6 createRequest, 8 7 } from '@urql/core'; ··· 14 13 Data = any, 15 14 Variables extends AnyVariables = AnyVariables 16 15 >( 17 - query: string | DocumentNode | TypedDocumentNode<Data, Variables>, 16 + query: DocumentInput<Data, Variables>, 18 17 variables: Variables 19 18 ): GraphQLRequest<Data, Variables> { 20 19 const prev = useRef<undefined | GraphQLRequest<Data, Variables>>(undefined);
-1
packages/svelte-urql/package.json
··· 48 48 "prepublishOnly": "run-s clean build" 49 49 }, 50 50 "peerDependencies": { 51 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", 52 51 "svelte": "^3.0.0" 53 52 }, 54 53 "dependencies": {
-1
packages/vue-urql/package.json
··· 54 54 "vue": "^3.2.47" 55 55 }, 56 56 "peerDependencies": { 57 - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", 58 57 "vue": "^2.7.0 || ^3.0.0" 59 58 }, 60 59 "dependencies": {
+25 -4
pnpm-lock.yaml
··· 14 14 15 15 .: 16 16 specifiers: 17 + '@0no-co/graphql.web': ^1.0.0 17 18 '@actions/artifact': ^1.1.1 18 19 '@actions/core': ^1.10.0 19 20 '@actions/github': ^5.1.1 ··· 71 72 '@actions/github': 5.1.1 72 73 node-fetch: 3.3.1 73 74 devDependencies: 75 + '@0no-co/graphql.web': 1.0.0_graphql@16.6.0 74 76 '@actions/artifact': 1.1.1 75 77 '@actions/core': 1.10.0 76 78 '@babel/core': 7.21.3 ··· 158 160 159 161 exchanges/graphcache: 160 162 specifiers: 163 + '@0no-co/graphql.web': ^1.0.0 161 164 '@cypress/react': ^7.0.2 162 165 '@urql/core': '>=3.2.2' 163 166 '@urql/exchange-execute': workspace:* ··· 169 172 urql: workspace:* 170 173 wonka: ^6.2.4 171 174 dependencies: 175 + '@0no-co/graphql.web': 1.0.0_graphql@16.6.0 172 176 '@urql/core': link:../../packages/core 173 177 wonka: 6.2.4 174 178 devDependencies: ··· 253 257 254 258 packages/core: 255 259 specifiers: 256 - graphql: ^16.6.0 260 + '@0no-co/graphql.web': ^1.0.0 257 261 wonka: ^6.2.4 258 262 dependencies: 263 + '@0no-co/graphql.web': 1.0.0 259 264 wonka: 6.2.4 260 - devDependencies: 261 - graphql: 16.6.0 262 265 263 266 packages/introspection: 264 267 specifiers: ··· 467 470 vue: 3.2.47 468 471 469 472 packages: 473 + 474 + /@0no-co/graphql.web/1.0.0: 475 + resolution: {integrity: sha512-JBq2pWyDchE1vVjj/+c4dzZ8stbpew4RrzpZ3vYdn1WJFGHfYg6YIX1fDdMKtSXJJM9FUlsoDOxemr9WMM2p+A==} 476 + peerDependencies: 477 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 478 + peerDependenciesMeta: 479 + graphql: 480 + optional: true 481 + dev: false 482 + 483 + /@0no-co/graphql.web/1.0.0_graphql@16.6.0: 484 + resolution: {integrity: sha512-JBq2pWyDchE1vVjj/+c4dzZ8stbpew4RrzpZ3vYdn1WJFGHfYg6YIX1fDdMKtSXJJM9FUlsoDOxemr9WMM2p+A==} 485 + peerDependencies: 486 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 487 + peerDependenciesMeta: 488 + graphql: 489 + optional: true 490 + dependencies: 491 + graphql: 16.6.0 470 492 471 493 /@actions/artifact/1.1.1: 472 494 resolution: {integrity: sha512-Vv4y0EW0ptEkU+Pjs5RGS/0EryTvI6s79LjSV9Gg/h+O3H/ddpjhuX/Bi/HZE4pbNPyjGtQjbdFWphkZhmgabA==} ··· 7889 7911 /graphql/16.6.0: 7890 7912 resolution: {integrity: sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==} 7891 7913 engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} 7892 - dev: true 7893 7914 7894 7915 /gud/1.0.0: 7895 7916 resolution: {integrity: sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==}
+4 -1
scripts/rollup/cleanup-plugin.mjs
··· 24 24 25 25 function cleanup() { 26 26 const emptyImportRe = /import\s+(?:'[^']+'|"[^"]+")\s*;?/g; 27 + const gqlImportRe = /(import\s+(?:[*\s{}\w\d]+)\s*from\s*'graphql';?)/g; 27 28 const jsFilter = createFilter(/.m?js$/, null, { resolve: false }); 28 29 const dtsFilter = createFilter(/\.d\.ts(\.map)?$/, null, { resolve: false }); 29 30 ··· 37 38 babelrc: false 38 39 }); 39 40 } else if (dtsFilter(chunk.fileName)) { 40 - return code.replace(emptyImportRe, ''); 41 + return code 42 + .replace(emptyImportRe, '') 43 + .replace(gqlImportRe, x => '/*!@ts-ignore*/\n' + x); 41 44 } 42 45 }, 43 46 };