diff --git a/.api-reports/api-report-cache.md b/.api-reports/api-report-cache.md index 0af8cb6cff1..b31968f747e 100644 --- a/.api-reports/api-report-cache.md +++ b/.api-reports/api-report-cache.md @@ -75,6 +75,13 @@ export type ApolloReducerConfig = { addTypename?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) type BroadcastOptions = Pick, "optimistic" | "onWatchUpdated">; @@ -872,8 +879,10 @@ export interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; diff --git a/.api-reports/api-report-core.md b/.api-reports/api-report-core.md index d9772093c3a..fd7fcc664d7 100644 --- a/.api-reports/api-report-core.md +++ b/.api-reports/api-report-core.md @@ -271,6 +271,13 @@ export type ApolloReducerConfig = { addTypename?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) interface Body_2 { // (undocumented) @@ -2005,8 +2012,10 @@ export interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; diff --git a/.api-reports/api-report-react.md b/.api-reports/api-report-react.md index 50bdee23220..0e1e91c88b5 100644 --- a/.api-reports/api-report-react.md +++ b/.api-reports/api-report-react.md @@ -337,6 +337,13 @@ type ApolloQueryResult = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // Warning: (ae-forgotten-export) The symbol "WatchQueryFetchPolicy" needs to be exported by the entry point index.d.ts // // @public (undocumented) @@ -1849,8 +1856,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2092,11 +2101,17 @@ export function useQuery(rv: ReactiveVar): T; // @public (undocumented) -export function useReadQuery(queryRef: QueryReference): { +export function useReadQuery(queryRef: QueryReference): UseReadQueryResult; + +// @public (undocumented) +export interface UseReadQueryResult { + // (undocumented) data: TData; - networkStatus: NetworkStatus; + // (undocumented) error: ApolloError | undefined; -}; + // (undocumented) + networkStatus: NetworkStatus; +} // @public (undocumented) export function useSubscription(subscription: DocumentNode | TypedDocumentNode, options?: SubscriptionHookOptions, NoInfer>): SubscriptionResult; @@ -2184,11 +2199,11 @@ interface WatchQueryOptions = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) interface BaseMutationOptions = ApolloCache> extends Omit, "mutation"> { // Warning: (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts @@ -1584,8 +1591,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1722,11 +1731,11 @@ interface WatchQueryOptions = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) interface BaseQueryOptions extends Omit, "query"> { // (undocumented) @@ -1519,8 +1526,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1620,11 +1629,11 @@ interface WatchQueryOptions = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) interface BaseMutationOptions = ApolloCache> extends Omit, "mutation"> { // Warning: (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts @@ -1540,8 +1547,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1664,11 +1673,11 @@ export function withSubscription = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // Warning: (ae-forgotten-export) The symbol "WatchQueryFetchPolicy" needs to be exported by the entry point index.d.ts // // @public (undocumented) @@ -1742,8 +1749,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1979,11 +1988,17 @@ export function useQuery(rv: ReactiveVar): T; // @public (undocumented) -export function useReadQuery(queryRef: QueryReference): { +export function useReadQuery(queryRef: QueryReference): UseReadQueryResult; + +// @public (undocumented) +export interface UseReadQueryResult { + // (undocumented) data: TData; - networkStatus: NetworkStatus; + // (undocumented) error: ApolloError | undefined; -}; + // (undocumented) + networkStatus: NetworkStatus; +} // Warning: (ae-forgotten-export) The symbol "SubscriptionHookOptions" needs to be exported by the entry point index.d.ts // @@ -2075,11 +2090,11 @@ interface WatchQueryOptions = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) interface BaseQueryOptions extends Omit, "query"> { // Warning: (ae-forgotten-export) The symbol "ApolloClient" needs to be exported by the entry point index.d.ts @@ -1506,8 +1513,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1607,11 +1616,11 @@ interface WatchQueryOptions = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) namespace Cache_2 { // (undocumented) @@ -861,6 +868,8 @@ export interface MockedProviderProps { childProps?: object; // (undocumented) children?: any; + // (undocumented) + connectToDevTools?: boolean; // Warning: (ae-forgotten-export) The symbol "DefaultOptions" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -1542,8 +1551,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1664,11 +1675,11 @@ export function withWarningSpy(it: (...args: TArgs // Warnings were encountered during analysis: // // src/cache/core/types/DataProxy.ts:141:5 - (ae-forgotten-export) The symbol "MissingFieldError" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:95:3 - (ae-forgotten-export) The symbol "ReadFieldFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:96:3 - (ae-forgotten-export) The symbol "CanReadFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:97:3 - (ae-forgotten-export) The symbol "isReference" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:98:3 - (ae-forgotten-export) The symbol "ToReferenceFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:99:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:96:3 - (ae-forgotten-export) The symbol "ReadFieldFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:97:3 - (ae-forgotten-export) The symbol "CanReadFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:98:3 - (ae-forgotten-export) The symbol "isReference" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:99:3 - (ae-forgotten-export) The symbol "ToReferenceFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:100:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts // src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts // src/core/LocalState.ts:46:5 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts // src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index 20d5192c592..8f7dd41a516 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -297,6 +297,13 @@ type ApolloQueryResult = { partial?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) namespace Cache_2 { // (undocumented) @@ -1500,8 +1507,10 @@ interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -1622,11 +1631,11 @@ export function withWarningSpy(it: (...args: TArgs // Warnings were encountered during analysis: // // src/cache/core/types/DataProxy.ts:141:5 - (ae-forgotten-export) The symbol "MissingFieldError" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:95:3 - (ae-forgotten-export) The symbol "ReadFieldFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:96:3 - (ae-forgotten-export) The symbol "CanReadFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:97:3 - (ae-forgotten-export) The symbol "isReference" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:98:3 - (ae-forgotten-export) The symbol "ToReferenceFunction" needs to be exported by the entry point index.d.ts -// src/cache/core/types/common.ts:99:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:96:3 - (ae-forgotten-export) The symbol "ReadFieldFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:97:3 - (ae-forgotten-export) The symbol "CanReadFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:98:3 - (ae-forgotten-export) The symbol "isReference" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:99:3 - (ae-forgotten-export) The symbol "ToReferenceFunction" needs to be exported by the entry point index.d.ts +// src/cache/core/types/common.ts:100:3 - (ae-forgotten-export) The symbol "StorageType" needs to be exported by the entry point index.d.ts // src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts // src/core/LocalState.ts:46:5 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts // src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-utilities.md b/.api-reports/api-report-utilities.md index 01b618e5d27..b3815818dfa 100644 --- a/.api-reports/api-report-utilities.md +++ b/.api-reports/api-report-utilities.md @@ -329,6 +329,13 @@ type ApolloReducerConfig = { // @public (undocumented) export function argumentsObjectFromField(field: FieldNode | DirectiveNode, variables?: Record): Object | null; +// @public (undocumented) +export type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) export function asyncMap(observable: Observable, mapFn: (value: V) => R | PromiseLike, catchFn?: (error: any) => R | PromiseLike): Observable; @@ -2299,7 +2306,7 @@ export interface StoreObject { } // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2520,7 +2527,7 @@ interface WriteContext extends ReadMergeModifyContext { // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:205:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts -// src/utilities/graphql/storeUtils.ts:208:12 - (ae-forgotten-export) The symbol "storeKeyNameStringify" needs to be exported by the entry point index.d.ts +// src/utilities/graphql/storeUtils.ts:226:12 - (ae-forgotten-export) The symbol "storeKeyNameStringify" needs to be exported by the entry point index.d.ts // src/utilities/policies/pagination.ts:76:3 - (ae-forgotten-export) The symbol "TRelayEdge" needs to be exported by the entry point index.d.ts // src/utilities/policies/pagination.ts:77:3 - (ae-forgotten-export) The symbol "TRelayPageInfo" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index e4423fa340e..caf740c5e7a 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -310,6 +310,13 @@ export type ApolloReducerConfig = { addTypename?: boolean; }; +// @public (undocumented) +type AsStoreObject = { + [K in keyof T]: T[K]; +}; + // @public (undocumented) export type BackgroundQueryHookFetchPolicy = Extract; @@ -2452,8 +2459,10 @@ export interface StoreObject { __typename?: string; } +// Warning: (ae-forgotten-export) The symbol "AsStoreObject" needs to be exported by the entry point index.d.ts +// // @public (undocumented) -type StoreObjectValueMaybeReference = StoreVal extends Record[] ? Readonly | readonly Reference[] : StoreVal extends Record ? StoreVal | Reference : StoreVal; +type StoreObjectValueMaybeReference = StoreVal extends Array> ? ReadonlyArray | Reference> : StoreVal extends Record ? AsStoreObject | Reference : StoreVal; // @public (undocumented) export type StoreValue = number | string | string[] | Reference | Reference[] | null | undefined | void | Object; @@ -2733,11 +2742,17 @@ export function useQuery(rv: ReactiveVar): T; // @public (undocumented) -export function useReadQuery(queryRef: QueryReference): { +export function useReadQuery(queryRef: QueryReference): UseReadQueryResult; + +// @public (undocumented) +export interface UseReadQueryResult { + // (undocumented) data: TData; - networkStatus: NetworkStatus; + // (undocumented) error: ApolloError | undefined; -}; + // (undocumented) + networkStatus: NetworkStatus; +} // @public (undocumented) export function useSubscription(subscription: DocumentNode | TypedDocumentNode, options?: SubscriptionHookOptions, NoInfer>): SubscriptionResult; diff --git a/.changeset/good-experts-repair.md b/.changeset/good-experts-repair.md new file mode 100644 index 00000000000..37aef92f934 --- /dev/null +++ b/.changeset/good-experts-repair.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Add an explicit return type for the `useReadQuery` hook called `UseReadQueryResult`. Previously the return type of this hook was inferred from the return value. diff --git a/.circleci/config.yml b/.circleci/config.yml index 65d5c98dda7..03f4684e528 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,8 @@ version: 2.1 +orbs: + secops: apollo/circleci-secops-orb@2.0.0 + jobs: # Filesize: # docker: @@ -12,7 +15,7 @@ jobs: Lint: docker: - - image: cimg/node:20.6.1 + - image: cimg/node:20.8.0 steps: - checkout - run: npm version @@ -21,7 +24,7 @@ jobs: Formatting: docker: - - image: cimg/node:20.6.1 + - image: cimg/node:20.8.0 steps: - checkout - run: npm ci @@ -29,7 +32,7 @@ jobs: Tests: docker: - - image: cimg/node:20.6.1 + - image: cimg/node:20.8.0 steps: - checkout - run: npm run ci:precheck @@ -47,7 +50,7 @@ jobs: BuildTarball: docker: - - image: cimg/node:20.6.1 + - image: cimg/node:20.8.0 steps: - checkout - run: npm run ci:precheck @@ -64,7 +67,7 @@ jobs: framework: type: string docker: - - image: cimg/node:20.6.1 + - image: cimg/node:20.8.0 steps: - checkout - attach_workspace: @@ -141,3 +144,12 @@ workflows: - "@types/react@17 @types/react-dom@17" - "@types/react@18 @types/react-dom@18" - "typescript@next" + security-scans: + jobs: + - secops/gitleaks: + context: + - platform-docker-ro + - github-orb + - secops-oidc + git-base-revision: <<#pipeline.git.base_revision>><><> + git-revision: << pipeline.git.revision >> diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 1f0e8939cc2..d2e1bc647dc 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -13,7 +13,7 @@ body: - type: input attributes: label: Link to Reproduction - description: "A link with runnable reproduction. For web projects, you can fork our `react-apollo-error-template` to create one via [GitHub repository](https://github.com/apollographql/react-apollo-error-template) or [CodeSandbox](https://codesandbox.io/s/github/apollographql/react-apollo-error-template). For React Native projects, you can fork our `rn-apollo-client-testbed` via [GitHub respository](https://github.com/apollographql/rn-apollo-client-testbed). Make sure this includes everything necessary (`package.json`, `tsconfig.json`, etc.) so we don't have to guess anything! If a minimal reproduction can't be created, please share a [Replay](https://docs.replay.io/workflows/recording-bug-reports) of the bug (note: you don't have to grant Replay access to a private repo to create a recording, but it will contain source maps for your JavaScript code)." + description: "A link with runnable reproduction. For web projects, you can fork our `react-apollo-error-template` to create one via [GitHub repository](https://github.com/apollographql/react-apollo-error-template) or [CodeSandbox](https://codesandbox.io/s/github/apollographql/react-apollo-error-template). For React Native projects, you can fork our `rn-apollo-client-testbed` via [GitHub respository](https://github.com/apollographql/rn-apollo-client-testbed). Make sure this includes everything necessary (`package.json`, `tsconfig.json`, etc.) so we don't have to guess anything! If a minimal reproduction can't be created, please share a [Replay](https://docs.replay.io/workflows/recording-bug-reports) of the bug (note: you don't have to grant Replay access to a private repo to create a recording, but it will contain source maps for your JavaScript code). Feel free to ask for an email address to send Replays to if they contain sensitive information." validations: required: true - type: textarea diff --git a/.github/workflows/exit-prerelease.yml b/.github/workflows/exit-prerelease.yml index 8d350e43252..67f6c41bb43 100644 --- a/.github/workflows/exit-prerelease.yml +++ b/.github/workflows/exit-prerelease.yml @@ -52,7 +52,7 @@ jobs: - name: Remove pre.json run: npx rimraf .changeset/pre.json - - uses: stefanzweifel/git-auto-commit-action@v4 + - uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Exit prerelease mode # Commit these changes to the branch workflow is running against diff --git a/CHANGELOG.md b/CHANGELOG.md index c91f9b1dbb7..8a3c2bcc7ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,20 @@ Adds support for a new property `MockedResponse.variableMatcher`: a predicate function that accepts a `variables` param. If `true`, the `variables` will be passed into the `ResultFunction` to help dynamically build a response. +## 3.8.6 + +### Patch Changes + +- [#11291](https://github.com/apollographql/apollo-client/pull/11291) [`2be7eafe3`](https://github.com/apollographql/apollo-client/commit/2be7eafe3c115d56d993dbda64d320550712df1f) Thanks [@ArioA](https://github.com/ArioA)! - Fix a bug that allows to only call `loadErrorMessages` without also calling `loadDevErrorMessages`. + +- [#11274](https://github.com/apollographql/apollo-client/pull/11274) [`b29f000f3`](https://github.com/apollographql/apollo-client/commit/b29f000f36f281e256809b5454eaeca2ec4450bf) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Start the query ref auto dispose timeout after the initial promise has settled. This prevents requests that run longer than the timeout duration from keeping the component suspended indefinitely. + +- [#11289](https://github.com/apollographql/apollo-client/pull/11289) [`b5894dbf0`](https://github.com/apollographql/apollo-client/commit/b5894dbf0fd5ea5ef1ff20dd896a658ef78c69dc) Thanks [@phryneas](https://github.com/phryneas)! - `MockedProvider`: default `connectToDevTools` to `false` in created `ApolloClient` instance. + + This will prevent the mocked `ApolloClient` instance from trying to connect to the DevTools, which would start a `setTimeout` that might keep running after a test has finished. + +- [#11206](https://github.com/apollographql/apollo-client/pull/11206) [`dd2ce7687`](https://github.com/apollographql/apollo-client/commit/dd2ce7687ae9afa399e950a523fc7330284c25fe) Thanks [@phryneas](https://github.com/phryneas)! - `cache.modify`: Less strict types & new dev runtime warnings. + ## 3.8.5 ### Patch Changes diff --git a/docs/shared/mutation-result.mdx b/docs/shared/mutation-result.mdx index 3feb6b1cc50..21e4e858137 100644 --- a/docs/shared/mutation-result.mdx +++ b/docs/shared/mutation-result.mdx @@ -27,6 +27,7 @@ A function to trigger the mutation from your UI. You can optionally pass this fu * `onError` * `optimisticResponse` * `refetchQueries` +* `onQueryUpdated` * `update` * `variables` * `client` diff --git a/docs/source/development-testing/testing.mdx b/docs/source/development-testing/testing.mdx index 78402c3f021..d32222cb6ab 100644 --- a/docs/source/development-testing/testing.mdx +++ b/docs/source/development-testing/testing.mdx @@ -240,6 +240,9 @@ We can use the asynchronous `screen.findByText` method to query the DOM elements ```jsx it("should render dog", async () => { const dogMock = { + delay: 30 // to prevent React from batching the loading state away + // delay: Infinity // if you only want to test the loading state + request: { query: GET_DOG_QUERY, variables: { name: "Buck" } diff --git a/package-lock.json b/package-lock.json index 0d656a76bf1..fa6958d2fef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,12 +25,12 @@ "zen-observable-ts": "^1.2.5" }, "devDependencies": { - "@arethetypeswrong/cli": "0.11.0", + "@arethetypeswrong/cli": "0.12.2", "@babel/parser": "7.23.0", "@changesets/changelog-github": "0.4.8", "@changesets/cli": "2.26.2", "@graphql-tools/schema": "10.0.0", - "@microsoft/api-extractor": "7.37.0", + "@microsoft/api-extractor": "7.38.0", "@rollup/plugin-node-resolve": "11.2.1", "@size-limit/esbuild-why": "8.2.6", "@size-limit/preset-small-lib": "8.2.6", @@ -42,33 +42,33 @@ "@types/bytes": "3.1.2", "@types/fetch-mock": "7.3.6", "@types/glob": "8.1.0", - "@types/hoist-non-react-statics": "3.3.2", + "@types/hoist-non-react-statics": "3.3.3", "@types/jest": "29.5.5", - "@types/lodash": "4.14.198", - "@types/node": "20.8.0", - "@types/node-fetch": "2.6.5", - "@types/react": "18.2.22", - "@types/react-dom": "18.2.7", + "@types/lodash": "4.14.199", + "@types/node": "20.8.6", + "@types/node-fetch": "2.6.6", + "@types/react": "18.2.28", + "@types/react-dom": "18.2.13", "@types/use-sync-external-store": "0.0.4", - "@typescript-eslint/eslint-plugin": "6.7.2", - "@typescript-eslint/parser": "6.7.2", - "@typescript-eslint/rule-tester": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/eslint-plugin": "6.7.5", + "@typescript-eslint/parser": "6.7.5", + "@typescript-eslint/rule-tester": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "acorn": "8.10.0", "blob-polyfill": "7.0.20220408", "bytes": "3.1.2", "cross-fetch": "3.1.8", - "eslint": "8.50.0", - "eslint-import-resolver-typescript": "3.6.0", + "eslint": "8.51.0", + "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-import": "npm:@phryneas/eslint-plugin-import@2.27.5-pr.2813.2817.199971c", "eslint-plugin-local-rules": "2.0.0", "eslint-plugin-testing-library": "5.11.1", - "expect-type": "0.16.0", + "expect-type": "0.17.3", "fetch-mock": "9.11.0", "glob": "8.1.0", "graphql": "16.8.1", - "graphql-ws": "5.14.0", + "graphql-ws": "5.14.1", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "jest-junit": "16.0.0", @@ -81,14 +81,14 @@ "react-dom-17": "npm:react-dom@^17", "react-error-boundary": "3.1.4", "recast": "0.23.4", - "resolve": "1.22.6", - "rimraf": "5.0.1", + "resolve": "1.22.8", + "rimraf": "5.0.5", "rollup": "2.79.1", "rollup-plugin-terser": "7.0.2", "rxjs": "7.8.1", "size-limit": "8.2.6", "subscriptions-transport-ws": "0.11.0", - "terser": "5.20.0", + "terser": "5.21.0", "ts-api-utils": "1.0.3", "ts-jest": "29.1.1", "ts-jest-resolver": "2.0.1", @@ -140,18 +140,18 @@ "dev": true }, "node_modules/@andrewbranch/untar.js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.2.tgz", - "integrity": "sha512-hL80MHK3b++pEp6K23+Nl5r5D1F19DRagp2ruCBIv4McyCiLKq67vUNvEQY1aGCAKNZ8GxV23n5MhOm7RwO8Pg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", "dev": true }, "node_modules/@arethetypeswrong/cli": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.11.0.tgz", - "integrity": "sha512-0GxlV58x8DaiWRUx0JWc3glr8iGsjK+KATuubH8qRqjw4aIGB8BBQ8Bv2Bvs9DfGuojBgbVWhOTe8+3BepYZ6Q==", + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.12.2.tgz", + "integrity": "sha512-SE4Rqy8LM8zgRLeVXZqFIOg4w4TCDG2AMguuZDDRcrUmVQj7phW0tWJnKwsZtyJ6SdqXTIzWvGYiUJiHg2hb9w==", "dev": true, "dependencies": { - "@arethetypeswrong/core": "0.10.2", + "@arethetypeswrong/core": "0.12.2", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", @@ -201,12 +201,12 @@ } }, "node_modules/@arethetypeswrong/core": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.10.2.tgz", - "integrity": "sha512-jL1MPpZKuMkm0EbZn1OLgdTO5hci7g79EUSELEnATdFyTgbPUxJwTXi1Kdont/BG05BZCcxZnOQgYO/whVmwdA==", + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.12.2.tgz", + "integrity": "sha512-ez/quGfC6RVg7VrwCgMVreJ01jbkfJQRNxOG7Bpl4YGcPRs45ZE1AzpHiIdzqfwFg9EBVSaewaffrsK5MVbALw==", "dev": true, "dependencies": { - "@andrewbranch/untar.js": "^1.0.0", + "@andrewbranch/untar.js": "^1.0.3", "fetch-ponyfill": "^7.1.0", "fflate": "^0.7.4", "semver": "^7.5.4", @@ -1400,9 +1400,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2111,17 +2111,17 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.37.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.37.0.tgz", - "integrity": "sha512-df/wffWpDhYRw7kzdxeHGsCpim+dC8aFiZlsJb4uFvVPWhBZpDzOhQxSUTFx3Df1ORY+/JjuPR3fDE9Hq+PHzQ==", + "version": "7.38.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.0.tgz", + "integrity": "sha512-e1LhZYnfw+JEebuY2bzhw0imDCl1nwjSThTrQqBXl40hrVo6xm3j/1EpUr89QyzgjqmAwek2ZkIVZbrhaR+cqg==", "dev": true, "dependencies": { - "@microsoft/api-extractor-model": "7.28.0", + "@microsoft/api-extractor-model": "7.28.2", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0", - "@rushstack/rig-package": "0.5.0", - "@rushstack/ts-command-line": "4.16.0", + "@rushstack/node-core-library": "3.61.0", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.16.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -2134,14 +2134,14 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.0.tgz", - "integrity": "sha512-QIMtUVm1tqiKG+M6ciFgRShcDoovyltaeg+CbyOnyr7SMrp6gg0ojK5/nToMqR9kAvsTS4QVgW4Twl50EoAjcw==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.2.tgz", + "integrity": "sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==", "dev": true, "dependencies": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.60.0" + "@rushstack/node-core-library": "3.61.0" } }, "node_modules/@microsoft/api-extractor/node_modules/semver": { @@ -2292,9 +2292,9 @@ "dev": true }, "node_modules/@rushstack/node-core-library": { - "version": "3.60.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.60.0.tgz", - "integrity": "sha512-PcyrqhILvzU+65wMFybQ2VeGNnU5JzhDq2OvUi3j6jPUxyllM7b2hrRUwCuVaYboewYzIbpzXFzgxe2K7ii1nw==", + "version": "3.61.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", + "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==", "dev": true, "dependencies": { "colors": "~1.2.1", @@ -2330,9 +2330,9 @@ } }, "node_modules/@rushstack/rig-package": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.0.tgz", - "integrity": "sha512-bGnOW4DWHOePDiABKy6qyqYJl9i7fKn4bRucExRVt5QzyPxuVHMl8CMmCabtoNSpXzgG3qymWOrMoa/W2PpJrw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", "dev": true, "dependencies": { "resolve": "~1.22.1", @@ -2340,9 +2340,9 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "4.16.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.0.tgz", - "integrity": "sha512-WJKhdR9ThK9Iy7t78O3at7I3X4Ssp5RRZay/IQa8NywqkFy/DQbT3iLouodMMdUwLZD9n8n++xLubVd3dkmpkg==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.16.1.tgz", + "integrity": "sha512-+OCsD553GYVLEmz12yiFjMOzuPeCiZ3f8wTiFHL30ZVXexTyPmgjwXEhg2K2P0a2lVf+8YBy7WtPoflB2Fp8/A==", "dev": true, "dependencies": { "@types/argparse": "1.0.38", @@ -2774,9 +2774,9 @@ } }, "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.3.tgz", + "integrity": "sha512-Wny3a2UXn5FEA1l7gc6BbpoV5mD1XijZqgkp4TRgDCDL5r3B5ieOFGUX5h3n78Tr1MEG7BfvoM8qeztdvNU0fw==", "dev": true, "dependencies": { "@types/react": "*", @@ -2882,9 +2882,9 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", + "version": "4.14.199", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", + "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==", "dev": true }, "node_modules/@types/minimatch": { @@ -2900,15 +2900,18 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", - "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==", - "dev": true + "version": "20.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz", + "integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@types/node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-OZsUlr2nxvkqUFLSaY2ZbA+P1q22q+KrlxWOn/38RX+u5kTkYL2mTujEpzUhGkS+K/QCYp9oagfXG39XOzyySg==", + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw==", "dev": true, "dependencies": { "@types/node": "*", @@ -2928,9 +2931,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.22", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.22.tgz", - "integrity": "sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==", + "version": "18.2.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.28.tgz", + "integrity": "sha512-ad4aa/RaaJS3hyGz0BGegdnSRXQBkd1CCYDCdNjBPg90UUpLgo+WlJqb9fMYUxtehmzF3PJaTWqRZjko6BRzBg==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -2939,9 +2942,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.13.tgz", + "integrity": "sha512-eJIUv7rPP+EC45uNYp/ThhSpE16k22VJUknt5OLoH9tbXoi8bMhwLf5xRuWMywamNbWzhrSmU7IBJfPup1+3fw==", "dev": true, "dependencies": { "@types/react": "*" @@ -3011,16 +3014,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.2.tgz", - "integrity": "sha512-ooaHxlmSgZTM6CHYAFRlifqh1OAr3PAQEwi7lhYhaegbnXrnh7CDcHmc3+ihhbQC7H0i4JF0psI5ehzkF6Yl6Q==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", + "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/type-utils": "6.7.2", - "@typescript-eslint/utils": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/type-utils": "6.7.5", + "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -3061,15 +3064,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.2.tgz", - "integrity": "sha512-KA3E4ox0ws+SPyxQf9iSI25R6b4Ne78ORhNHeVKrPQnoYsb9UhieoiRoJgrzgEeKGOXhcY1i8YtOeCHHTDa6Fw==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", + "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4" }, "engines": { @@ -3089,13 +3092,13 @@ } }, "node_modules/@typescript-eslint/rule-tester": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-6.7.2.tgz", - "integrity": "sha512-jhnGel3v8annJcmubTA0rzNw5xwDhQDXGqRp57OJ8uUXYcfdrom/326R0lNLWLBvBp+UXrcsZBi6ybj+jlp7Vw==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/rule-tester/-/rule-tester-6.7.5.tgz", + "integrity": "sha512-rDUQDkMg577jA7U+2NFlgLv3S43epbjruLZ4MQaELhH+WZLmmGylFbcCWeonRmtFjF2Xd/lfYsjqQ+p61XZDkw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "ajv": "^6.10.0", "lodash.merge": "4.6.2", "semver": "^7.5.4" @@ -3128,13 +3131,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.2.tgz", - "integrity": "sha512-bgi6plgyZjEqapr7u2mhxGR6E8WCzKNUFWNh6fkpVe9+yzRZeYtDTbsIBzKbcxI+r1qVWt6VIoMSNZ4r2A+6Yw==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2" + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -3145,13 +3148,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.2.tgz", - "integrity": "sha512-36F4fOYIROYRl0qj95dYKx6kybddLtsbmPIYNK0OBeXv2j9L5nZ17j9jmfy+bIDHKQgn2EZX+cofsqi8NPATBQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", + "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -3172,9 +3175,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.2.tgz", - "integrity": "sha512-flJYwMYgnUNDAN9/GAI3l8+wTmvTYdv64fcH8aoJK76Y+1FCZ08RtI5zDerM/FYT5DMkAc+19E4aLmd5KqdFyg==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -3185,13 +3188,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.2.tgz", - "integrity": "sha512-kiJKVMLkoSciGyFU0TOY0fRxnp9qq1AzVOHNeN1+B9erKFCJ4Z8WdjAkKQPP+b1pWStGFqezMLltxO+308dJTQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/visitor-keys": "6.7.2", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3227,17 +3230,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.2.tgz", - "integrity": "sha512-ZCcBJug/TS6fXRTsoTkgnsvyWSiXwMNiPzBUani7hDidBdj1779qwM1FIAmpH4lvlOZNF3EScsxxuGifjpLSWQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", + "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/typescript-estree": "6.7.2", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", "semver": "^7.5.4" }, "engines": { @@ -3267,12 +3270,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.2.tgz", - "integrity": "sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.2", + "@typescript-eslint/types": "6.7.5", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4901,15 +4904,15 @@ } }, "node_modules/eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", + "@eslint/js": "8.51.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4975,9 +4978,9 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.0.tgz", - "integrity": "sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -5312,9 +5315,9 @@ } }, "node_modules/eslint/node_modules/globals": { - "version": "13.22.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", - "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5579,9 +5582,9 @@ } }, "node_modules/expect-type": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-0.16.0.tgz", - "integrity": "sha512-wCpFeVBiAPGiYkQZzaqvGuuBnNCHbtnowMOBpBGY8a27XbG8VAit3lklWph1r8VmgsH61mOZqI3NuGm8bZnUlw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-0.17.3.tgz", + "integrity": "sha512-K0ZdZJ97jiAtaOwhEHHz/f0N6Xbj5reRz5g6+5BO7+OvqQ7PMQz0/c8bFSJs1zPotNJL5HJaC6t6lGPEAtGyOw==", "dev": true, "engines": { "node": ">=12.0.0" @@ -6169,9 +6172,9 @@ } }, "node_modules/graphql-ws": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.0.tgz", - "integrity": "sha512-itrUTQZP/TgswR4GSSYuwWUzrE/w5GhbwM2GX3ic2U7aw33jgEsayfIlvaj7/GcIvZgNMzsPTrE5hqPuFUiE5g==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.14.1.tgz", + "integrity": "sha512-aqkls1espsygP1PfkAuuLIV96IbztQ6EaADse97pw8wRIMT3+AL/OYfS8V2iCRkc0gzckitoDRGCQEdnySggiA==", "dev": true, "engines": { "node": ">=10" @@ -6952,9 +6955,9 @@ "dev": true }, "node_modules/jackspeak": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -9216,13 +9219,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -9803,9 +9806,9 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -9877,15 +9880,15 @@ } }, "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^10.2.5" + "glob": "^10.3.7" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { "node": ">=14" @@ -9904,19 +9907,19 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz", - "integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.0", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -9926,9 +9929,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10695,9 +10698,9 @@ } }, "node_modules/terser": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.20.0.tgz", - "integrity": "sha512-e56ETryaQDyebBwJIWYB2TT6f2EZ0fL0sW/JRXNMN26zZdKi2u/E/5my5lG6jNxym6qsrVXfFRmOdV42zlAgLQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -11170,6 +11173,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/package.json b/package.json index b8cefcee3b9..057e250d569 100644 --- a/package.json +++ b/package.json @@ -103,12 +103,12 @@ "zen-observable-ts": "^1.2.5" }, "devDependencies": { - "@arethetypeswrong/cli": "0.11.0", + "@arethetypeswrong/cli": "0.12.2", "@babel/parser": "7.23.0", "@changesets/changelog-github": "0.4.8", "@changesets/cli": "2.26.2", "@graphql-tools/schema": "10.0.0", - "@microsoft/api-extractor": "7.37.0", + "@microsoft/api-extractor": "7.38.0", "@rollup/plugin-node-resolve": "11.2.1", "@size-limit/esbuild-why": "8.2.6", "@size-limit/preset-small-lib": "8.2.6", @@ -120,33 +120,33 @@ "@types/bytes": "3.1.2", "@types/fetch-mock": "7.3.6", "@types/glob": "8.1.0", - "@types/hoist-non-react-statics": "3.3.2", + "@types/hoist-non-react-statics": "3.3.3", "@types/jest": "29.5.5", - "@types/lodash": "4.14.198", - "@types/node": "20.8.0", - "@types/node-fetch": "2.6.5", - "@types/react": "18.2.22", - "@types/react-dom": "18.2.7", + "@types/lodash": "4.14.199", + "@types/node": "20.8.6", + "@types/node-fetch": "2.6.6", + "@types/react": "18.2.28", + "@types/react-dom": "18.2.13", "@types/use-sync-external-store": "0.0.4", - "@typescript-eslint/eslint-plugin": "6.7.2", - "@typescript-eslint/parser": "6.7.2", - "@typescript-eslint/rule-tester": "6.7.2", - "@typescript-eslint/types": "6.7.2", - "@typescript-eslint/utils": "6.7.2", + "@typescript-eslint/eslint-plugin": "6.7.5", + "@typescript-eslint/parser": "6.7.5", + "@typescript-eslint/rule-tester": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "acorn": "8.10.0", "blob-polyfill": "7.0.20220408", "bytes": "3.1.2", "cross-fetch": "3.1.8", - "eslint": "8.50.0", - "eslint-import-resolver-typescript": "3.6.0", + "eslint": "8.51.0", + "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-import": "npm:@phryneas/eslint-plugin-import@2.27.5-pr.2813.2817.199971c", "eslint-plugin-local-rules": "2.0.0", "eslint-plugin-testing-library": "5.11.1", - "expect-type": "0.16.0", + "expect-type": "0.17.3", "fetch-mock": "9.11.0", "glob": "8.1.0", "graphql": "16.8.1", - "graphql-ws": "5.14.0", + "graphql-ws": "5.14.1", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "jest-junit": "16.0.0", @@ -159,14 +159,14 @@ "react-dom-17": "npm:react-dom@^17", "react-error-boundary": "3.1.4", "recast": "0.23.4", - "resolve": "1.22.6", - "rimraf": "5.0.1", + "resolve": "1.22.8", + "rimraf": "5.0.5", "rollup": "2.79.1", "rollup-plugin-terser": "7.0.2", "rxjs": "7.8.1", "size-limit": "8.2.6", "subscriptions-transport-ws": "0.11.0", - "terser": "5.20.0", + "terser": "5.21.0", "ts-api-utils": "1.0.3", "ts-jest": "29.1.1", "ts-jest-resolver": "2.0.1", diff --git a/renovate.json b/renovate.json index 9264bc08977..ac7f81ee4b8 100644 --- a/renovate.json +++ b/renovate.json @@ -33,6 +33,7 @@ "react-dom-17", "@testing-library/react-12", "@rollup/plugin-node-resolve", - "rollup" + "rollup", + "glob" ] } diff --git a/src/cache/core/__tests__/cache.ts b/src/cache/core/__tests__/cache.ts index f456695c7b5..6ca7e77e8b6 100644 --- a/src/cache/core/__tests__/cache.ts +++ b/src/cache/core/__tests__/cache.ts @@ -374,7 +374,7 @@ describe.skip("Cache type tests", () => { }, children(field) { expectTypeOf(field).toEqualTypeOf< - ReadonlyArray<{ anotherObject: false }> | ReadonlyArray + ReadonlyArray<{ anotherObject: false } | Reference> >(); return field; }, @@ -440,7 +440,7 @@ describe.skip("Cache type tests", () => { id: "foo", fields(field) { expectTypeOf(field).toEqualTypeOf< - boolean | symbol | readonly OtherChildEntry[] | readonly Reference[] + boolean | symbol | ReadonlyArray >(); return field; }, @@ -477,7 +477,7 @@ describe.skip("Cache type tests", () => { id: "foo", fields(field) { expectTypeOf(field).toEqualTypeOf< - boolean | symbol | readonly OtherChildEntry[] | readonly Reference[] + boolean | symbol | ReadonlyArray >(); return field; }, diff --git a/src/cache/core/types/common.ts b/src/cache/core/types/common.ts index 052844014a0..19200d4845e 100644 --- a/src/cache/core/types/common.ts +++ b/src/cache/core/types/common.ts @@ -5,6 +5,7 @@ import type { StoreObject, StoreValue, isReference, + AsStoreObject, } from "../../../utilities/index.js"; import type { StorageType } from "../../inmemory/policies.js"; @@ -104,13 +105,12 @@ export type Modifier = ( details: ModifierDetails ) => T | DeleteModifier | InvalidateModifier; -type StoreObjectValueMaybeReference = StoreVal extends Record< - string, - any ->[] - ? Readonly | readonly Reference[] +type StoreObjectValueMaybeReference = StoreVal extends Array< + infer Item extends Record +> + ? ReadonlyArray | Reference> : StoreVal extends Record - ? StoreVal | Reference + ? AsStoreObject | Reference : StoreVal; export type AllFieldsModifier> = Modifier< diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index 498936c1e31..a7289cd2c64 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -18,6 +18,7 @@ import { StoreReader } from "../readFromStore"; import { StoreWriter } from "../writeToStore"; import { ObjectCanon } from "../object-canon"; import { TypePolicies } from "../policies"; +import { spyOnConsole } from "../../../testing/internal"; disableFragmentWarnings(); @@ -3454,6 +3455,225 @@ describe("InMemoryCache#modify", () => { expect(cache.extract()).toEqual(snapshot); }); + + it("warns if `modify` returns a mixed array of objects and references", () => { + const cache = new InMemoryCache(); + const query = gql` + query { + me { + id + books { + id + title + } + } + } + `; + + interface Book { + __typename: "Book"; + id: string; + title: string; + } + + const book1: Book = { __typename: "Book", id: "1", title: "1984" }; + const book2: Book = { __typename: "Book", id: "2", title: "The Odyssey" }; + const book3: Book = { __typename: "Book", id: "3", title: "The Hobbit" }; + const book4: Book = { __typename: "Book", id: "4", title: "The Swarm" }; + + cache.writeQuery({ + query, + data: { + me: { + __typename: "User", + id: "42", + books: [book1, book2, book3], + }, + }, + }); + + expect(cache.readQuery({ query })).toEqual({ + me: { + __typename: "User", + books: [book1, book2, book3], + id: "42", + }, + }); + + { + using consoleSpy = spyOnConsole("warn"); + cache.modify<{ books: Book[] }>({ + id: cache.identify({ __typename: "User", id: "42" }), + fields: { + books(existingBooks, { toReference }) { + return [toReference(existingBooks[2])!, book4]; + }, + }, + }); + expect(consoleSpy.warn).toHaveBeenLastCalledWith( + "cache.modify: Writing an array with a mix of both References and Objects will not result in the Objects being normalized correctly.\n" + + "Please convert the object instance %o to a Reference before writing it to the cache by calling `toReference(object, true)`.", + book4 + ); + } + }); + + it("warns if `modify` returns a Reference that is not part of the store as part of an array", () => { + const cache = new InMemoryCache(); + const query = gql` + query { + me { + id + books { + id + title + } + } + } + `; + + type Book = { + __typename: "Book"; + id: string; + title: string; + }; + + const book1: Book = { __typename: "Book", id: "1", title: "1984" }; + const book2: Book = { __typename: "Book", id: "2", title: "The Odyssey" }; + const book3: Book = { __typename: "Book", id: "3", title: "The Hobbit" }; + const book4: Book = { __typename: "Book", id: "4", title: "The Swarm" }; + + cache.writeQuery({ + query, + data: { + me: { + __typename: "User", + id: "42", + books: [book1, book2, book3], + }, + }, + }); + + expect(cache.readQuery({ query })).toEqual({ + me: { + __typename: "User", + books: [book1, book2, book3], + id: "42", + }, + }); + + { + using consoleSpy = spyOnConsole("warn"); + cache.modify<{ books: Book[] }>({ + id: cache.identify({ __typename: "User", id: "42" }), + fields: { + books(existingBooks, { toReference }) { + return [...existingBooks, toReference(book4)!]; + }, + }, + }); + expect(consoleSpy.warn).toHaveBeenLastCalledWith( + "cache.modify: You are trying to write a Reference that is not part of the store: %o\n" + + "Please make sure to set the `mergeIntoStore` parameter to `true` when creating a Reference that is not part of the store yet:\n" + + "`toReference(object, true)`", + { __ref: "Book:4" } + ); + } + + // reading the cache *looks* good to the user + expect(cache.readQuery({ query })).toEqual({ + me: { + __typename: "User", + // this is what we're warning about - book 4 is not in the store + books: [book1, book2, book3], + id: "42", + }, + }); + expect(cache.extract()).toEqual({ + ROOT_QUERY: { __typename: "Query", me: { __ref: "User:42" } }, + "Book:1": book1, + "Book:2": book2, + "Book:3": book3, + // no Book:4 + "User:42": { + __typename: "User", + id: "42", + // Book:4 here is a dead ref + books: [ + { __ref: "Book:1" }, + { __ref: "Book:2" }, + { __ref: "Book:3" }, + { __ref: "Book:4" }, + ], + }, + }); + }); + + it("warns if `modify` returns a Reference that is not part of the store", () => { + const cache = new InMemoryCache(); + const query = gql` + query { + me { + id + } + } + `; + + type User = { + __typename: string; + id: string; + }; + + cache.writeQuery({ + query, + data: { + me: { + __typename: "User", + id: "42", + }, + }, + }); + + expect(cache.readQuery({ query })).toEqual({ + me: { + __typename: "User", + id: "42", + }, + }); + + { + using consoleSpy = spyOnConsole("warn"); + cache.modify<{ me: User }>({ + id: "ROOT_QUERY", + fields: { + me(existingUser, { toReference }) { + return toReference({ + __typename: "User", + id: "43", + })!; + }, + }, + }); + expect(consoleSpy.warn).toHaveBeenLastCalledWith( + "cache.modify: You are trying to write a Reference that is not part of the store: %o\n" + + "Please make sure to set the `mergeIntoStore` parameter to `true` when creating a Reference that is not part of the store yet:\n" + + "`toReference(object, true)`", + { __ref: "User:43" } + ); + } + + // reading the cache returns `null` + expect(cache.readQuery({ query })).toEqual(null); + expect(cache.extract()).toEqual({ + // User:43 is a dead ref + ROOT_QUERY: { __typename: "Query", me: { __ref: "User:43" } }, + "User:42": { + __typename: "User", + id: "42", + }, + // no User:43 + }); + }); }); describe("ReactiveVar and makeVar", () => { diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 024e694b220..ddb03b274da 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -257,6 +257,51 @@ export abstract class EntityStore implements NormalizedCache { changedFields[storeFieldName] = newValue; needToMerge = true; fieldValue = newValue; + + if (__DEV__) { + const checkReference = (ref: Reference) => { + if (this.lookup(ref.__ref) === undefined) { + invariant.warn( + "cache.modify: You are trying to write a Reference that is not part of the store: %o\n" + + "Please make sure to set the `mergeIntoStore` parameter to `true` when creating a Reference that is not part of the store yet:\n" + + "`toReference(object, true)`", + ref + ); + return true; + } + }; + if (isReference(newValue)) { + checkReference(newValue); + } else if (Array.isArray(newValue)) { + // Warn about writing "mixed" arrays of Reference and non-Reference objects + let seenReference: boolean = false; + let someNonReference: unknown; + for (const value of newValue) { + if (isReference(value)) { + seenReference = true; + if (checkReference(value)) break; + } else { + // Do not warn on primitive values, since those could never be represented + // by a reference. This is a valid (albeit uncommon) use case. + if (typeof value === "object" && !!value) { + const [id] = this.policies.identify(value); + // check if object could even be referenced, otherwise we are not interested in it for this warning + if (id) { + someNonReference = value; + } + } + } + if (seenReference && someNonReference !== undefined) { + invariant.warn( + "cache.modify: Writing an array with a mix of both References and Objects will not result in the Objects being normalized correctly.\n" + + "Please convert the object instance %o to a Reference before writing it to the cache by calling `toReference(object, true)`.", + someNonReference + ); + break; + } + } + } + } } } } diff --git a/src/dev/loadErrorMessageHandler.ts b/src/dev/loadErrorMessageHandler.ts index 199a6477b5c..ad18c159ed5 100644 --- a/src/dev/loadErrorMessageHandler.ts +++ b/src/dev/loadErrorMessageHandler.ts @@ -16,7 +16,7 @@ export function loadErrorMessageHandler(...errorCodes: ErrorCodes[]) { function handler(message: string | number, args: unknown[]) { if (typeof message === "number") { const definition = global[ApolloErrorMessageHandler]![message]; - if (!message || !definition.message) return; + if (!message || !definition?.message) return; message = definition.message; } return args.reduce( diff --git a/src/react/cache/QueryReference.ts b/src/react/cache/QueryReference.ts index 7a03ea10d37..f1ad5732bac 100644 --- a/src/react/cache/QueryReference.ts +++ b/src/react/cache/QueryReference.ts @@ -123,10 +123,19 @@ export class InternalQueryReference { // suspended resource does not use this queryRef in the given time. This // helps prevent memory leaks when a component has unmounted before the // query has finished loading. - this.autoDisposeTimeoutId = setTimeout( - this.dispose, - options.autoDisposeTimeoutMs ?? 30_000 - ); + const startDisposeTimer = () => { + if (!this.references) { + this.autoDisposeTimeoutId = setTimeout( + this.dispose, + options.autoDisposeTimeoutMs ?? 30_000 + ); + } + }; + + // We wait until the request has settled to ensure we don't dispose of the + // query ref before the request finishes, otherwise we would leave the + // promise in a pending state rendering the suspense boundary indefinitely. + this.promise.then(startDisposeTimer, startDisposeTimer); } get watchQueryOptions() { diff --git a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx index 08b4abb3f64..468fe8f4fc5 100644 --- a/src/react/hooks/__tests__/useSuspenseQuery.test.tsx +++ b/src/react/hooks/__tests__/useSuspenseQuery.test.tsx @@ -805,8 +805,12 @@ describe("useSuspenseQuery", () => { expect(screen.queryByText("Loading greeting...")).not.toBeInTheDocument(); - link.simulateResult({ result: { data: { greeting: "Hello" } } }); - link.simulateComplete(); + await act(() => { + link.simulateResult({ result: { data: { greeting: "Hello" } } }, true); + // Ensure simulateResult will deliver the result since its wrapped with + // setTimeout + jest.advanceTimersByTime(10); + }); expect(client.getObservableQueries().size).toBe(1); expect(client).toHaveSuspenseCacheEntryUsing(query); @@ -817,10 +821,6 @@ describe("useSuspenseQuery", () => { expect(client).not.toHaveSuspenseCacheEntryUsing(query); jest.useRealTimers(); - - // Avoid act warnings for a suspended resource - // eslint-disable-next-line testing-library/no-unnecessary-act - await act(() => wait(0)); }); it("has configurable auto dispose timer if the component never renders again after suspending", async () => { @@ -871,8 +871,12 @@ describe("useSuspenseQuery", () => { expect(screen.queryByText("Loading greeting...")).not.toBeInTheDocument(); - link.simulateResult({ result: { data: { greeting: "Hello" } } }); - link.simulateComplete(); + await act(() => { + link.simulateResult({ result: { data: { greeting: "Hello" } } }, true); + // Ensure simulateResult will deliver the result since its wrapped with + // setTimeout + jest.advanceTimersByTime(10); + }); expect(client.getObservableQueries().size).toBe(1); expect(client).toHaveSuspenseCacheEntryUsing(query); @@ -883,10 +887,6 @@ describe("useSuspenseQuery", () => { expect(client).not.toHaveSuspenseCacheEntryUsing(query); jest.useRealTimers(); - - // Avoid act warnings for a suspended resource - // eslint-disable-next-line testing-library/no-unnecessary-act - await act(() => wait(0)); }); it("cancels auto dispose if the component renders before timer finishes", async () => { @@ -940,6 +940,57 @@ describe("useSuspenseQuery", () => { jest.useRealTimers(); }); + // https://github.com/apollographql/apollo-client/issues/11270 + it("does not leave component suspended if query completes if request takes longer than auto dispose timeout", async () => { + jest.useFakeTimers(); + const { query } = useSimpleQueryCase(); + const link = new MockSubscriptionLink(); + const client = new ApolloClient({ + link, + cache: new InMemoryCache(), + defaultOptions: { + react: { + suspense: { + autoDisposeTimeoutMs: 10, + }, + }, + }, + }); + + function App() { + return ( + + + + + + ); + } + + function Greeting() { + const { data } = useSuspenseQuery(query); + + return {data.greeting}; + } + + render(); + + // Ensure suspends immediately + expect(screen.getByText("Loading greeting...")).toBeInTheDocument(); + + jest.advanceTimersByTime(20); + + link.simulateResult({ result: { data: { greeting: "Hello" } } }, true); + + await waitFor(() => { + expect(screen.queryByText("Loading greeting...")).not.toBeInTheDocument(); + }); + + expect(screen.getByText("Hello")).toBeInTheDocument(); + + jest.useRealTimers(); + }); + it("allows the client to be overridden", async () => { const { query } = useSimpleQueryCase(); diff --git a/src/react/hooks/index.ts b/src/react/hooks/index.ts index 3aace0d3e9d..61d50665cac 100644 --- a/src/react/hooks/index.ts +++ b/src/react/hooks/index.ts @@ -11,6 +11,7 @@ export type { UseSuspenseQueryResult } from "./useSuspenseQuery.js"; export { useSuspenseQuery } from "./useSuspenseQuery.js"; export type { UseBackgroundQueryResult } from "./useBackgroundQuery.js"; export { useBackgroundQuery } from "./useBackgroundQuery.js"; +export type { UseReadQueryResult } from "./useReadQuery.js"; export { useReadQuery } from "./useReadQuery.js"; export { skipToken } from "./constants.js"; export type { SkipToken } from "./constants.js"; diff --git a/src/react/hooks/useReadQuery.ts b/src/react/hooks/useReadQuery.ts index 85d4b3026f1..e6a97e1446f 100644 --- a/src/react/hooks/useReadQuery.ts +++ b/src/react/hooks/useReadQuery.ts @@ -5,8 +5,37 @@ import { __use } from "./internal/index.js"; import { toApolloError } from "./useSuspenseQuery.js"; import { invariant } from "../../utilities/globals/index.js"; import { useSyncExternalStore } from "./useSyncExternalStore.js"; +import type { ApolloError } from "../../errors/index.js"; +import type { NetworkStatus } from "../../core/index.js"; -export function useReadQuery(queryRef: QueryReference) { +export interface UseReadQueryResult { + /** + * An object containing the result of your GraphQL query after it completes. + * + * This value might be `undefined` if a query results in one or more errors + * (depending on the query's `errorPolicy`). + */ + data: TData; + /** + * If the query produces one or more errors, this object contains either an + * array of `graphQLErrors` or a single `networkError`. Otherwise, this value + * is `undefined`. + * + * This property can be ignored when using the default `errorPolicy` or an + * `errorPolicy` of `none`. The hook will throw the error instead of setting + * this property. + */ + error: ApolloError | undefined; + /** + * A number indicating the current network state of the query's associated + * request. {@link https://github.com/apollographql/apollo-client/blob/d96f4578f89b933c281bb775a39503f6cdb59ee8/src/core/networkStatus.ts#L4 | See possible values}. + */ + networkStatus: NetworkStatus; +} + +export function useReadQuery( + queryRef: QueryReference +): UseReadQueryResult { const internalQueryRef = unwrapQueryRef(queryRef); invariant( internalQueryRef.promiseCache, diff --git a/src/testing/react/MockedProvider.tsx b/src/testing/react/MockedProvider.tsx index fcc3dfdb217..b7afb9d416c 100644 --- a/src/testing/react/MockedProvider.tsx +++ b/src/testing/react/MockedProvider.tsx @@ -20,6 +20,11 @@ export interface MockedProviderProps { children?: any; link?: ApolloLink; showWarnings?: boolean; + /** + * If set to true, the MockedProvider will try to connect to the Apollo DevTools. + * Defaults to false. + */ + connectToDevTools?: boolean; } export interface MockedProviderState { @@ -45,10 +50,12 @@ export class MockedProvider extends React.Component< resolvers, link, showWarnings, + connectToDevTools = false, } = this.props; const client = new ApolloClient({ cache: cache || new Cache({ addTypename }), defaultOptions, + connectToDevTools, link: link || new MockLink(mocks || [], addTypename, { showWarnings }), resolvers, }); diff --git a/src/testing/react/__tests__/MockedProvider.test.tsx b/src/testing/react/__tests__/MockedProvider.test.tsx index b1676890bf7..a1fcdee8fe4 100644 --- a/src/testing/react/__tests__/MockedProvider.test.tsx +++ b/src/testing/react/__tests__/MockedProvider.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import { DocumentNode } from "graphql"; -import { act, render, waitFor } from "@testing-library/react"; +import { act, render, screen, waitFor } from "@testing-library/react"; import gql from "graphql-tag"; import { itAsync, MockedResponse, MockLink } from "../../core"; @@ -1085,6 +1085,70 @@ describe("General use", () => { }).then(resolve, reject); } ); + + it("should support loading state testing with delay", async () => { + function Component({ username }: Variables) { + const { loading, data } = useQuery(query, { variables }); + + if (loading || data === undefined) return

Loading the user ID...

; + + return

The user ID is '{data.user.id}'

; + } + + const mocks: ReadonlyArray = [ + { + delay: 30, // prevent React from batching the loading state away + request: { + query, + variables, + }, + result: { data: { user } }, + }, + ]; + + render( + + + + ); + + expect( + await screen.findByText("Loading the user ID...") + ).toBeInTheDocument(); + expect( + await screen.findByText("The user ID is 'user_id'") + ).toBeInTheDocument(); + }); + + it("should support loading state testing with infinite delay", async () => { + function Component({ username }: Variables) { + const { loading, data } = useQuery(query, { variables }); + + if (loading || data === undefined) return

Loading the user ID...

; + + return

The user ID is '{data.user.id}'

; + } + + const mocks: ReadonlyArray = [ + { + delay: Infinity, // keep loading forever. + request: { + query, + variables, + }, + }, + ]; + + render( + + + + ); + + expect( + await screen.findByText("Loading the user ID...") + ).toBeInTheDocument(); + }); }); describe("@client testing", () => { diff --git a/src/utilities/globals/__tests__/invariantWrappers.test.ts b/src/utilities/globals/__tests__/invariantWrappers.test.ts index f9255c170c8..2b750c534ed 100644 --- a/src/utilities/globals/__tests__/invariantWrappers.test.ts +++ b/src/utilities/globals/__tests__/invariantWrappers.test.ts @@ -99,3 +99,21 @@ test("invariant.log(5, ...), with handlers", () => { { a: 1 } ); }); + +test("base invariant(false, 6, ...), raises fallback", () => { + using _ = mockErrorMessageHandler(); + expect(() => { + invariant(false, 6, "hello"); + }).toThrow( + new InvariantError( + "An error occurred! For more details, see the full error text at https://go.apollo.dev/c/err#" + + encodeURIComponent( + JSON.stringify({ + version: "local", + message: 6, + args: ["hello"], + }) + ) + ) + ); +}); diff --git a/src/utilities/graphql/storeUtils.ts b/src/utilities/graphql/storeUtils.ts index c119a447c26..1912c01fd14 100644 --- a/src/utilities/graphql/storeUtils.ts +++ b/src/utilities/graphql/storeUtils.ts @@ -56,6 +56,24 @@ export interface StoreObject { [storeFieldName: string]: StoreValue; } +/** + * Workaround for a TypeScript quirk: + * types per default have an implicit index signature that makes them + * assignable to `StoreObject`. + * interfaces do not have that implicit index signature, so they cannot + * be assigned to `StoreObject`. + * This type just maps over a type or interface that is passed in, + * implicitly adding the index signature. + * That way, the result can be assigned to `StoreObject`. + * + * This is important if some user-defined interface is used e.g. + * in cache.modify, where the `toReference` method expects a + * `StoreObject` as input. + */ +export type AsStoreObject = { + [K in keyof T]: T[K]; +}; + export function isDocumentNode(value: any): value is DocumentNode { return ( isNonNullObject(value) && diff --git a/src/utilities/index.ts b/src/utilities/index.ts index ea660b1cafe..da8affb4b5a 100644 --- a/src/utilities/index.ts +++ b/src/utilities/index.ts @@ -39,6 +39,7 @@ export { print } from "./graphql/print.js"; export type { StoreObject, + AsStoreObject, Reference, StoreValue, Directives,