{"version":3,"file":"index.mjs","names":[],"sources":["../src/withTRPC.tsx","../src/createTRPCNext.tsx"],"sourcesContent":["/**\n * Heavily based on urql's ssr\n * https://github.com/FormidableLabs/urql/blob/main/packages/next-urql/src/with-urql-client.ts\n */\nimport type { DehydratedState, QueryClient } from '@tanstack/react-query';\nimport { HydrationBoundary, QueryClientProvider } from '@tanstack/react-query';\nimport type {\n  CreateTRPCClientOptions,\n  TRPCClient,\n  TRPCClientError,\n  TRPCUntypedClient,\n} from '@trpc/client';\nimport type { CoercedTransformerParameters } from '@trpc/client/unstable-internals';\nimport {\n  getTransformer,\n  type TransformerOptions,\n} from '@trpc/client/unstable-internals';\nimport type {\n  CreateTRPCReactOptions,\n  CreateTRPCReactQueryClientConfig,\n} from '@trpc/react-query/shared';\nimport { createRootHooks, getQueryClient } from '@trpc/react-query/shared';\nimport type {\n  AnyRouter,\n  Dict,\n  inferClientTypes,\n  ResponseMeta,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type {\n  AppContextType,\n  AppPropsType,\n  NextComponentType,\n  NextPageContext,\n} from 'next/dist/shared/lib/utils';\nimport type { NextRouter } from 'next/router';\nimport React, { useState } from 'react';\n\nexport type WithTRPCConfig<TRouter extends AnyRouter> =\n  CreateTRPCClientOptions<TRouter> &\n    CreateTRPCReactQueryClientConfig & {\n      abortOnUnmount?: boolean;\n    };\n\ntype WithTRPCOptions<TRouter extends AnyRouter> =\n  CreateTRPCReactOptions<TRouter> & {\n    config: (info: { ctx?: NextPageContext }) => WithTRPCConfig<TRouter>;\n  } & TransformerOptions<inferClientTypes<TRouter>>;\n\nexport type TRPCPrepassHelper = (opts: {\n  parent: WithTRPCSSROptions<AnyRouter>;\n  WithTRPC: NextComponentType<any, any, any>;\n  AppOrPage: NextComponentType<any, any, any>;\n}) => void;\nexport type WithTRPCSSROptions<TRouter extends AnyRouter> =\n  WithTRPCOptions<TRouter> & {\n    /**\n     * If you enable this, you also need to add a `ssrPrepass`-prop\n     * @see https://trpc.io/docs/client/nextjs/ssr\n     */\n    ssr:\n      true | ((opts: { ctx: NextPageContext }) => boolean | Promise<boolean>);\n    responseMeta?: (opts: {\n      ctx: NextPageContext;\n      clientErrors: TRPCClientError<TRouter>[];\n    }) => ResponseMeta;\n    /**\n     * use `import { ssrPrepass } from '@trpc/next/ssrPrepass'`\n     * @see https://trpc.io/docs/client/nextjs/ssr\n     */\n    ssrPrepass: TRPCPrepassHelper;\n  };\n\nexport type WithTRPCNoSSROptions<TRouter extends AnyRouter> =\n  WithTRPCOptions<TRouter> & {\n    ssr?: false;\n  };\n\nexport type TRPCPrepassProps<\n  TRouter extends AnyRouter,\n  TSSRContext extends NextPageContext = NextPageContext,\n> = {\n  config: WithTRPCConfig<TRouter>;\n  queryClient: QueryClient;\n  trpcClient: TRPCUntypedClient<TRouter> | TRPCClient<TRouter>;\n  ssrState: 'prepass';\n  ssrContext: TSSRContext;\n};\n\nexport function withTRPC<\n  TRouter extends AnyRouter,\n  TSSRContext extends NextPageContext = NextPageContext,\n>(opts: WithTRPCNoSSROptions<TRouter> | WithTRPCSSROptions<TRouter>) {\n  const { config: getClientConfig } = opts;\n  const transformer = getTransformer(\n    (opts as CoercedTransformerParameters).transformer,\n  );\n\n  type $PrepassProps = TRPCPrepassProps<TRouter, TSSRContext>;\n  return (AppOrPage: NextComponentType<any, any, any>): NextComponentType => {\n    const trpc = createRootHooks<TRouter, TSSRContext>(opts);\n\n    const WithTRPC = (\n      props: AppPropsType<NextRouter, any> & {\n        trpc?: $PrepassProps;\n      },\n    ) => {\n      const [prepassProps] = useState(() => {\n        if (props.trpc) {\n          return props.trpc;\n        }\n\n        const config = getClientConfig({});\n        const queryClient = getQueryClient(config);\n        const trpcClient = trpc.createClient(config);\n\n        return {\n          abortOnUnmount: config.abortOnUnmount,\n          queryClient,\n          trpcClient,\n          ssrState: opts.ssr ? ('mounting' as const) : (false as const),\n          ssrContext: null,\n        };\n      });\n\n      const { queryClient, trpcClient, ssrState, ssrContext } = prepassProps;\n\n      // allow normal components to be wrapped, not just app/pages\n      const trpcState = props.pageProps?.trpcState;\n\n      const hydratedState: DehydratedState | undefined = React.useMemo(() => {\n        if (!trpcState) {\n          return trpcState;\n        }\n\n        return transformer.input.deserialize(trpcState);\n      }, [trpcState]);\n\n      return (\n        <trpc.Provider\n          abortOnUnmount={(prepassProps as any).abortOnUnmount ?? false}\n          client={trpcClient}\n          queryClient={queryClient}\n          ssrState={ssrState}\n          ssrContext={ssrContext}\n        >\n          <QueryClientProvider client={queryClient}>\n            <HydrationBoundary state={hydratedState}>\n              <AppOrPage {...props} />\n            </HydrationBoundary>\n          </QueryClientProvider>\n        </trpc.Provider>\n      );\n    };\n\n    if (opts.ssr) {\n      opts.ssrPrepass({\n        parent: opts,\n        AppOrPage,\n        WithTRPC,\n      });\n    } else if (AppOrPage.getInitialProps) {\n      // Allow combining `getServerSideProps` and `getInitialProps`\n\n      WithTRPC.getInitialProps = async (appOrPageCtx: AppContextType) => {\n        // Determine if we are wrapping an App component or a Page component.\n        const isApp = !!appOrPageCtx.Component;\n\n        // Run the wrapped component's getInitialProps function.\n        let pageProps: Dict<unknown> = {};\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        const originalProps = await AppOrPage.getInitialProps!(\n          appOrPageCtx as any,\n        );\n        const originalPageProps = isApp\n          ? (originalProps.pageProps ?? {})\n          : originalProps;\n\n        pageProps = {\n          ...originalPageProps,\n          ...pageProps,\n        };\n        const getAppTreeProps = (props: Dict<unknown>) =>\n          isApp ? { pageProps: props } : props;\n\n        return getAppTreeProps(pageProps);\n      };\n    }\n\n    const displayName = AppOrPage.displayName ?? AppOrPage.name ?? 'Component';\n    WithTRPC.displayName = `withTRPC(${displayName})`;\n\n    return WithTRPC as any;\n  };\n}\n","/* istanbul ignore file -- @preserve */\n// We're testing this through E2E-testing\nimport type {\n  CreateReactUtils,\n  DecorateRouterRecord,\n  TRPCUseQueries,\n  TRPCUseSuspenseQueries,\n} from '@trpc/react-query/shared';\nimport {\n  createReactDecoration,\n  createReactQueryUtils,\n  createRootHooks,\n} from '@trpc/react-query/shared';\nimport type {\n  AnyRouter,\n  ProtectedIntersection,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { createFlatProxy } from '@trpc/server/unstable-core-do-not-import';\nimport type { NextPageContext } from 'next/types';\nimport { useMemo } from 'react';\nimport type { WithTRPCNoSSROptions, WithTRPCSSROptions } from './withTRPC';\nimport { withTRPC } from './withTRPC';\n\n/**\n * @internal\n */\nexport interface CreateTRPCNextBase<\n  TRouter extends AnyRouter,\n  TSSRContext extends NextPageContext,\n> {\n  /**\n   * @deprecated renamed to `useUtils` and will be removed in a future tRPC version\n   *\n   * @see https://trpc.io/docs/v11/client/react/useUtils\n   */\n  useContext(): CreateReactUtils<TRouter, TSSRContext>;\n  /**\n   * @see https://trpc.io/docs/v11/client/react/useUtils\n   */\n  useUtils(): CreateReactUtils<TRouter, TSSRContext>;\n  withTRPC: ReturnType<typeof withTRPC<TRouter, TSSRContext>>;\n  useQueries: TRPCUseQueries<TRouter>;\n  useSuspenseQueries: TRPCUseSuspenseQueries<TRouter>;\n}\n\n/**\n * @internal\n */\nexport type CreateTRPCNext<\n  TRouter extends AnyRouter,\n  TSSRContext extends NextPageContext,\n> = ProtectedIntersection<\n  CreateTRPCNextBase<TRouter, TSSRContext>,\n  DecorateRouterRecord<\n    TRouter['_def']['_config']['$types'],\n    TRouter['_def']['record']\n  >\n>;\n\nexport function createTRPCNext<\n  TRouter extends AnyRouter,\n  TSSRContext extends NextPageContext = NextPageContext,\n>(\n  opts: WithTRPCNoSSROptions<TRouter> | WithTRPCSSROptions<TRouter>,\n): CreateTRPCNext<TRouter, TSSRContext> {\n  const hooks = createRootHooks<TRouter, TSSRContext>(opts);\n\n  // TODO: maybe set TSSRContext to `never` when using `WithTRPCNoSSROptions`\n  const _withTRPC = withTRPC(opts);\n\n  const proxy = createReactDecoration(hooks) as DecorateRouterRecord<\n    TRouter['_def']['_config']['$types'],\n    TRouter['_def']['record']\n  >;\n\n  return createFlatProxy((key) => {\n    if (key === 'useContext' || key === 'useUtils') {\n      return () => {\n        const context = hooks.useUtils();\n        // create a stable reference of the utils context\n        return useMemo(() => {\n          return (createReactQueryUtils as any)(context);\n        }, [context]);\n      };\n    }\n\n    if (key === 'useQueries') {\n      return hooks.useQueries;\n    }\n\n    if (key === 'useSuspenseQueries') {\n      return hooks.useSuspenseQueries;\n    }\n\n    if (key === 'withTRPC') {\n      return _withTRPC;\n    }\n\n    return proxy[key];\n  });\n}\n"],"mappings":";;;;;;;AAwFA,SAAgB,SAGd,MAAmE;CACnE,MAAM,EAAE,QAAQ,oBAAoB;CACpC,MAAM,cAAc,eACjB,KAAsC,WACzC;CAGA,QAAQ,cAAmE;;EACzE,MAAM,OAAO,gBAAsC,IAAI;EAEvD,MAAM,YACJ,UAGG;;GACH,MAAM,CAAC,gBAAgB,eAAe;IACpC,IAAI,MAAM,MACR,OAAO,MAAM;IAGf,MAAM,SAAS,gBAAgB,CAAC,CAAC;IACjC,MAAM,cAAc,eAAe,MAAM;IACzC,MAAM,aAAa,KAAK,aAAa,MAAM;IAE3C,OAAO;KACL,gBAAgB,OAAO;KACvB;KACA;KACA,UAAU,KAAK,MAAO,aAAwB;KAC9C,YAAY;IACd;GACF,CAAC;GAED,MAAM,EAAE,aAAa,YAAY,UAAU,eAAe;GAG1D,MAAM,aAAA,mBAAY,MAAM,eAAA,QAAA,qBAAA,KAAA,IAAA,KAAA,IAAA,iBAAW;GAEnC,MAAM,gBAA6C,MAAM,cAAc;IACrE,IAAI,CAAC,WACH,OAAO;IAGT,OAAO,YAAY,MAAM,YAAY,SAAS;GAChD,GAAG,CAAC,SAAS,CAAC;GAEd,OACE,sBAAA,cAAC,KAAK,UAAN;IACE,iBAAA,kBAAiB,aAAqB,oBAAA,QAAA,oBAAA,KAAA,IAAA,kBAAkB;IACxD,QAAQ;IACK;IACH;IACE;GAOC,GALb,sBAAA,cAAC,qBAAD,EAAqB,QAAQ,YAIR,GAHnB,sBAAA,cAAC,mBAAD,EAAmB,OAAO,cAEP,GADjB,sBAAA,cAAC,WAAc,KAAQ,CACN,CACA,CACR;EAEnB;EAEA,IAAI,KAAK,KACP,KAAK,WAAW;GACd,QAAQ;GACR;GACA;EACF,CAAC;OACI,IAAI,UAAU,iBAGnB,SAAS,kBAAkB,OAAO,iBAAiC;;GAEjE,MAAM,QAAQ,CAAC,CAAC,aAAa;GAG7B,IAAI,YAA2B,CAAC;GAEhC,MAAM,gBAAgB,MAAM,UAAU,gBACpC,YACF;GACA,MAAM,oBAAoB,SAAA,wBACrB,cAAc,eAAA,QAAA,0BAAA,KAAA,IAAA,wBAAa,CAAC,IAC7B;GAEJ,YAAA,eAAA,eAAA,CAAA,GACK,iBAAA,GACA,SACL;GACA,MAAM,mBAAmB,UACvB,QAAQ,EAAE,WAAW,MAAM,IAAI;GAEjC,OAAO,gBAAgB,SAAS;EAClC;EAIF,SAAS,cAAc,aAAA,QAAA,wBADH,UAAU,iBAAA,QAAA,0BAAA,KAAA,IAAA,wBAAe,UAAU,UAAA,QAAA,SAAA,KAAA,IAAA,OAAQ,YAChB;EAE/C,OAAO;CACT;AACF;;;;ACtIA,SAAgB,eAId,MACsC;CACtC,MAAM,QAAQ,gBAAsC,IAAI;CAGxD,MAAM,YAAY,SAAS,IAAI;CAE/B,MAAM,QAAQ,sBAAsB,KAAK;CAKzC,OAAO,iBAAiB,QAAQ;EAC9B,IAAI,QAAQ,gBAAgB,QAAQ,YAClC,aAAa;GACX,MAAM,UAAU,MAAM,SAAS;GAE/B,OAAO,cAAc;IACnB,OAAQ,sBAA8B,OAAO;GAC/C,GAAG,CAAC,OAAO,CAAC;EACd;EAGF,IAAI,QAAQ,cACV,OAAO,MAAM;EAGf,IAAI,QAAQ,sBACV,OAAO,MAAM;EAGf,IAAI,QAAQ,YACV,OAAO;EAGT,OAAO,MAAM;CACf,CAAC;AACH"}