create-better-t-stack 3.11.1 → 3.12.0
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/dist/chunk-Dt3mZKp0.mjs +24 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +40 -60
- package/dist/index.mjs +2 -2
- package/dist/{src-Dc2OdxbP.mjs → src-DBVnwTkj.mjs} +644 -609
- package/package.json +2 -2
- package/templates/addons/turborepo/turbo.json.hbs +8 -0
- package/templates/api/orpc/native/utils/orpc.ts.hbs +21 -20
- package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +3 -5
- package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +73 -67
- package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +15 -14
- package/templates/api/trpc/native/utils/trpc.ts.hbs +8 -7
- package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +59 -57
- package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +10 -9
- package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +10 -9
- package/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs +5 -4
- package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +8 -7
- package/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs +9 -8
- package/templates/auth/better-auth/server/base/src/index.ts.hbs +239 -235
- package/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs +2 -3
- package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +9 -11
- package/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs +3 -2
- package/templates/backend/server/elysia/src/index.ts.hbs +71 -71
- package/templates/backend/server/express/src/index.ts.hbs +57 -57
- package/templates/backend/server/fastify/src/index.ts.hbs +107 -107
- package/templates/backend/server/hono/src/index.ts.hbs +75 -85
- package/templates/base/tsconfig.json.hbs +3 -0
- package/templates/db/drizzle/mysql/src/index.ts.hbs +23 -30
- package/templates/db/drizzle/postgres/src/index.ts.hbs +6 -13
- package/templates/db/drizzle/sqlite/src/index.ts.hbs +11 -18
- package/templates/db/mongoose/mongodb/src/index.ts.hbs +3 -2
- package/templates/db/prisma/mongodb/prisma/schema/schema.prisma.hbs +1 -1
- package/templates/db/prisma/mysql/prisma/schema/schema.prisma.hbs +1 -1
- package/templates/db/prisma/mysql/prisma.config.ts.hbs +16 -16
- package/templates/db/prisma/mysql/src/index.ts.hbs +16 -15
- package/templates/db/prisma/postgres/prisma/schema/schema.prisma.hbs +1 -1
- package/templates/db/prisma/postgres/src/index.ts.hbs +10 -9
- package/templates/db/prisma/sqlite/prisma/schema/schema.prisma.hbs +1 -1
- package/templates/db/prisma/sqlite/src/index.ts.hbs +4 -7
- package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +2 -1
- package/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs +2 -1
- package/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs +2 -1
- package/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs +1 -3
- package/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs +4 -3
- package/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs +2 -1
- package/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs +4 -1
- package/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs +4 -1
- package/templates/frontend/native/bare/app/_layout.tsx.hbs +4 -2
- package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +4 -2
- package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +4 -3
- package/templates/frontend/nuxt/nuxt.config.ts.hbs +6 -3
- package/templates/frontend/react/next/next.config.ts.hbs +9 -8
- package/templates/frontend/react/next/src/components/providers.tsx.hbs +4 -1
- package/templates/frontend/react/next/tsconfig.json.hbs +2 -2
- package/templates/frontend/react/react-router/src/root.tsx.hbs +3 -4
- package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +3 -2
- package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +97 -93
- package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +23 -3
- package/templates/packages/config/tsconfig.base.json.hbs +1 -1
- package/templates/{deploy/alchemy → packages/env}/env.d.ts.hbs +6 -4
- package/templates/packages/env/package.json.hbs +7 -0
- package/templates/packages/env/src/native.ts.hbs +21 -0
- package/templates/packages/env/src/server.ts.hbs +38 -0
- package/templates/packages/env/src/web.ts.hbs +89 -0
- package/templates/packages/env/tsconfig.json.hbs +3 -0
- package/templates/{deploy/alchemy → packages/infra}/alchemy.run.ts.hbs +84 -80
- package/templates/packages/infra/package.json.hbs +10 -0
- package/templates/payments/polar/server/base/src/lib/payments.ts.hbs +3 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import { env } from "@{{projectName}}/env/server";
|
|
2
2
|
{{#if (eq runtime "node")}}
|
|
3
3
|
import { node } from "@elysiajs/node";
|
|
4
4
|
{{/if}}
|
|
@@ -28,23 +28,23 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
28
28
|
|
|
29
29
|
{{#if (eq api "orpc")}}
|
|
30
30
|
const rpcHandler = new RPCHandler(appRouter, {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
interceptors: [
|
|
32
|
+
onError((error) => {
|
|
33
|
+
console.error(error);
|
|
34
|
+
}),
|
|
35
|
+
],
|
|
36
36
|
});
|
|
37
37
|
const apiHandler = new OpenAPIHandler(appRouter, {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
plugins: [
|
|
39
|
+
new OpenAPIReferencePlugin({
|
|
40
|
+
schemaConverters: [new ZodToJsonSchemaConverter()],
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
interceptors: [
|
|
44
|
+
onError((error) => {
|
|
45
|
+
console.error(error);
|
|
46
|
+
}),
|
|
47
|
+
],
|
|
48
48
|
});
|
|
49
49
|
{{/if}}
|
|
50
50
|
|
|
@@ -53,65 +53,65 @@ const app = new Elysia({ adapter: node() })
|
|
|
53
53
|
{{else}}
|
|
54
54
|
const app = new Elysia()
|
|
55
55
|
{{/if}}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
.use(
|
|
57
|
+
cors({
|
|
58
|
+
origin: env.CORS_ORIGIN,
|
|
59
|
+
methods: ["GET", "POST", "OPTIONS"],
|
|
60
|
+
{{#if (eq auth "better-auth")}}
|
|
61
|
+
allowedHeaders: ["Content-Type", "Authorization"],
|
|
62
|
+
credentials: true,
|
|
63
|
+
{{/if}}
|
|
64
|
+
}),
|
|
65
|
+
)
|
|
66
|
+
{{#if (eq auth "better-auth")}}
|
|
67
|
+
.all("/api/auth/*", async (context) => {
|
|
68
|
+
const { request, status } = context;
|
|
69
|
+
if (["POST", "GET"].includes(request.method)) {
|
|
70
|
+
return auth.handler(request);
|
|
71
|
+
}
|
|
72
|
+
return status(405)
|
|
73
|
+
})
|
|
74
|
+
{{/if}}
|
|
75
75
|
{{#if (eq api "orpc")}}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
.all('/rpc*', async (context) => {
|
|
77
|
+
const { response } = await rpcHandler.handle(context.request, {
|
|
78
|
+
prefix: '/rpc',
|
|
79
|
+
context: await createContext({ context })
|
|
80
|
+
})
|
|
81
|
+
return response ?? new Response('Not Found', { status: 404 })
|
|
82
|
+
})
|
|
83
|
+
.all('/api*', async (context) => {
|
|
84
|
+
const { response } = await apiHandler.handle(context.request, {
|
|
85
|
+
prefix: '/api-reference',
|
|
86
|
+
context: await createContext({ context })
|
|
87
|
+
})
|
|
88
|
+
return response ?? new Response('Not Found', { status: 404 })
|
|
89
|
+
})
|
|
90
90
|
{{/if}}
|
|
91
91
|
{{#if (eq api "trpc")}}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
.all("/trpc/*", async (context) => {
|
|
93
|
+
const res = await fetchRequestHandler({
|
|
94
|
+
endpoint: "/trpc",
|
|
95
|
+
router: appRouter,
|
|
96
|
+
req: context.request,
|
|
97
|
+
createContext: () => createContext({ context }),
|
|
98
|
+
});
|
|
99
|
+
return res;
|
|
100
|
+
})
|
|
101
101
|
{{/if}}
|
|
102
102
|
{{#if (includes examples "ai")}}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
.post("/ai", async (context) => {
|
|
104
|
+
const body = await context.request.json();
|
|
105
|
+
const uiMessages = body.messages || [];
|
|
106
|
+
const result = streamText({
|
|
107
|
+
model: google("gemini-2.5-flash"),
|
|
108
|
+
messages: convertToModelMessages(uiMessages)
|
|
109
|
+
});
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
return result.toUIMessageStreamResponse();
|
|
112
|
+
})
|
|
113
113
|
{{/if}}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
.get("/", () => "OK")
|
|
115
|
+
.listen(3000, () => {
|
|
116
|
+
console.log("Server is running on http://localhost:3000");
|
|
117
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import { env } from "@{{projectName}}/env/server";
|
|
2
2
|
{{#if (eq api "trpc")}}
|
|
3
3
|
import { createExpressMiddleware } from "@trpc/server/adapters/express";
|
|
4
4
|
import { createContext } from "@{{projectName}}/api/context";
|
|
@@ -29,14 +29,14 @@ import { toNodeHandler } from "better-auth/node";
|
|
|
29
29
|
const app = express();
|
|
30
30
|
|
|
31
31
|
app.use(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
cors({
|
|
33
|
+
origin: env.CORS_ORIGIN,
|
|
34
|
+
methods: ["GET", "POST", "OPTIONS"],
|
|
35
|
+
{{#if (eq auth "better-auth")}}
|
|
36
|
+
allowedHeaders: ["Content-Type", "Authorization"],
|
|
37
|
+
credentials: true,
|
|
38
|
+
{{/if}}
|
|
39
|
+
})
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
{{#if (eq auth "better-auth")}}
|
|
@@ -45,57 +45,57 @@ app.all("/api/auth{/*path}", toNodeHandler(auth));
|
|
|
45
45
|
|
|
46
46
|
{{#if (eq api "trpc")}}
|
|
47
47
|
app.use(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
"/trpc",
|
|
49
|
+
createExpressMiddleware({
|
|
50
|
+
router: appRouter,
|
|
51
|
+
createContext,
|
|
52
|
+
})
|
|
53
53
|
);
|
|
54
54
|
{{/if}}
|
|
55
55
|
|
|
56
56
|
{{#if (eq api "orpc")}}
|
|
57
57
|
const rpcHandler = new RPCHandler(appRouter, {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
interceptors: [
|
|
59
|
+
onError((error) => {
|
|
60
|
+
console.error(error);
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
63
|
});
|
|
64
64
|
const apiHandler = new OpenAPIHandler(appRouter, {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
plugins: [
|
|
66
|
+
new OpenAPIReferencePlugin({
|
|
67
|
+
schemaConverters: [new ZodToJsonSchemaConverter()],
|
|
68
|
+
}),
|
|
69
|
+
],
|
|
70
|
+
interceptors: [
|
|
71
|
+
onError((error) => {
|
|
72
|
+
console.error(error);
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
app.use(async (req, res, next) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
const rpcResult = await rpcHandler.handle(req, res, {
|
|
79
|
+
prefix: "/rpc",
|
|
80
|
+
{{#if (eq auth "better-auth")}}
|
|
81
|
+
context: await createContext({ req }),
|
|
82
|
+
{{else}}
|
|
83
|
+
context: {},
|
|
84
|
+
{{/if}}
|
|
85
|
+
});
|
|
86
|
+
if (rpcResult.matched) return;
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
const apiResult = await apiHandler.handle(req, res, {
|
|
89
|
+
prefix: "/api-reference",
|
|
90
|
+
{{#if (eq auth "better-auth")}}
|
|
91
|
+
context: await createContext({ req }),
|
|
92
|
+
{{else}}
|
|
93
|
+
context: {},
|
|
94
|
+
{{/if}}
|
|
95
|
+
});
|
|
96
|
+
if (apiResult.matched) return;
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
next();
|
|
99
99
|
});
|
|
100
100
|
{{/if}}
|
|
101
101
|
|
|
@@ -103,20 +103,20 @@ app.use(express.json());
|
|
|
103
103
|
|
|
104
104
|
{{#if (includes examples "ai")}}
|
|
105
105
|
app.post("/ai", async (req, res) => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
const { messages = [] } = (req.body || {}) as { messages: UIMessage[] };
|
|
107
|
+
const result = streamText({
|
|
108
|
+
model: google("gemini-2.5-flash"),
|
|
109
|
+
messages: convertToModelMessages(messages),
|
|
110
|
+
});
|
|
111
|
+
result.pipeUIMessageStreamToResponse(res);
|
|
112
112
|
});
|
|
113
113
|
{{/if}}
|
|
114
114
|
|
|
115
115
|
app.get("/", (_req, res) => {
|
|
116
|
-
|
|
116
|
+
res.status(200).send("OK");
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
const port =
|
|
119
|
+
const port = env.PORT;
|
|
120
120
|
app.listen(port, () => {
|
|
121
|
-
|
|
121
|
+
console.log(`Server is running on port ${port}`);
|
|
122
122
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import { env } from "@{{projectName}}/env/server";
|
|
2
2
|
import Fastify from "fastify";
|
|
3
3
|
import fastifyCors from "@fastify/cors";
|
|
4
4
|
|
|
@@ -32,77 +32,77 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
32
32
|
{{/if}}
|
|
33
33
|
|
|
34
34
|
const baseCorsConfig = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
origin: env.CORS_ORIGIN,
|
|
36
|
+
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
37
|
+
allowedHeaders: [
|
|
38
|
+
"Content-Type",
|
|
39
|
+
"Authorization",
|
|
40
|
+
"X-Requested-With"
|
|
41
|
+
],
|
|
42
|
+
credentials: true,
|
|
43
|
+
maxAge: 86400,
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
{{#if (eq api "orpc")}}
|
|
47
47
|
const rpcHandler = new RPCHandler(appRouter, {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
plugins: [
|
|
49
|
+
new CORSPlugin({
|
|
50
|
+
origin: env.CORS_ORIGIN,
|
|
51
|
+
credentials: true,
|
|
52
|
+
allowHeaders: ["Content-Type", "Authorization"],
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
interceptors: [
|
|
56
|
+
onError((error) => {
|
|
57
|
+
console.error(error);
|
|
58
|
+
}),
|
|
59
|
+
],
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
const apiHandler = new OpenAPIHandler(appRouter, {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
plugins: [
|
|
64
|
+
new OpenAPIReferencePlugin({
|
|
65
|
+
schemaConverters: [new ZodToJsonSchemaConverter()],
|
|
66
|
+
}),
|
|
67
|
+
],
|
|
68
|
+
interceptors: [
|
|
69
|
+
onError((error) => {
|
|
70
|
+
console.error(error);
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
const fastify = Fastify({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
76
|
+
logger: true,
|
|
77
|
+
serverFactory: (fastifyHandler) => {
|
|
78
|
+
const server = createServer(async (req, res) => {
|
|
79
|
+
const { matched } = await rpcHandler.handle(req, res, {
|
|
80
|
+
context: await createContext(req.headers),
|
|
81
|
+
prefix: "/rpc",
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (matched) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const apiResult = await apiHandler.handle(req, res, {
|
|
89
|
+
context: await createContext(req.headers),
|
|
90
|
+
prefix: "/api-reference",
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (apiResult.matched) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fastifyHandler(req, res);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return server;
|
|
101
|
+
},
|
|
102
102
|
});
|
|
103
103
|
{{else}}
|
|
104
104
|
const fastify = Fastify({
|
|
105
|
-
|
|
105
|
+
logger: true,
|
|
106
106
|
});
|
|
107
107
|
{{/if}}
|
|
108
108
|
|
|
@@ -110,73 +110,73 @@ fastify.register(fastifyCors, baseCorsConfig);
|
|
|
110
110
|
|
|
111
111
|
{{#if (eq auth "better-auth")}}
|
|
112
112
|
fastify.route({
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
113
|
+
method: ["GET", "POST"],
|
|
114
|
+
url: "/api/auth/*",
|
|
115
|
+
async handler(request, reply) {
|
|
116
|
+
try {
|
|
117
|
+
const url = new URL(request.url, `http://${request.headers.host}`);
|
|
118
|
+
const headers = new Headers();
|
|
119
|
+
Object.entries(request.headers).forEach(([key, value]) => {
|
|
120
|
+
if (value) headers.append(key, value.toString());
|
|
121
|
+
});
|
|
122
|
+
const req = new Request(url.toString(), {
|
|
123
|
+
method: request.method,
|
|
124
|
+
headers,
|
|
125
|
+
body: request.body ? JSON.stringify(request.body) : undefined,
|
|
126
|
+
});
|
|
127
|
+
const response = await auth.handler(req);
|
|
128
|
+
reply.status(response.status);
|
|
129
|
+
response.headers.forEach((value, key) => reply.header(key, value));
|
|
130
|
+
reply.send(response.body ? await response.text() : null);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
fastify.log.error({ err: error }, "Authentication Error:");
|
|
133
|
+
reply.status(500).send({
|
|
134
|
+
error: "Internal authentication error",
|
|
135
|
+
code: "AUTH_FAILURE"
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
139
|
});
|
|
140
140
|
{{/if}}
|
|
141
141
|
|
|
142
142
|
{{#if (eq api "trpc")}}
|
|
143
143
|
fastify.register(fastifyTRPCPlugin, {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
prefix: "/trpc",
|
|
145
|
+
trpcOptions: {
|
|
146
|
+
router: appRouter,
|
|
147
|
+
createContext,
|
|
148
|
+
onError({ path, error }) {
|
|
149
|
+
console.error(`Error in tRPC handler on path '${path}':`, error);
|
|
150
|
+
},
|
|
151
|
+
} satisfies FastifyTRPCPluginOptions<AppRouter>["trpcOptions"],
|
|
152
152
|
});
|
|
153
153
|
{{/if}}
|
|
154
154
|
|
|
155
155
|
{{#if (includes examples "ai")}}
|
|
156
156
|
interface AiRequestBody {
|
|
157
|
-
|
|
158
|
-
|
|
157
|
+
id?: string;
|
|
158
|
+
messages: UIMessage[];
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
fastify.post('/ai', async function (request) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
const { messages } = request.body as AiRequestBody;
|
|
163
|
+
const result = streamText({
|
|
164
|
+
model: google('gemini-2.5-flash'),
|
|
165
|
+
messages: convertToModelMessages(messages),
|
|
166
|
+
});
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
return result.toUIMessageStreamResponse();
|
|
169
169
|
});
|
|
170
170
|
{{/if}}
|
|
171
171
|
|
|
172
172
|
fastify.get('/', async () => {
|
|
173
|
-
|
|
173
|
+
return 'OK';
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
fastify.listen({ port: 3000 }, (err) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
if (err) {
|
|
178
|
+
fastify.log.error(err);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
console.log("Server running on port 3000");
|
|
182
182
|
});
|