fix(deps)!: update tanstack-query monorepo (#126)
* fix(deps): update tanstack-query monorepo to ^5.21.2 * fix(deps): update tanstack-query monorepo * fix: type issue with transformer * fix: issues with next-auth, updated to next canary * chore: fix type issue in trpc route * chore: fix formatting --------- Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
committed by
GitHub
parent
3bdd117659
commit
71521c0768
@@ -29,9 +29,9 @@
|
|||||||
"@mantine/modals": "^7.5.3",
|
"@mantine/modals": "^7.5.3",
|
||||||
"@mantine/tiptap": "^7.5.3",
|
"@mantine/tiptap": "^7.5.3",
|
||||||
"@t3-oss/env-nextjs": "^0.9.2",
|
"@t3-oss/env-nextjs": "^0.9.2",
|
||||||
"@tanstack/react-query": "^5.20.5",
|
"@tanstack/react-query": "^5.21.2",
|
||||||
"@tanstack/react-query-devtools": "^5.21.0",
|
"@tanstack/react-query-devtools": "^5.21.3",
|
||||||
"@tanstack/react-query-next-experimental": "5.20.5",
|
"@tanstack/react-query-next-experimental": "5.21.2",
|
||||||
"@tiptap/extension-link": "^2.2.3",
|
"@tiptap/extension-link": "^2.2.3",
|
||||||
"@tiptap/react": "^2.2.3",
|
"@tiptap/react": "^2.2.3",
|
||||||
"@tiptap/starter-kit": "^2.2.3",
|
"@tiptap/starter-kit": "^2.2.3",
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"@homarr/gridstack": "^1.0.0",
|
"@homarr/gridstack": "^1.0.0",
|
||||||
"jotai": "^2.6.4",
|
"jotai": "^2.6.4",
|
||||||
"mantine-modal-manager": "^7.5.2",
|
"mantine-modal-manager": "^7.5.2",
|
||||||
"next": "^14.1.0",
|
"next": "^14.1.1-canary.58",
|
||||||
"postcss-preset-mantine": "^1.13.0",
|
"postcss-preset-mantine": "^1.13.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default async function EditIntegrationPage({
|
|||||||
params,
|
params,
|
||||||
}: EditIntegrationPageProps) {
|
}: EditIntegrationPageProps) {
|
||||||
const t = await getScopedI18n("integration.page.edit");
|
const t = await getScopedI18n("integration.page.edit");
|
||||||
const integration = await api.integration.byId.query({ id: params.id });
|
const integration = await api.integration.byId({ id: params.id });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ interface IntegrationsPageProps {
|
|||||||
export default async function IntegrationsPage({
|
export default async function IntegrationsPage({
|
||||||
searchParams,
|
searchParams,
|
||||||
}: IntegrationsPageProps) {
|
}: IntegrationsPageProps) {
|
||||||
const integrations = await api.integration.all.query();
|
const integrations = await api.integration.all();
|
||||||
const t = await getScopedI18n("integration");
|
const t = await getScopedI18n("integration");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import type { PropsWithChildren } from "react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||||
@@ -9,19 +10,7 @@ import superjson from "superjson";
|
|||||||
|
|
||||||
import { clientApi } from "@homarr/api/client";
|
import { clientApi } from "@homarr/api/client";
|
||||||
|
|
||||||
import { env } from "~/env.mjs";
|
export function TRPCReactProvider(props: PropsWithChildren) {
|
||||||
|
|
||||||
const getBaseUrl = () => {
|
|
||||||
if (typeof window !== "undefined") return ""; // browser should use relative url
|
|
||||||
if (env.VERCEL_URL) return env.VERCEL_URL; // SSR should use vercel url
|
|
||||||
|
|
||||||
return `http://localhost:${env.PORT}`; // dev SSR should use localhost
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TRPCReactProvider(props: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
headers?: Headers;
|
|
||||||
}) {
|
|
||||||
const [queryClient] = useState(
|
const [queryClient] = useState(
|
||||||
() =>
|
() =>
|
||||||
new QueryClient({
|
new QueryClient({
|
||||||
@@ -35,7 +24,6 @@ export function TRPCReactProvider(props: {
|
|||||||
|
|
||||||
const [trpcClient] = useState(() =>
|
const [trpcClient] = useState(() =>
|
||||||
clientApi.createClient({
|
clientApi.createClient({
|
||||||
transformer: superjson,
|
|
||||||
links: [
|
links: [
|
||||||
loggerLink({
|
loggerLink({
|
||||||
enabled: (opts) =>
|
enabled: (opts) =>
|
||||||
@@ -43,11 +31,12 @@ export function TRPCReactProvider(props: {
|
|||||||
(opts.direction === "down" && opts.result instanceof Error),
|
(opts.direction === "down" && opts.result instanceof Error),
|
||||||
}),
|
}),
|
||||||
unstable_httpBatchStreamLink({
|
unstable_httpBatchStreamLink({
|
||||||
url: `${getBaseUrl()}/api/trpc`,
|
transformer: superjson,
|
||||||
|
url: getBaseUrl() + "/api/trpc",
|
||||||
headers() {
|
headers() {
|
||||||
const headers = new Map(props.headers);
|
const headers = new Headers();
|
||||||
headers.set("x-trpc-source", "nextjs-react");
|
headers.set("x-trpc-source", "nextjs-react");
|
||||||
return Object.fromEntries(headers);
|
return headers;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@@ -65,3 +54,9 @@ export function TRPCReactProvider(props: {
|
|||||||
</clientApi.Provider>
|
</clientApi.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBaseUrl() {
|
||||||
|
if (typeof window !== "undefined") return window.location.origin;
|
||||||
|
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;
|
||||||
|
return `http://localhost:${process.env.PORT ?? 3000}`;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ import { createBoardPage } from "../_creator";
|
|||||||
|
|
||||||
export default createBoardPage<{ locale: string }>({
|
export default createBoardPage<{ locale: string }>({
|
||||||
async getInitialBoard() {
|
async getInitialBoard() {
|
||||||
return await api.board.default.query();
|
return await api.board.default();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ import { createBoardPage } from "../_creator";
|
|||||||
|
|
||||||
export default createBoardPage<{ locale: string; name: string }>({
|
export default createBoardPage<{ locale: string; name: string }>({
|
||||||
async getInitialBoard({ name }) {
|
async getInitialBoard({ name }) {
|
||||||
return await api.board.byName.query({ name });
|
return await api.board.byName({ name });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function BoardSettingsPage({ params }: Props) {
|
export default async function BoardSettingsPage({ params }: Props) {
|
||||||
const board = await api.board.byName.query({ name: params.name });
|
const board = await api.board.byName({ name: params.name });
|
||||||
const t = await getScopedI18n("board.setting");
|
const t = await getScopedI18n("board.setting");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata, Viewport } from "next";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
|
|
||||||
import "@homarr/ui/styles.css";
|
|
||||||
import "@homarr/notifications/styles.css";
|
import "@homarr/notifications/styles.css";
|
||||||
import "@homarr/spotlight/styles.css";
|
import "@homarr/spotlight/styles.css";
|
||||||
|
import "@homarr/ui/styles.css";
|
||||||
import { headers } from "next/headers";
|
|
||||||
|
|
||||||
import { Notifications } from "@homarr/notifications";
|
import { Notifications } from "@homarr/notifications";
|
||||||
import {
|
import {
|
||||||
@@ -23,16 +21,28 @@ const fontSans = Inter({
|
|||||||
variable: "--font-sans",
|
variable: "--font-sans",
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Since we're passing `headers()` to the `TRPCReactProvider` we need to
|
|
||||||
* make the entire app dynamic. You can move the `TRPCReactProvider` further
|
|
||||||
* down the tree (e.g. /dashboard and onwards) to make part of the app statically rendered.
|
|
||||||
*/
|
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
|
metadataBase: new URL("http://localhost:3000"),
|
||||||
title: "Create T3 Turbo",
|
title: "Create T3 Turbo",
|
||||||
description: "Simple monorepo with shared backend for web & mobile apps",
|
description: "Simple monorepo with shared backend for web & mobile apps",
|
||||||
|
openGraph: {
|
||||||
|
title: "Create T3 Turbo",
|
||||||
|
description: "Simple monorepo with shared backend for web & mobile apps",
|
||||||
|
url: "https://create-t3-turbo.vercel.app",
|
||||||
|
siteName: "Create T3 Turbo",
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
card: "summary_large_image",
|
||||||
|
site: "@jullerino",
|
||||||
|
creator: "@jullerino",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
themeColor: [
|
||||||
|
{ media: "(prefers-color-scheme: light)", color: "white" },
|
||||||
|
{ media: "(prefers-color-scheme: dark)", color: "black" },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Layout(props: {
|
export default function Layout(props: {
|
||||||
@@ -42,12 +52,12 @@ export default function Layout(props: {
|
|||||||
const colorScheme = "dark";
|
const colorScheme = "dark";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en" suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
<ColorSchemeScript defaultColorScheme={colorScheme} />
|
<ColorSchemeScript defaultColorScheme={colorScheme} />
|
||||||
</head>
|
</head>
|
||||||
<body className={["font-sans", fontSans.variable].join(" ")}>
|
<body className={["font-sans", fontSans.variable].join(" ")}>
|
||||||
<TRPCReactProvider headers={headers()}>
|
<TRPCReactProvider>
|
||||||
<NextInternationalProvider locale={props.params.locale}>
|
<NextInternationalProvider locale={props.params.locale}>
|
||||||
<MantineProvider
|
<MantineProvider
|
||||||
defaultColorScheme={colorScheme}
|
defaultColorScheme={colorScheme}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { DeleteBoardButton } from "./_components/delete-board-button";
|
|||||||
export default async function ManageBoardsPage() {
|
export default async function ManageBoardsPage() {
|
||||||
const t = await getScopedI18n("management.page.board");
|
const t = await getScopedI18n("management.page.board");
|
||||||
|
|
||||||
const boards = await api.board.getAll.query();
|
const boards = await api.board.getAll();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const handler = auth(async (req) => {
|
|||||||
router: appRouter,
|
router: appRouter,
|
||||||
req,
|
req,
|
||||||
createContext: () =>
|
createContext: () =>
|
||||||
createTRPCContext({ auth: req.auth, headers: req.headers }),
|
createTRPCContext({ session: req.auth, headers: req.headers }),
|
||||||
onError({ error, path }) {
|
onError({ error, path }) {
|
||||||
console.error(`>>> tRPC Error on '${path}'`, error);
|
console.error(`>>> tRPC Error on '${path}'`, error);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
import { cache } from "react";
|
import { cache } from "react";
|
||||||
import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
import { createTRPCClient, loggerLink, TRPCClientError } from "@trpc/client";
|
|
||||||
import { callProcedure } from "@trpc/server";
|
|
||||||
import { observable } from "@trpc/server/observable";
|
|
||||||
import type { TRPCErrorResponse } from "@trpc/server/rpc";
|
|
||||||
import SuperJSON from "superjson";
|
|
||||||
|
|
||||||
import { appRouter, createTRPCContext } from "@homarr/api";
|
import { createCaller, createTRPCContext } from "@homarr/api";
|
||||||
import { auth } from "@homarr/auth";
|
import { auth } from "@homarr/auth";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,44 +13,9 @@ const createContext = cache(async () => {
|
|||||||
heads.set("x-trpc-source", "rsc");
|
heads.set("x-trpc-source", "rsc");
|
||||||
|
|
||||||
return createTRPCContext({
|
return createTRPCContext({
|
||||||
auth: await auth(),
|
session: await auth(),
|
||||||
headers: heads,
|
headers: heads,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
export const api = createTRPCClient<typeof appRouter>({
|
export const api = createCaller(createContext);
|
||||||
transformer: SuperJSON,
|
|
||||||
links: [
|
|
||||||
loggerLink({
|
|
||||||
enabled: (op) =>
|
|
||||||
process.env.NODE_ENV === "development" ||
|
|
||||||
(op.direction === "down" && op.result instanceof Error),
|
|
||||||
}),
|
|
||||||
/**
|
|
||||||
* Custom RSC link that invokes procedures directly in the server component Don't be too afraid
|
|
||||||
* about the complexity here, it's just wrapping `callProcedure` with an observable to make it a
|
|
||||||
* valid ending link for tRPC.
|
|
||||||
*/
|
|
||||||
() =>
|
|
||||||
({ op }) =>
|
|
||||||
observable((observer) => {
|
|
||||||
createContext()
|
|
||||||
.then((ctx) => {
|
|
||||||
return callProcedure({
|
|
||||||
procedures: appRouter._def.procedures,
|
|
||||||
path: op.path,
|
|
||||||
getRawInput: () => Promise.resolve(op.input),
|
|
||||||
ctx,
|
|
||||||
type: op.type,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
observer.next({ result: { data } });
|
|
||||||
observer.complete();
|
|
||||||
})
|
|
||||||
.catch((cause: TRPCErrorResponse) => {
|
|
||||||
observer.error(TRPCClientError.from(cause));
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
|
|
||||||
|
|
||||||
import type { AppRouter } from "./src/root";
|
|
||||||
|
|
||||||
export { appRouter, type AppRouter } from "./src/root";
|
|
||||||
export { createTRPCContext } from "./src/trpc";
|
|
||||||
/**
|
|
||||||
* Inference helpers for input types
|
|
||||||
* @example type HelloInput = RouterInputs['example']['hello']
|
|
||||||
**/
|
|
||||||
export type RouterInputs = inferRouterInputs<AppRouter>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inference helpers for output types
|
|
||||||
* @example type HelloOutput = RouterOutputs['example']['hello']
|
|
||||||
**/
|
|
||||||
export type RouterOutputs = inferRouterOutputs<AppRouter>;
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "@homarr/api",
|
"name": "@homarr/api",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./index.ts",
|
".": "./src/index.ts",
|
||||||
"./client": "./src/client.ts"
|
"./client": "./src/client.ts"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createTRPCReact } from "@trpc/react-query";
|
import { createTRPCReact } from "@trpc/react-query";
|
||||||
|
|
||||||
import type { AppRouter } from "..";
|
import type { AppRouter } from ".";
|
||||||
|
|
||||||
export const clientApi = createTRPCReact<AppRouter>();
|
export const clientApi = createTRPCReact<AppRouter>();
|
||||||
|
|||||||
33
packages/api/src/index.ts
Normal file
33
packages/api/src/index.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
|
||||||
|
|
||||||
|
import type { AppRouter } from "./root";
|
||||||
|
import { appRouter } from "./root";
|
||||||
|
import { createCallerFactory, createTRPCContext } from "./trpc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a server-side caller for the tRPC API
|
||||||
|
* @example
|
||||||
|
* const trpc = createCaller(createContext);
|
||||||
|
* const res = await trpc.post.all();
|
||||||
|
* ^? Post[]
|
||||||
|
*/
|
||||||
|
const createCaller = createCallerFactory(appRouter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inference helpers for input types
|
||||||
|
* @example
|
||||||
|
* type PostByIdInput = RouterInputs['post']['byId']
|
||||||
|
* ^? { id: number }
|
||||||
|
**/
|
||||||
|
type RouterInputs = inferRouterInputs<AppRouter>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inference helpers for output types
|
||||||
|
* @example
|
||||||
|
* type AllPostsOutput = RouterOutputs['post']['all']
|
||||||
|
* ^? Post[]
|
||||||
|
**/
|
||||||
|
type RouterOutputs = inferRouterOutputs<AppRouter>;
|
||||||
|
|
||||||
|
export { createTRPCContext, appRouter, createCaller };
|
||||||
|
export type { AppRouter, RouterInputs, RouterOutputs };
|
||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from "@homarr/db/schema/sqlite";
|
} from "@homarr/db/schema/sqlite";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
import type { RouterOutputs } from "../../..";
|
import type { RouterOutputs } from "../..";
|
||||||
import { boardRouter } from "../board";
|
import { boardRouter } from "../board";
|
||||||
|
|
||||||
// Mock the auth module to return an empty session
|
// Mock the auth module to return an empty session
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { createId } from "@homarr/db";
|
|||||||
import { integrations, integrationSecrets } from "@homarr/db/schema/sqlite";
|
import { integrations, integrationSecrets } from "@homarr/db/schema/sqlite";
|
||||||
import { createDb } from "@homarr/db/test";
|
import { createDb } from "@homarr/db/test";
|
||||||
|
|
||||||
import type { RouterInputs } from "../../..";
|
import type { RouterInputs } from "../..";
|
||||||
import { encryptSecret, integrationRouter } from "../integration";
|
import { encryptSecret, integrationRouter } from "../integration";
|
||||||
import { expectToBeDefined } from "./board.spec";
|
import { expectToBeDefined } from "./board.spec";
|
||||||
|
|
||||||
|
|||||||
@@ -17,49 +17,28 @@ import { ZodError } from "@homarr/validation";
|
|||||||
/**
|
/**
|
||||||
* 1. CONTEXT
|
* 1. CONTEXT
|
||||||
*
|
*
|
||||||
* This section defines the "contexts" that are available in the backend API
|
* This section defines the "contexts" that are available in the backend API.
|
||||||
*
|
*
|
||||||
* These allow you to access things like the database, the session, etc, when
|
* These allow you to access things when processing a request, like the database, the session, etc.
|
||||||
* processing a request
|
|
||||||
*
|
*
|
||||||
*/
|
* This helper generates the "internals" for a tRPC context. The API handler and RSC clients each
|
||||||
interface CreateContextOptions {
|
* wrap this and provides the required context.
|
||||||
session: Session | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This helper generates the "internals" for a tRPC context. If you need to use
|
|
||||||
* it, you can export it from here
|
|
||||||
*
|
*
|
||||||
* Examples of things you may need it for:
|
* @see https://trpc.io/docs/server/context
|
||||||
* - testing, so we dont have to mock Next.js' req/res
|
|
||||||
* - trpc's `createSSGHelpers` where we don't have req/res
|
|
||||||
* @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
|
|
||||||
*/
|
|
||||||
const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
|
||||||
return {
|
|
||||||
session: opts.session,
|
|
||||||
db,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the actual context you'll use in your router. It will be used to
|
|
||||||
* process every request that goes through your tRPC endpoint
|
|
||||||
* @link https://trpc.io/docs/context
|
|
||||||
*/
|
*/
|
||||||
export const createTRPCContext = async (opts: {
|
export const createTRPCContext = async (opts: {
|
||||||
headers?: Headers;
|
headers: Headers;
|
||||||
auth: Session | null;
|
session: Session | null;
|
||||||
}) => {
|
}) => {
|
||||||
const session = opts.auth ?? (await auth());
|
const session = opts.session ?? (await auth());
|
||||||
const source = opts.headers?.get("x-trpc-source") ?? "unknown";
|
const source = opts.headers.get("x-trpc-source") ?? "unknown";
|
||||||
|
|
||||||
console.log(">>> tRPC Request from", source, "by", session?.user);
|
console.log(">>> tRPC Request from", source, "by", session?.user);
|
||||||
|
|
||||||
return createInnerTRPCContext({
|
return {
|
||||||
session,
|
session,
|
||||||
});
|
db,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,18 +49,21 @@ export const createTRPCContext = async (opts: {
|
|||||||
*/
|
*/
|
||||||
const t = initTRPC.context<typeof createTRPCContext>().create({
|
const t = initTRPC.context<typeof createTRPCContext>().create({
|
||||||
transformer: superjson,
|
transformer: superjson,
|
||||||
errorFormatter({ shape, error }) {
|
errorFormatter: ({ shape, error }) => ({
|
||||||
return {
|
...shape,
|
||||||
...shape,
|
data: {
|
||||||
data: {
|
...shape.data,
|
||||||
...shape.data,
|
zodError: error.cause instanceof ZodError ? error.cause.flatten() : null,
|
||||||
zodError:
|
},
|
||||||
error.cause instanceof ZodError ? error.cause.flatten() : null,
|
}),
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a server-side caller
|
||||||
|
* @see https://trpc.io/docs/server/server-side-calls
|
||||||
|
*/
|
||||||
|
export const createCallerFactory = t.createCallerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
|
* 3. ROUTER & PROCEDURE (THE IMPORTANT BIT)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,18 +7,10 @@ export const env = createEnv({
|
|||||||
process.env.NODE_ENV === "production"
|
process.env.NODE_ENV === "production"
|
||||||
? z.string().min(1)
|
? z.string().min(1)
|
||||||
: z.string().min(1).optional(),
|
: z.string().min(1).optional(),
|
||||||
AUTH_URL: z.preprocess(
|
|
||||||
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
|
|
||||||
// Since NextAuth.js automatically uses the VERCEL_URL if present.
|
|
||||||
(str) => process.env.VERCEL_URL ?? str,
|
|
||||||
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
|
|
||||||
process.env.VERCEL ? z.string() : z.string().url(),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
client: {},
|
client: {},
|
||||||
runtimeEnv: {
|
runtimeEnv: {
|
||||||
AUTH_SECRET: process.env.AUTH_SECRET,
|
AUTH_SECRET: process.env.AUTH_SECRET,
|
||||||
AUTH_URL: process.env.AUTH_URL,
|
|
||||||
},
|
},
|
||||||
skipValidation:
|
skipValidation:
|
||||||
Boolean(process.env.CI) || Boolean(process.env.SKIP_ENV_VALIDATION),
|
Boolean(process.env.CI) || Boolean(process.env.SKIP_ENV_VALIDATION),
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"@t3-oss/env-nextjs": "^0.9.2",
|
"@t3-oss/env-nextjs": "^0.9.2",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"cookies": "^0.9.1",
|
"cookies": "^0.9.1",
|
||||||
"next": "^14.1.0",
|
"next": "^14.1.1-canary.58",
|
||||||
"next-auth": "5.0.0-beta.11",
|
"next-auth": "5.0.0-beta.11",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "18.2.0"
|
||||||
|
|||||||
7464
pnpm-lock.yaml
generated
7464
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user