create-croissant 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/api/index.mjs +29 -3
- package/template/apps/web/node_modules/@better-auth/core/dist/context/global.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/factory.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/api.mjs +1 -31
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/noop.mjs +42 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/pure.index.d.mts +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/pure.index.mjs +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/tracer.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/index.d.mts +2 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/index.mjs +2 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/utils.d.mts +10 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/utils.mjs +13 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/apple.d.mts +11 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/apple.mjs +7 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/atlassian.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/cognito.d.mts +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/cognito.mjs +3 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/facebook.d.mts +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/facebook.mjs +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/figma.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/google.d.mts +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/google.mjs +3 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/microsoft-entra-id.d.mts +2 -2
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/microsoft-entra-id.mjs +6 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paybin.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paypal.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/salesforce.mjs +1 -1
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/is-api-error.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/is-api-error.mjs +8 -0
- package/template/apps/web/node_modules/@better-auth/core/package.json +7 -1
- package/template/apps/web/node_modules/@better-auth/core/src/api/index.ts +39 -5
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/api.ts +2 -49
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/noop.ts +74 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/pure.index.ts +31 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/index.ts +5 -1
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/utils.ts +13 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/apple.ts +10 -2
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/cognito.ts +3 -2
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/facebook.ts +10 -1
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/google.ts +3 -2
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/microsoft-entra-id.ts +13 -3
- package/template/apps/web/node_modules/@better-auth/core/src/utils/is-api-error.ts +10 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/package.json +3 -3
- package/template/apps/web/package.json +4 -4
- package/template/apps/web/src/components/app-sidebar.tsx +77 -121
- package/template/apps/web/src/routeTree.gen.ts +112 -1
- package/template/apps/web/src/routes/__root.tsx +13 -1
- package/template/apps/web/src/routes/client-orpc-auth.tsx +62 -0
- package/template/apps/web/src/routes/client-orpc.tsx +43 -0
- package/template/apps/web/src/routes/isr.tsx +33 -0
- package/template/apps/web/src/routes/ssr-orpc-auth.tsx +53 -0
- package/template/apps/web/src/routes/ssr-orpc.tsx +36 -0
- package/template/package.json +2 -2
- package/template/packages/auth/package.json +1 -1
- package/template/packages/orpc/package.json +2 -4
|
@@ -9,13 +9,28 @@
|
|
|
9
9
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
10
|
|
|
11
11
|
import { Route as rootRouteImport } from './routes/__root'
|
|
12
|
+
import { Route as SsrOrpcAuthRouteImport } from './routes/ssr-orpc-auth'
|
|
13
|
+
import { Route as SsrOrpcRouteImport } from './routes/ssr-orpc'
|
|
12
14
|
import { Route as SignupRouteImport } from './routes/signup'
|
|
13
15
|
import { Route as LoginRouteImport } from './routes/login'
|
|
16
|
+
import { Route as IsrRouteImport } from './routes/isr'
|
|
14
17
|
import { Route as DashboardRouteImport } from './routes/dashboard'
|
|
18
|
+
import { Route as ClientOrpcAuthRouteImport } from './routes/client-orpc-auth'
|
|
19
|
+
import { Route as ClientOrpcRouteImport } from './routes/client-orpc'
|
|
15
20
|
import { Route as IndexRouteImport } from './routes/index'
|
|
16
21
|
import { Route as ApiRpcSplatRouteImport } from './routes/api/rpc.$'
|
|
17
22
|
import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
|
|
18
23
|
|
|
24
|
+
const SsrOrpcAuthRoute = SsrOrpcAuthRouteImport.update({
|
|
25
|
+
id: '/ssr-orpc-auth',
|
|
26
|
+
path: '/ssr-orpc-auth',
|
|
27
|
+
getParentRoute: () => rootRouteImport,
|
|
28
|
+
} as any)
|
|
29
|
+
const SsrOrpcRoute = SsrOrpcRouteImport.update({
|
|
30
|
+
id: '/ssr-orpc',
|
|
31
|
+
path: '/ssr-orpc',
|
|
32
|
+
getParentRoute: () => rootRouteImport,
|
|
33
|
+
} as any)
|
|
19
34
|
const SignupRoute = SignupRouteImport.update({
|
|
20
35
|
id: '/signup',
|
|
21
36
|
path: '/signup',
|
|
@@ -26,11 +41,26 @@ const LoginRoute = LoginRouteImport.update({
|
|
|
26
41
|
path: '/login',
|
|
27
42
|
getParentRoute: () => rootRouteImport,
|
|
28
43
|
} as any)
|
|
44
|
+
const IsrRoute = IsrRouteImport.update({
|
|
45
|
+
id: '/isr',
|
|
46
|
+
path: '/isr',
|
|
47
|
+
getParentRoute: () => rootRouteImport,
|
|
48
|
+
} as any)
|
|
29
49
|
const DashboardRoute = DashboardRouteImport.update({
|
|
30
50
|
id: '/dashboard',
|
|
31
51
|
path: '/dashboard',
|
|
32
52
|
getParentRoute: () => rootRouteImport,
|
|
33
53
|
} as any)
|
|
54
|
+
const ClientOrpcAuthRoute = ClientOrpcAuthRouteImport.update({
|
|
55
|
+
id: '/client-orpc-auth',
|
|
56
|
+
path: '/client-orpc-auth',
|
|
57
|
+
getParentRoute: () => rootRouteImport,
|
|
58
|
+
} as any)
|
|
59
|
+
const ClientOrpcRoute = ClientOrpcRouteImport.update({
|
|
60
|
+
id: '/client-orpc',
|
|
61
|
+
path: '/client-orpc',
|
|
62
|
+
getParentRoute: () => rootRouteImport,
|
|
63
|
+
} as any)
|
|
34
64
|
const IndexRoute = IndexRouteImport.update({
|
|
35
65
|
id: '/',
|
|
36
66
|
path: '/',
|
|
@@ -49,26 +79,41 @@ const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
|
|
|
49
79
|
|
|
50
80
|
export interface FileRoutesByFullPath {
|
|
51
81
|
'/': typeof IndexRoute
|
|
82
|
+
'/client-orpc': typeof ClientOrpcRoute
|
|
83
|
+
'/client-orpc-auth': typeof ClientOrpcAuthRoute
|
|
52
84
|
'/dashboard': typeof DashboardRoute
|
|
85
|
+
'/isr': typeof IsrRoute
|
|
53
86
|
'/login': typeof LoginRoute
|
|
54
87
|
'/signup': typeof SignupRoute
|
|
88
|
+
'/ssr-orpc': typeof SsrOrpcRoute
|
|
89
|
+
'/ssr-orpc-auth': typeof SsrOrpcAuthRoute
|
|
55
90
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
56
91
|
'/api/rpc/$': typeof ApiRpcSplatRoute
|
|
57
92
|
}
|
|
58
93
|
export interface FileRoutesByTo {
|
|
59
94
|
'/': typeof IndexRoute
|
|
95
|
+
'/client-orpc': typeof ClientOrpcRoute
|
|
96
|
+
'/client-orpc-auth': typeof ClientOrpcAuthRoute
|
|
60
97
|
'/dashboard': typeof DashboardRoute
|
|
98
|
+
'/isr': typeof IsrRoute
|
|
61
99
|
'/login': typeof LoginRoute
|
|
62
100
|
'/signup': typeof SignupRoute
|
|
101
|
+
'/ssr-orpc': typeof SsrOrpcRoute
|
|
102
|
+
'/ssr-orpc-auth': typeof SsrOrpcAuthRoute
|
|
63
103
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
64
104
|
'/api/rpc/$': typeof ApiRpcSplatRoute
|
|
65
105
|
}
|
|
66
106
|
export interface FileRoutesById {
|
|
67
107
|
__root__: typeof rootRouteImport
|
|
68
108
|
'/': typeof IndexRoute
|
|
109
|
+
'/client-orpc': typeof ClientOrpcRoute
|
|
110
|
+
'/client-orpc-auth': typeof ClientOrpcAuthRoute
|
|
69
111
|
'/dashboard': typeof DashboardRoute
|
|
112
|
+
'/isr': typeof IsrRoute
|
|
70
113
|
'/login': typeof LoginRoute
|
|
71
114
|
'/signup': typeof SignupRoute
|
|
115
|
+
'/ssr-orpc': typeof SsrOrpcRoute
|
|
116
|
+
'/ssr-orpc-auth': typeof SsrOrpcAuthRoute
|
|
72
117
|
'/api/auth/$': typeof ApiAuthSplatRoute
|
|
73
118
|
'/api/rpc/$': typeof ApiRpcSplatRoute
|
|
74
119
|
}
|
|
@@ -76,34 +121,74 @@ export interface FileRouteTypes {
|
|
|
76
121
|
fileRoutesByFullPath: FileRoutesByFullPath
|
|
77
122
|
fullPaths:
|
|
78
123
|
| '/'
|
|
124
|
+
| '/client-orpc'
|
|
125
|
+
| '/client-orpc-auth'
|
|
79
126
|
| '/dashboard'
|
|
127
|
+
| '/isr'
|
|
80
128
|
| '/login'
|
|
81
129
|
| '/signup'
|
|
130
|
+
| '/ssr-orpc'
|
|
131
|
+
| '/ssr-orpc-auth'
|
|
82
132
|
| '/api/auth/$'
|
|
83
133
|
| '/api/rpc/$'
|
|
84
134
|
fileRoutesByTo: FileRoutesByTo
|
|
85
|
-
to:
|
|
135
|
+
to:
|
|
136
|
+
| '/'
|
|
137
|
+
| '/client-orpc'
|
|
138
|
+
| '/client-orpc-auth'
|
|
139
|
+
| '/dashboard'
|
|
140
|
+
| '/isr'
|
|
141
|
+
| '/login'
|
|
142
|
+
| '/signup'
|
|
143
|
+
| '/ssr-orpc'
|
|
144
|
+
| '/ssr-orpc-auth'
|
|
145
|
+
| '/api/auth/$'
|
|
146
|
+
| '/api/rpc/$'
|
|
86
147
|
id:
|
|
87
148
|
| '__root__'
|
|
88
149
|
| '/'
|
|
150
|
+
| '/client-orpc'
|
|
151
|
+
| '/client-orpc-auth'
|
|
89
152
|
| '/dashboard'
|
|
153
|
+
| '/isr'
|
|
90
154
|
| '/login'
|
|
91
155
|
| '/signup'
|
|
156
|
+
| '/ssr-orpc'
|
|
157
|
+
| '/ssr-orpc-auth'
|
|
92
158
|
| '/api/auth/$'
|
|
93
159
|
| '/api/rpc/$'
|
|
94
160
|
fileRoutesById: FileRoutesById
|
|
95
161
|
}
|
|
96
162
|
export interface RootRouteChildren {
|
|
97
163
|
IndexRoute: typeof IndexRoute
|
|
164
|
+
ClientOrpcRoute: typeof ClientOrpcRoute
|
|
165
|
+
ClientOrpcAuthRoute: typeof ClientOrpcAuthRoute
|
|
98
166
|
DashboardRoute: typeof DashboardRoute
|
|
167
|
+
IsrRoute: typeof IsrRoute
|
|
99
168
|
LoginRoute: typeof LoginRoute
|
|
100
169
|
SignupRoute: typeof SignupRoute
|
|
170
|
+
SsrOrpcRoute: typeof SsrOrpcRoute
|
|
171
|
+
SsrOrpcAuthRoute: typeof SsrOrpcAuthRoute
|
|
101
172
|
ApiAuthSplatRoute: typeof ApiAuthSplatRoute
|
|
102
173
|
ApiRpcSplatRoute: typeof ApiRpcSplatRoute
|
|
103
174
|
}
|
|
104
175
|
|
|
105
176
|
declare module '@tanstack/react-router' {
|
|
106
177
|
interface FileRoutesByPath {
|
|
178
|
+
'/ssr-orpc-auth': {
|
|
179
|
+
id: '/ssr-orpc-auth'
|
|
180
|
+
path: '/ssr-orpc-auth'
|
|
181
|
+
fullPath: '/ssr-orpc-auth'
|
|
182
|
+
preLoaderRoute: typeof SsrOrpcAuthRouteImport
|
|
183
|
+
parentRoute: typeof rootRouteImport
|
|
184
|
+
}
|
|
185
|
+
'/ssr-orpc': {
|
|
186
|
+
id: '/ssr-orpc'
|
|
187
|
+
path: '/ssr-orpc'
|
|
188
|
+
fullPath: '/ssr-orpc'
|
|
189
|
+
preLoaderRoute: typeof SsrOrpcRouteImport
|
|
190
|
+
parentRoute: typeof rootRouteImport
|
|
191
|
+
}
|
|
107
192
|
'/signup': {
|
|
108
193
|
id: '/signup'
|
|
109
194
|
path: '/signup'
|
|
@@ -118,6 +203,13 @@ declare module '@tanstack/react-router' {
|
|
|
118
203
|
preLoaderRoute: typeof LoginRouteImport
|
|
119
204
|
parentRoute: typeof rootRouteImport
|
|
120
205
|
}
|
|
206
|
+
'/isr': {
|
|
207
|
+
id: '/isr'
|
|
208
|
+
path: '/isr'
|
|
209
|
+
fullPath: '/isr'
|
|
210
|
+
preLoaderRoute: typeof IsrRouteImport
|
|
211
|
+
parentRoute: typeof rootRouteImport
|
|
212
|
+
}
|
|
121
213
|
'/dashboard': {
|
|
122
214
|
id: '/dashboard'
|
|
123
215
|
path: '/dashboard'
|
|
@@ -125,6 +217,20 @@ declare module '@tanstack/react-router' {
|
|
|
125
217
|
preLoaderRoute: typeof DashboardRouteImport
|
|
126
218
|
parentRoute: typeof rootRouteImport
|
|
127
219
|
}
|
|
220
|
+
'/client-orpc-auth': {
|
|
221
|
+
id: '/client-orpc-auth'
|
|
222
|
+
path: '/client-orpc-auth'
|
|
223
|
+
fullPath: '/client-orpc-auth'
|
|
224
|
+
preLoaderRoute: typeof ClientOrpcAuthRouteImport
|
|
225
|
+
parentRoute: typeof rootRouteImport
|
|
226
|
+
}
|
|
227
|
+
'/client-orpc': {
|
|
228
|
+
id: '/client-orpc'
|
|
229
|
+
path: '/client-orpc'
|
|
230
|
+
fullPath: '/client-orpc'
|
|
231
|
+
preLoaderRoute: typeof ClientOrpcRouteImport
|
|
232
|
+
parentRoute: typeof rootRouteImport
|
|
233
|
+
}
|
|
128
234
|
'/': {
|
|
129
235
|
id: '/'
|
|
130
236
|
path: '/'
|
|
@@ -151,9 +257,14 @@ declare module '@tanstack/react-router' {
|
|
|
151
257
|
|
|
152
258
|
const rootRouteChildren: RootRouteChildren = {
|
|
153
259
|
IndexRoute: IndexRoute,
|
|
260
|
+
ClientOrpcRoute: ClientOrpcRoute,
|
|
261
|
+
ClientOrpcAuthRoute: ClientOrpcAuthRoute,
|
|
154
262
|
DashboardRoute: DashboardRoute,
|
|
263
|
+
IsrRoute: IsrRoute,
|
|
155
264
|
LoginRoute: LoginRoute,
|
|
156
265
|
SignupRoute: SignupRoute,
|
|
266
|
+
SsrOrpcRoute: SsrOrpcRoute,
|
|
267
|
+
SsrOrpcAuthRoute: SsrOrpcAuthRoute,
|
|
157
268
|
ApiAuthSplatRoute: ApiAuthSplatRoute,
|
|
158
269
|
ApiRpcSplatRoute: ApiRpcSplatRoute,
|
|
159
270
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router"
|
|
2
|
+
import { SidebarProvider, SidebarTrigger } from "@workspace/ui/components/sidebar"
|
|
2
3
|
|
|
3
4
|
import appCss from "@workspace/ui/globals.css?url"
|
|
5
|
+
import { AppSidebar } from "@/components/app-sidebar"
|
|
4
6
|
|
|
5
7
|
export const Route = createRootRoute({
|
|
6
8
|
head: () => ({
|
|
@@ -33,7 +35,17 @@ function RootDocument({ children }: { children: React.ReactNode }) {
|
|
|
33
35
|
<HeadContent />
|
|
34
36
|
</head>
|
|
35
37
|
<body>
|
|
36
|
-
|
|
38
|
+
<SidebarProvider>
|
|
39
|
+
<AppSidebar />
|
|
40
|
+
<main className="flex flex-1 flex-col overflow-hidden">
|
|
41
|
+
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
|
42
|
+
<SidebarTrigger />
|
|
43
|
+
</header>
|
|
44
|
+
<div className="flex-1 overflow-auto p-4">
|
|
45
|
+
{children}
|
|
46
|
+
</div>
|
|
47
|
+
</main>
|
|
48
|
+
</SidebarProvider>
|
|
37
49
|
<Scripts />
|
|
38
50
|
</body>
|
|
39
51
|
</html>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
3
|
+
import { getSessionFn } from "../lib/auth-utils"
|
|
4
|
+
import { orpc } from "../lib/orpc"
|
|
5
|
+
|
|
6
|
+
export const Route = createFileRoute("/client-orpc-auth")({
|
|
7
|
+
beforeLoad: async () => {
|
|
8
|
+
const session = await getSessionFn()
|
|
9
|
+
if (!session) {
|
|
10
|
+
throw redirect({
|
|
11
|
+
to: "/login",
|
|
12
|
+
search: {
|
|
13
|
+
redirect: "/client-orpc-auth",
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
return { session }
|
|
18
|
+
},
|
|
19
|
+
component: ClientORPCAuth,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
function ClientORPCAuth() {
|
|
23
|
+
const { session } = Route.useRouteContext()
|
|
24
|
+
const [data, setData] = React.useState<any>(null)
|
|
25
|
+
const [loading, setLoading] = React.useState(true)
|
|
26
|
+
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
const fetchData = async () => {
|
|
29
|
+
try {
|
|
30
|
+
const res = await orpc.getSecretData()
|
|
31
|
+
setData(res)
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.error(err)
|
|
34
|
+
} finally {
|
|
35
|
+
setLoading(false)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fetchData()
|
|
40
|
+
}, [])
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className="flex flex-col gap-4">
|
|
44
|
+
<h1 className="text-2xl font-bold">Client + oRPC (Authenticated)</h1>
|
|
45
|
+
<p>This page is protected and fetches secret data on the client.</p>
|
|
46
|
+
|
|
47
|
+
<div className="rounded-lg border p-4">
|
|
48
|
+
<h2 className="font-semibold">User Session:</h2>
|
|
49
|
+
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(session, null, 2)}</pre>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div className="rounded-lg border p-4">
|
|
53
|
+
<h2 className="font-semibold">Secret Data (Client-side):</h2>
|
|
54
|
+
{loading ? (
|
|
55
|
+
<p>Loading...</p>
|
|
56
|
+
) : (
|
|
57
|
+
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(data, null, 2)}</pre>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
3
|
+
import { orpc } from "../lib/orpc"
|
|
4
|
+
|
|
5
|
+
export const Route = createFileRoute("/client-orpc")({
|
|
6
|
+
component: ClientORPC,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
function ClientORPC() {
|
|
10
|
+
const [data, setData] = React.useState<any>(null)
|
|
11
|
+
const [loading, setLoading] = React.useState(true)
|
|
12
|
+
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
const fetchData = async () => {
|
|
15
|
+
try {
|
|
16
|
+
const res = await orpc.hello({ name: "Client User" })
|
|
17
|
+
setData(res)
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error(err)
|
|
20
|
+
} finally {
|
|
21
|
+
setLoading(false)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fetchData()
|
|
26
|
+
}, [])
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="flex flex-col gap-4">
|
|
30
|
+
<h1 className="text-2xl font-bold">Client + oRPC Example</h1>
|
|
31
|
+
<p>This page fetches data on the client using the oRPC client.</p>
|
|
32
|
+
|
|
33
|
+
<div className="rounded-lg border p-4">
|
|
34
|
+
<h2 className="font-semibold">Message from oRPC (Client-side):</h2>
|
|
35
|
+
{loading ? (
|
|
36
|
+
<p>Loading...</p>
|
|
37
|
+
) : (
|
|
38
|
+
<p>{data?.message}</p>
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
2
|
+
|
|
3
|
+
export const Route = createFileRoute("/isr")({
|
|
4
|
+
loader: () => {
|
|
5
|
+
// In a real ISR scenario, this would be cached on the server
|
|
6
|
+
// For this example, we'll just show the time it was "generated"
|
|
7
|
+
return {
|
|
8
|
+
generatedAt: new Date().toISOString(),
|
|
9
|
+
message: "This page is an example of ISR. In a production build with proper configuration, this data would be cached and updated in the background.",
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
component: ISRExample,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
function ISRExample() {
|
|
16
|
+
const { generatedAt, message } = Route.useLoaderData()
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex flex-col gap-4">
|
|
20
|
+
<h1 className="text-2xl font-bold">ISR Example</h1>
|
|
21
|
+
<p>{message}</p>
|
|
22
|
+
|
|
23
|
+
<div className="rounded-lg border p-4">
|
|
24
|
+
<h2 className="font-semibold">Generated At:</h2>
|
|
25
|
+
<p className="font-mono">{generatedAt}</p>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<p className="text-sm text-muted-foreground">
|
|
29
|
+
Refresh the page to see if the time updates. In a true ISR setup, it would only update after a certain interval.
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
2
|
+
import { getSessionFn } from "../lib/auth-utils"
|
|
3
|
+
import { orpc } from "../lib/orpc"
|
|
4
|
+
|
|
5
|
+
export const Route = createFileRoute("/ssr-orpc-auth")({
|
|
6
|
+
beforeLoad: async () => {
|
|
7
|
+
const session = await getSessionFn()
|
|
8
|
+
if (!session) {
|
|
9
|
+
throw redirect({
|
|
10
|
+
to: "/login",
|
|
11
|
+
search: {
|
|
12
|
+
redirect: "/ssr-orpc-auth",
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
return { session }
|
|
17
|
+
},
|
|
18
|
+
loader: async () => {
|
|
19
|
+
try {
|
|
20
|
+
const secretData = await orpc.getSecretData()
|
|
21
|
+
return { secretData }
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return { secretData: null, error: "Failed to fetch secret data" }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
component: SSRORPCAuth,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
function SSRORPCAuth() {
|
|
30
|
+
const { session } = Route.useRouteContext()
|
|
31
|
+
const { secretData, error } = Route.useLoaderData()
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div className="flex flex-col gap-4">
|
|
35
|
+
<h1 className="text-2xl font-bold">SSR + oRPC (Authenticated)</h1>
|
|
36
|
+
<p>This page is protected and fetches secret data on the server.</p>
|
|
37
|
+
|
|
38
|
+
<div className="rounded-lg border p-4">
|
|
39
|
+
<h2 className="font-semibold">User Session:</h2>
|
|
40
|
+
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(session, null, 2)}</pre>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div className="rounded-lg border p-4">
|
|
44
|
+
<h2 className="font-semibold">Secret Data:</h2>
|
|
45
|
+
{error ? (
|
|
46
|
+
<p className="text-destructive">{error}</p>
|
|
47
|
+
) : (
|
|
48
|
+
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(secretData, null, 2)}</pre>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
2
|
+
import { orpc } from "../lib/orpc"
|
|
3
|
+
|
|
4
|
+
export const Route = createFileRoute("/ssr-orpc")({
|
|
5
|
+
loader: async () => {
|
|
6
|
+
const data = await orpc.hello({ name: "SSR User" })
|
|
7
|
+
const planets = await orpc.getPlanets()
|
|
8
|
+
return { data, planets }
|
|
9
|
+
},
|
|
10
|
+
component: SSRORPC,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
function SSRORPC() {
|
|
14
|
+
const { data, planets } = Route.useLoaderData()
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="flex flex-col gap-4">
|
|
18
|
+
<h1 className="text-2xl font-bold">SSR + oRPC Example</h1>
|
|
19
|
+
<p>This page fetches data on the server using oRPC in a loader.</p>
|
|
20
|
+
|
|
21
|
+
<div className="rounded-lg border p-4">
|
|
22
|
+
<h2 className="font-semibold">Message from oRPC:</h2>
|
|
23
|
+
<p>{data.message}</p>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div className="rounded-lg border p-4">
|
|
27
|
+
<h2 className="font-semibold">Planets from DB:</h2>
|
|
28
|
+
<ul className="list-disc ml-6">
|
|
29
|
+
{planets.map((planet) => (
|
|
30
|
+
<li key={planet.id}>{planet.name}</li>
|
|
31
|
+
))}
|
|
32
|
+
</ul>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
package/template/package.json
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"update-deps": "npx npm-check-updates -u -w --root && npm install"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@tanstack/eslint-config": "0.
|
|
18
|
-
"eslint": "
|
|
17
|
+
"@tanstack/eslint-config": "0.4.0",
|
|
18
|
+
"eslint": "10.2.1",
|
|
19
19
|
"prettier": "^3.8.1",
|
|
20
20
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
21
21
|
"turbo": "^2.8.17",
|
|
@@ -9,14 +9,12 @@
|
|
|
9
9
|
"typecheck": "tsc --noEmit"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@orpc/client": "
|
|
13
|
-
"@orpc/server": "
|
|
12
|
+
"@orpc/client": "^1.14.0",
|
|
13
|
+
"@orpc/server": "^1.14.0",
|
|
14
14
|
"@workspace/auth": "*",
|
|
15
15
|
"@workspace/db": "*",
|
|
16
16
|
"zod": "^4.3.6"
|
|
17
17
|
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
},
|
|
20
18
|
"exports": {
|
|
21
19
|
"./router": "./src/lib/router.ts"
|
|
22
20
|
}
|