From 56de988f5567ec8a4dba1695e017c588a6123fd0 Mon Sep 17 00:00:00 2001 From: Conrawl Rogers Date: Fri, 1 Mar 2024 10:42:25 -0400 Subject: [PATCH] fix: improve typing for composables --- package.json | 3 +- playground/nuxt.config.ts | 2 + src/module.ts | 3 +- src/runtime/composables.ts | 96 +++++++++++++++++++++++++++++--------- 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index f2d20fac..41b984d1 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "dev": "nuxi dev playground", "dev:build": "nuxi build playground", "dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground", - "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .", + "lint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore .", + "lint:fix": "eslint --fix --ext .js,.ts,.vue --ignore-path .gitignore .", "release": "standard-version --prerelease alpha && git push --follow-tags && pnpm publish --tag next" }, "dependencies": { diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 9b96749e..0d010067 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -1,4 +1,6 @@ export default defineNuxtConfig({ + devtools: { enabled: true }, + modules: ['@nuxt/ui', '@nuxtjs/apollo'], colorMode: { diff --git a/src/module.ts b/src/module.ts index f5cd2b51..125b5439 100644 --- a/src/module.ts +++ b/src/module.ts @@ -43,7 +43,8 @@ export default defineNuxtModule({ }, async setup (options, nuxt) { if (!options.clients || !Object.keys(options.clients).length) { - throw new Error('[@nuxtjs/apollo] Atleast one client must be configured.') + logger.warn('No apollo clients configured.') + return } const { resolve } = createResolver(import.meta.url) diff --git a/src/runtime/composables.ts b/src/runtime/composables.ts index 4f432b89..7644afea 100644 --- a/src/runtime/composables.ts +++ b/src/runtime/composables.ts @@ -13,14 +13,40 @@ type KeysOf = Array = QueryOptions['query'] type TVariables = QueryOptions['variables'] | null type TAsyncQuery = { + /** + * A unique key to ensure the query can be properly de-duplicated across requests. Defaults to a hash of the query and variables. + */ key?: string + /** + * A GraphQL query string parsed into an AST with the gql template literal. + */ query: TQuery + /** + * An object containing all of the GraphQL variables your query requires to execute. + * + * Each key in the object corresponds to a variable name, and that key's value corresponds to the variable value. + */ variables?: TVariables + /** + * The name of the Apollo Client to use. Defaults to `default`. + */ clientId?: ApolloClientKeys + /** + * If you're using Apollo Link, this object is the initial value of the context object that's passed along your link chain. + */ context?: DefaultContext + /** + * If `true`, this overrides the default fetchPolicy for the Apollo Client to `cache-first`. + * */ cache?: boolean } +/** + * `useAsyncQuery` resolves the GraphQL query asynchronously in a SSR-friendly composable. + * + * @param opts An object containing the query, variables, clientId, context, and cache options. + * @param options Customize the underlying `useAsyncData` composable. + */ export function useAsyncQuery < T, DataT = T, @@ -29,6 +55,15 @@ export function useAsyncQuery < NuxtErrorDataT = unknown > (opts: TAsyncQuery, options?: AsyncDataOptions): AsyncData | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError) | null> +/** + * `useAsyncQuery` resolves the GraphQL query asynchronously in a SSR-friendly composable. + * + * @param query A GraphQL query string parsed into an AST with the gql template literal. + * @param variables An object containing all of the GraphQL variables your query requires to execute. + * @param clientId The name of the Apollo Client to use. Defaults to `default`. + * @param context The context object that's passed along your link chain. + * @param options Customize the underlying `useAsyncData` composable. + */ export function useAsyncQuery < T, DataT = T, @@ -42,6 +77,12 @@ export function useAsyncQuery (...args: any[]) { return useAsyncData(key, fn, options) } +/** + * `useLazyAsyncQuery` resolves the GraphQL query after loading the route, instead of blocking client-side navigation. + * + * @param opts An object containing the query, variables, clientId, context, and cache options. + * @param options Customize the underlying `useAsyncData` composable. + */ export function useLazyAsyncQuery < T, DataT = T, @@ -50,6 +91,15 @@ export function useLazyAsyncQuery < NuxtErrorDataT = unknown > (opts: TAsyncQuery, options?: AsyncDataOptions): AsyncData | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError) | null> +/** + * `useLazyAsyncQuery` resolves the GraphQL query after loading the route, instead of blocking client-side navigation. + * + * @param query A GraphQL query string parsed into an AST with the gql template literal. + * @param variables An object containing all of the GraphQL variables your query requires to execute. + * @param clientId The name of the Apollo Client to use. Defaults to `default`. + * @param context The context object that's passed along your link chain. + * @param options Customize the underlying `useAsyncData` composable. + */ export function useLazyAsyncQuery < T, DataT = T, @@ -113,7 +163,7 @@ const prep = (...args: any[]) => { options.watch.push(variables) } - const key = args?.[0]?.key || hash({ query: print(query), variables, clientId }) + const key: string = args?.[0]?.key || hash({ query: print(query), variables, clientId }) const fn = () => clients![clientId!]?.query({ query, @@ -126,9 +176,32 @@ const prep = (...args: any[]) => { } export function useApollo (): { + /** + * Access the configured apollo clients. + */ clients: Record> | undefined + /** + * Retrieve the auth token for the specified client. Adheres to the `apollo:auth` hook. + * + * @param {string} client The client who's token to retrieve. Defaults to `default`. + */ getToken: (client?: ApolloClientKeys) => Promise + + /** + * Apply auth token to the specified Apollo client, and optionally reset it's cache. + * + * @param {string} token The token to be applied. + * @param {string} client - Name of the Apollo client. Defaults to `default`. + * @param {boolean} skipResetStore - If `true`, the cache will not be reset. + * */ onLogin: (token?: string, client?: ApolloClientKeys, skipResetStore?: boolean) => Promise + + /** + * Remove the auth token from the Apollo client, and optionally reset it's cache. + * + * @param {string} client - Name of the Apollo client. Defaults to `default`. + * @param {boolean} skipResetStore - If `true`, the cache will not be reset. + * */ onLogout: (client?: ApolloClientKeys, skipResetStore?: boolean) => Promise } @@ -186,33 +259,12 @@ export function useApollo () { } return { - /** - * Retrieve the auth token for the specified client. Adheres to the `apollo:auth` hook. - * - * @param {string} client The client who's token to retrieve. Defaults to `default`. - */ getToken, - /** - * Access the configured apollo clients. - */ clients: nuxtApp?._apolloClients, - /** - * Apply auth token to the specified Apollo client, and optionally reset it's cache. - * - * @param {string} token The token to be applied. - * @param {string} client - Name of the Apollo client. Defaults to `default`. - * @param {boolean} skipResetStore - If `true`, the cache will not be reset. - * */ onLogin: (token?: string, client?: ApolloClientKeys, skipResetStore?: boolean) => updateAuth({ token, client, skipResetStore, mode: 'login' }), - /** - * Remove the auth token from the Apollo client, and optionally reset it's cache. - * - * @param {string} client - Name of the Apollo client. Defaults to `default`. - * @param {boolean} skipResetStore - If `true`, the cache will not be reset. - * */ onLogout: (client?: ApolloClientKeys, skipResetStore?: boolean) => updateAuth({ client, skipResetStore, mode: 'logout' }) } }