better-ts-stack 2.0.1 → 2.1.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.
Files changed (46) hide show
  1. package/README.md +114 -113
  2. package/dist/args.js +24 -20
  3. package/dist/builder/buildPlanner.js +1 -1
  4. package/dist/builder/configGenerator.js +1 -5
  5. package/dist/builder/index.js +15 -3
  6. package/dist/builder/moduleSelector.js +4 -2
  7. package/dist/builder/readmeGenerator.js +101 -0
  8. package/dist/builder/templateContext.js +30 -0
  9. package/dist/index.js +7 -1
  10. package/dist/output/nextSteps.js +22 -23
  11. package/dist/prompts/index.js +2 -1
  12. package/dist/prompts/stack.js +21 -2
  13. package/dist/types/index.js +2 -1
  14. package/dist/ui/messages.js +2 -1
  15. package/dist/validators/index.js +5 -2
  16. package/package.json +1 -1
  17. package/templates/backend/express/config.json +42 -40
  18. package/templates/backend/express/src/env.ts.hbs +39 -0
  19. package/templates/backend/express/src/index.ts.hbs +111 -75
  20. package/templates/backend/nestjs/config.json +43 -41
  21. package/templates/backend/nestjs/src/app.module.ts.hbs +13 -0
  22. package/templates/backend/nestjs/src/env.ts.hbs +39 -0
  23. package/templates/backend/nestjs/src/main.ts +3 -2
  24. package/templates/frontend/nextjs/app/page.tsx.hbs +98 -97
  25. package/templates/frontend/tanstack/config.json +45 -45
  26. package/templates/frontend/tanstack/src/routes/index.tsx.hbs +102 -101
  27. package/templates/frontend/tanstack/vite.config.ts +22 -14
  28. package/templates/modules/auth/express/config.json +20 -20
  29. package/templates/modules/auth/express/src/routes/auth.ts.hbs +27 -19
  30. package/templates/modules/auth/nestjs/config.json +20 -20
  31. package/templates/modules/auth/nestjs/src/auth/{auth.controller.ts → auth.controller.ts.hbs} +15 -0
  32. package/templates/modules/auth/nextjs/lib/auth-schema.ts +1 -1
  33. package/templates/modules/auth/tanstack/src/components/auth/sign-in-form.tsx +132 -134
  34. package/templates/modules/auth/tanstack/src/components/auth/sign-out-button.tsx +46 -48
  35. package/templates/modules/auth/tanstack/src/components/auth/sign-up-form.tsx +150 -152
  36. package/templates/modules/auth/tanstack/src/lib/auth-schema.ts +38 -38
  37. package/templates/modules/docker/.dockerignore +1 -0
  38. package/templates/modules/docker/Dockerfile.hbs +147 -136
  39. package/templates/modules/docker/docker-compose.yml.hbs +96 -1
  40. package/templates/modules/drizzle/express/src/lib/schema.ts +3 -1
  41. package/templates/modules/drizzle/nestjs/src/database/schema.ts +3 -1
  42. package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +11 -5
  43. package/templates/modules/drizzle/tanstack/src/lib/schema.ts.hbs +90 -84
  44. package/templates/modules/rate-limit/express/config.json +12 -0
  45. package/templates/modules/rate-limit/express/src/middleware/rateLimit.ts +21 -0
  46. package/templates/modules/rate-limit/nestjs/config.json +12 -0
@@ -1,97 +1,98 @@
1
- import Link from "next/link";
2
-
3
- import { ArrowRight } from "lucide-react";
4
-
5
- import { buttonVariants } from "@/components/ui/button";
6
- import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
7
- import { cn } from "@/lib/utils";
8
-
9
- const featureList = [
10
- "Next.js 16 App Router",
11
- "React 19 and TypeScript",
12
- "Tailwind CSS v4",
13
- {{#if useAuth}}"Better Auth-ready session flow",{{/if}}
14
- {{#if (eq database "prisma")}}"Prisma database tooling",{{/if}}
15
- {{#if (eq database "drizzle")}}"Drizzle database tooling",{{/if}}
16
- ];
17
-
18
- export default function Home() {
19
- return (
20
- <main className="min-h-screen bg-background text-foreground">
21
- <div className="mx-auto flex min-h-screen max-w-6xl flex-col justify-center gap-12 px-6 py-16 sm:px-10 lg:px-12">
22
- <section className="grid gap-10 lg:grid-cols-[1.2fr_0.8fr] lg:items-center">
23
- <div className="space-y-6">
24
- <span className="inline-flex w-fit items-center rounded-full border border-border bg-card px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground shadow-sm">
25
- Created with better-ts-stack
26
- </span>
27
- <div className="space-y-4">
28
- <h1 className="max-w-3xl text-4xl font-semibold tracking-tight sm:text-5xl">
29
- Ship your stack faster with a polished TypeScript foundation.
30
- </h1>
31
- <p className="max-w-2xl text-base leading-7 text-muted-foreground sm:text-lg">
32
- Your project already includes the core app shell, database wiring,
33
- and a shadcn-compatible UI foundation so you can keep building
34
- instead of setting up boilerplate.
35
- </p>
36
- </div>
37
- <div className="flex flex-col gap-3 sm:flex-row">
38
- {{#if useAuth}}
39
- <Link
40
- href="/sign-up"
41
- className={cn(buttonVariants({ size: "lg" }), "gap-2")}
42
- >
43
- Create an account
44
- <ArrowRight className="size-4" />
45
- </Link>
46
- <Link
47
- href="/sign-in"
48
- className={buttonVariants({ variant: "outline", size: "lg" })}
49
- >
50
- Login
51
- </Link>
52
- {{else}}
53
- <Link
54
- href="https://github.com/Abdullah-dev0/better-ts-stack"
55
- target="_blank"
56
- rel="noreferrer"
57
- className={cn(buttonVariants({ size: "lg" }), "gap-2")}
58
- >
59
- Explore the docs
60
- <ArrowRight className="size-4" />
61
- </Link>
62
- <Link
63
- href="https://nextjs.org/docs"
64
- target="_blank"
65
- rel="noreferrer"
66
- className={buttonVariants({ variant: "outline", size: "lg" })}
67
- >
68
- Next.js guide
69
- </Link>
70
- {{/if}}
71
- </div>
72
- </div>
73
-
74
- <Card className="border-border bg-card shadow-sm">
75
- <CardHeader>
76
- <CardTitle>Included in this starter</CardTitle>
77
- </CardHeader>
78
- <CardContent className="space-y-4">
79
- <ul className="space-y-3 text-sm text-muted-foreground">
80
- {featureList.map((feature) => (
81
- <li key={feature} className="flex items-center gap-3">
82
- <span className="size-2 rounded-full bg-primary" />
83
- <span>{feature}</span>
84
- </li>
85
- ))}
86
- </ul>
87
- <div className="rounded-2xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
88
- Start editing <code className="font-mono">app/page.tsx</code> and
89
- shape the project around your product instead of setup chores.
90
- </div>
91
- </CardContent>
92
- </Card>
93
- </section>
94
- </div>
95
- </main>
96
- );
97
- }
1
+ import Link from "next/link";
2
+
3
+ import { ArrowRight } from "lucide-react";
4
+
5
+ import { buttonVariants } from "@/components/ui/button";
6
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
7
+ import { cn } from "@/lib/utils";
8
+
9
+ const featureList = [
10
+ "Next.js 16 App Router",
11
+ "React 19 and TypeScript",
12
+ "Tailwind CSS v4",
13
+ {{#if useAuth}}"Better Auth-ready session flow",{{/if}}
14
+ {{#if (eq database "prisma")}}"Prisma database tooling",{{/if}}
15
+ {{#if (eq database "drizzle")}}"Drizzle database tooling",{{/if}}
16
+ {{#if (eq database "mongoose")}}"Mongoose database tooling",{{/if}}
17
+ ];
18
+
19
+ export default function Home() {
20
+ return (
21
+ <main className="min-h-screen bg-background text-foreground">
22
+ <div className="mx-auto flex min-h-screen max-w-6xl flex-col justify-center gap-12 px-6 py-16 sm:px-10 lg:px-12">
23
+ <section className="grid gap-10 lg:grid-cols-[1.2fr_0.8fr] lg:items-center">
24
+ <div className="space-y-6">
25
+ <span className="inline-flex w-fit items-center rounded-full border border-border bg-card px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground shadow-sm">
26
+ Created with better-ts-stack
27
+ </span>
28
+ <div className="space-y-4">
29
+ <h1 className="max-w-3xl text-4xl font-semibold tracking-tight sm:text-5xl">
30
+ Ship your stack faster with a polished TypeScript foundation.
31
+ </h1>
32
+ <p className="max-w-2xl text-base leading-7 text-muted-foreground sm:text-lg">
33
+ Your project already includes the core app shell, database wiring,
34
+ and a shadcn-compatible UI foundation so you can keep building
35
+ instead of setting up boilerplate.
36
+ </p>
37
+ </div>
38
+ <div className="flex flex-col gap-3 sm:flex-row">
39
+ {{#if useAuth}}
40
+ <Link
41
+ href="/sign-up"
42
+ className={cn(buttonVariants({ size: "lg" }), "gap-2")}
43
+ >
44
+ Create an account
45
+ <ArrowRight className="size-4" />
46
+ </Link>
47
+ <Link
48
+ href="/sign-in"
49
+ className={buttonVariants({ variant: "outline", size: "lg" })}
50
+ >
51
+ Login
52
+ </Link>
53
+ {{else}}
54
+ <Link
55
+ href="https://better-ts-stack.abdullahtech.me/docs"
56
+ target="_blank"
57
+ rel="noreferrer"
58
+ className={cn(buttonVariants({ size: "lg" }), "gap-2")}
59
+ >
60
+ Explore the docs
61
+ <ArrowRight className="size-4" />
62
+ </Link>
63
+ <Link
64
+ href="https://nextjs.org/docs"
65
+ target="_blank"
66
+ rel="noreferrer"
67
+ className={buttonVariants({ variant: "outline", size: "lg" })}
68
+ >
69
+ Next.js guide
70
+ </Link>
71
+ {{/if}}
72
+ </div>
73
+ </div>
74
+
75
+ <Card className="border-border bg-card shadow-sm">
76
+ <CardHeader>
77
+ <CardTitle>Included in this starter</CardTitle>
78
+ </CardHeader>
79
+ <CardContent className="space-y-4">
80
+ <ul className="space-y-3 text-sm text-muted-foreground">
81
+ {featureList.map((feature) => (
82
+ <li key={feature} className="flex items-center gap-3">
83
+ <span className="size-2 rounded-full bg-primary" />
84
+ <span>{feature}</span>
85
+ </li>
86
+ ))}
87
+ </ul>
88
+ <div className="rounded-2xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
89
+ Start editing <code className="font-mono">app/page.tsx</code> and
90
+ shape the project around your product instead of setup chores.
91
+ </div>
92
+ </CardContent>
93
+ </Card>
94
+ </section>
95
+ </div>
96
+ </main>
97
+ );
98
+ }
@@ -1,45 +1,45 @@
1
- {
2
- "id": "tanstack",
3
- "name": "TanStack Start",
4
- "description": "TanStack Start with TanStack Router, React 19, and Tailwind CSS v4",
5
- "type": "base",
6
- "scripts": {
7
- "dev": "vite dev",
8
- "build": "vite build",
9
- "start": "srvx --prod -s ../client dist/server/server.js",
10
- "preview": "vite preview",
11
- "type:check": "tsc --noEmit",
12
- "lint": "eslint src"
13
- },
14
- "dependencies": {
15
- "@tanstack/react-query": "^5.102.8",
16
- "@tanstack/react-query-devtools": "^5.102.8",
17
- "@tanstack/react-router": "^1.170.36",
18
- "@tanstack/react-router-devtools": "^1.167.2",
19
- "@tanstack/react-router-ssr-query": "^1.167.2",
20
- "@tanstack/react-start": "^1.168.53",
21
- "class-variance-authority": "^0.7.1",
22
- "clsx": "^2.1.1",
23
- "lucide-react": "^1.41.0",
24
- "react": "^19.2.8",
25
- "react-dom": "^19.2.8",
26
- "srvx": "^1.0.4",
27
- "tailwind-merge": "^3.6.0"
28
- },
29
- "devDependencies": {
30
- "@eslint/js": "^10.0.1",
31
- "@tailwindcss/vite": "^4.3.3",
32
- "@types/node": "^24.13.3",
33
- "@types/react": "^19.2.18",
34
- "@types/react-dom": "^19.2.7",
35
- "@vitejs/plugin-react": "^6.1.1",
36
- "eslint": "^10.10.0",
37
- "tailwindcss": "^4.3.3",
38
- "typescript": "^6.0.3",
39
- "typescript-eslint": "^8.69.0",
40
- "vite": "^8.3.0"
41
- },
42
- "envVars": {
43
- "PORT": "3000"
44
- }
45
- }
1
+ {
2
+ "id": "tanstack",
3
+ "name": "TanStack Start",
4
+ "description": "TanStack Start with TanStack Router, React 19, and Tailwind CSS v4",
5
+ "type": "base",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "start": "node --env-file-if-exists=.env .output/server/index.mjs",
10
+ "preview": "vite preview",
11
+ "type:check": "tsc --noEmit",
12
+ "lint": "eslint src"
13
+ },
14
+ "dependencies": {
15
+ "@tanstack/react-query": "^5.104.3",
16
+ "@tanstack/react-query-devtools": "^5.104.3",
17
+ "@tanstack/react-router": "^1.170.45",
18
+ "@tanstack/react-router-devtools": "^1.167.2",
19
+ "@tanstack/react-router-ssr-query": "^1.167.3",
20
+ "@tanstack/react-start": "^1.169.3",
21
+ "class-variance-authority": "^0.7.1",
22
+ "clsx": "^2.1.1",
23
+ "lucide-react": "^1.41.0",
24
+ "react": "^19.2.8",
25
+ "react-dom": "^19.2.8",
26
+ "tailwind-merge": "^3.6.0"
27
+ },
28
+ "devDependencies": {
29
+ "@eslint/js": "^10.0.1",
30
+ "@tailwindcss/vite": "^4.3.3",
31
+ "@types/node": "^24.13.3",
32
+ "@types/react": "^19.2.18",
33
+ "@types/react-dom": "^19.2.7",
34
+ "@vitejs/plugin-react": "^6.1.2",
35
+ "eslint": "^10.10.0",
36
+ "nitro": "^3.0.260903-beta",
37
+ "tailwindcss": "^4.3.3",
38
+ "typescript": "^6.0.3",
39
+ "typescript-eslint": "^8.69.0",
40
+ "vite": "^8.3.4"
41
+ },
42
+ "envVars": {
43
+ "PORT": "3000"
44
+ }
45
+ }
@@ -1,102 +1,103 @@
1
- import { createFileRoute{{#if useAuth}}, Link{{/if}} } from "@tanstack/react-router";
2
- import { ArrowRight } from "lucide-react";
3
-
4
- import { buttonVariants } from "~/components/ui/button";
5
- import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
6
- import { cn } from "~/lib/utils";
7
-
8
- export const Route = createFileRoute("/")({
9
- component: Home,
10
- });
11
-
12
- const featureList = [
13
- "TanStack Start SSR",
14
- "TanStack Router and Query",
15
- "React 19 and TypeScript",
16
- "Tailwind CSS v4",
17
- {{#if useAuth}}"Better Auth-ready session flow",{{/if}}
18
- {{#if (eq database "prisma")}}"Prisma database tooling",{{/if}}
19
- {{#if (eq database "drizzle")}}"Drizzle database tooling",{{/if}}
20
- ];
21
-
22
- function Home() {
23
- return (
24
- <main className="min-h-screen bg-background text-foreground">
25
- <div className="mx-auto flex min-h-screen max-w-6xl flex-col justify-center gap-12 px-6 py-16 sm:px-10 lg:px-12">
26
- <section className="grid gap-10 lg:grid-cols-[1.2fr_0.8fr] lg:items-center">
27
- <div className="space-y-6">
28
- <span className="inline-flex w-fit items-center rounded-full border border-border bg-card px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground shadow-sm">
29
- Created with better-ts-stack
30
- </span>
31
- <div className="space-y-4">
32
- <h1 className="max-w-3xl text-4xl font-semibold tracking-tight sm:text-5xl">
33
- Ship your stack faster with a polished TypeScript foundation.
34
- </h1>
35
- <p className="max-w-2xl text-base leading-7 text-muted-foreground sm:text-lg">
36
- Your project already includes the core app shell, database wiring,
37
- and a shadcn-compatible UI foundation so you can keep building
38
- instead of setting up boilerplate.
39
- </p>
40
- </div>
41
- <div className="flex flex-col gap-3 sm:flex-row">
42
- {{#if useAuth}}
43
- <Link
44
- to="/sign-up"
45
- className={cn(buttonVariants({ size: "lg" }), "gap-2")}
46
- >
47
- Create an account
48
- <ArrowRight className="size-4" />
49
- </Link>
50
- <Link
51
- to="/sign-in"
52
- className={buttonVariants({ variant: "outline", size: "lg" })}
53
- >
54
- Login
55
- </Link>
56
- {{else}}
57
- <a
58
- href="https://github.com/Abdullah-dev0/better-ts-stack"
59
- target="_blank"
60
- rel="noreferrer"
61
- className={cn(buttonVariants({ size: "lg" }), "gap-2")}
62
- >
63
- Explore the docs
64
- <ArrowRight className="size-4" />
65
- </a>
66
- <a
67
- href="https://tanstack.com/start/latest"
68
- target="_blank"
69
- rel="noreferrer"
70
- className={buttonVariants({ variant: "outline", size: "lg" })}
71
- >
72
- TanStack guide
73
- </a>
74
- {{/if}}
75
- </div>
76
- </div>
77
-
78
- <Card className="border-border bg-card shadow-sm">
79
- <CardHeader>
80
- <CardTitle>Included in this starter</CardTitle>
81
- </CardHeader>
82
- <CardContent className="space-y-4">
83
- <ul className="space-y-3 text-sm text-muted-foreground">
84
- {featureList.map((feature) => (
85
- <li key={feature} className="flex items-center gap-3">
86
- <span className="size-2 rounded-full bg-primary" />
87
- <span>{feature}</span>
88
- </li>
89
- ))}
90
- </ul>
91
- <div className="rounded-2xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
92
- Start editing{" "}
93
- <code className="font-mono">src/routes/index.tsx</code> and
94
- shape the project around your product instead of setup chores.
95
- </div>
96
- </CardContent>
97
- </Card>
98
- </section>
99
- </div>
100
- </main>
101
- );
1
+ import { createFileRoute{{#if useAuth}}, Link{{/if}} } from "@tanstack/react-router";
2
+ import { ArrowRight } from "lucide-react";
3
+
4
+ import { buttonVariants } from "~/components/ui/button";
5
+ import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
6
+ import { cn } from "~/lib/utils";
7
+
8
+ export const Route = createFileRoute("/")({
9
+ component: Home,
10
+ });
11
+
12
+ const featureList = [
13
+ "TanStack Start SSR",
14
+ "TanStack Router and Query",
15
+ "React 19 and TypeScript",
16
+ "Tailwind CSS v4",
17
+ {{#if useAuth}}"Better Auth-ready session flow",{{/if}}
18
+ {{#if (eq database "prisma")}}"Prisma database tooling",{{/if}}
19
+ {{#if (eq database "drizzle")}}"Drizzle database tooling",{{/if}}
20
+ {{#if (eq database "mongoose")}}"Mongoose database tooling",{{/if}}
21
+ ];
22
+
23
+ function Home() {
24
+ return (
25
+ <main className="min-h-screen bg-background text-foreground">
26
+ <div className="mx-auto flex min-h-screen max-w-6xl flex-col justify-center gap-12 px-6 py-16 sm:px-10 lg:px-12">
27
+ <section className="grid gap-10 lg:grid-cols-[1.2fr_0.8fr] lg:items-center">
28
+ <div className="space-y-6">
29
+ <span className="inline-flex w-fit items-center rounded-full border border-border bg-card px-3 py-1 text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground shadow-sm">
30
+ Created with better-ts-stack
31
+ </span>
32
+ <div className="space-y-4">
33
+ <h1 className="max-w-3xl text-4xl font-semibold tracking-tight sm:text-5xl">
34
+ Ship your stack faster with a polished TypeScript foundation.
35
+ </h1>
36
+ <p className="max-w-2xl text-base leading-7 text-muted-foreground sm:text-lg">
37
+ Your project already includes the core app shell, database wiring,
38
+ and a shadcn-compatible UI foundation so you can keep building
39
+ instead of setting up boilerplate.
40
+ </p>
41
+ </div>
42
+ <div className="flex flex-col gap-3 sm:flex-row">
43
+ {{#if useAuth}}
44
+ <Link
45
+ to="/sign-up"
46
+ className={cn(buttonVariants({ size: "lg" }), "gap-2")}
47
+ >
48
+ Create an account
49
+ <ArrowRight className="size-4" />
50
+ </Link>
51
+ <Link
52
+ to="/sign-in"
53
+ className={buttonVariants({ variant: "outline", size: "lg" })}
54
+ >
55
+ Login
56
+ </Link>
57
+ {{else}}
58
+ <a
59
+ href="https://better-ts-stack.abdullahtech.me/docs"
60
+ target="_blank"
61
+ rel="noreferrer"
62
+ className={cn(buttonVariants({ size: "lg" }), "gap-2")}
63
+ >
64
+ Explore the docs
65
+ <ArrowRight className="size-4" />
66
+ </a>
67
+ <a
68
+ href="https://tanstack.com/start/latest"
69
+ target="_blank"
70
+ rel="noreferrer"
71
+ className={buttonVariants({ variant: "outline", size: "lg" })}
72
+ >
73
+ TanStack guide
74
+ </a>
75
+ {{/if}}
76
+ </div>
77
+ </div>
78
+
79
+ <Card className="border-border bg-card shadow-sm">
80
+ <CardHeader>
81
+ <CardTitle>Included in this starter</CardTitle>
82
+ </CardHeader>
83
+ <CardContent className="space-y-4">
84
+ <ul className="space-y-3 text-sm text-muted-foreground">
85
+ {featureList.map((feature) => (
86
+ <li key={feature} className="flex items-center gap-3">
87
+ <span className="size-2 rounded-full bg-primary" />
88
+ <span>{feature}</span>
89
+ </li>
90
+ ))}
91
+ </ul>
92
+ <div className="rounded-2xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
93
+ Start editing{" "}
94
+ <code className="font-mono">src/routes/index.tsx</code> and
95
+ shape the project around your product instead of setup chores.
96
+ </div>
97
+ </CardContent>
98
+ </Card>
99
+ </section>
100
+ </div>
101
+ </main>
102
+ );
102
103
  }
@@ -1,14 +1,22 @@
1
- import { tanstackStart } from "@tanstack/react-start/plugin/vite";
2
- import tailwindcss from "@tailwindcss/vite";
3
- import viteReact from "@vitejs/plugin-react";
4
- import { defineConfig } from "vite";
5
-
6
- export default defineConfig({
7
- server: {
8
- port: 3000,
9
- },
10
- resolve: {
11
- tsconfigPaths: true,
12
- },
13
- plugins: [tanstackStart({ srcDirectory: "src" }), tailwindcss(), viteReact()],
14
- });
1
+ import { tanstackStart } from "@tanstack/react-start/plugin/vite";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+ import viteReact from "@vitejs/plugin-react";
4
+ import { nitro } from "nitro/vite";
5
+ import { defineConfig } from "vite";
6
+
7
+ export default defineConfig(({ command }) => ({
8
+ server: {
9
+ port: 3000,
10
+ },
11
+ resolve: {
12
+ tsconfigPaths: true,
13
+ },
14
+ plugins: [
15
+ tanstackStart({ srcDirectory: "src" }),
16
+ tailwindcss(),
17
+ viteReact(),
18
+ // Nitro builds the production server in .output/ (run with node). It is
19
+ // left out of `vite dev`, where TanStack Start's own dev server is steadier
20
+ command === "build" && nitro(),
21
+ ],
22
+ }));
@@ -1,20 +1,20 @@
1
- {
2
- "id": "auth",
3
- "name": "JWT Auth",
4
- "description": "JWT authentication with bcrypt password hashing",
5
- "type": "feature",
6
- "dependencies": {
7
- "bcrypt": "^6.0.0",
8
- "jsonwebtoken": "^9.0.3",
9
- "zod": "^4.6.5"
10
- },
11
- "devDependencies": {
12
- "@types/bcrypt": "^6.0.0",
13
- "@types/jsonwebtoken": "^9.0.10"
14
- },
15
- "scripts": {},
16
- "envVars": {
17
- "JWT_SECRET": "please-change-me",
18
- "JWT_EXPIRES_IN": "1h"
19
- }
20
- }
1
+ {
2
+ "id": "auth",
3
+ "name": "JWT Auth",
4
+ "description": "JWT authentication with bcrypt password hashing",
5
+ "type": "feature",
6
+ "dependencies": {
7
+ "bcrypt": "^6.0.0",
8
+ "jsonwebtoken": "^9.0.3",
9
+ "zod": "^4.6.5"
10
+ },
11
+ "devDependencies": {
12
+ "@types/bcrypt": "^6.0.0",
13
+ "@types/jsonwebtoken": "^9.0.10"
14
+ },
15
+ "scripts": {},
16
+ "envVars": {
17
+ "JWT_SECRET": "please-change-me",
18
+ "JWT_EXPIRES_IN": "1h"
19
+ }
20
+ }
@@ -1,19 +1,27 @@
1
- import { Request, Response, NextFunction, Router } from 'express';
2
- import { login, me, register } from '../controllers/authController';
3
- import { requireAuth } from '../middleware/requireAuth';
4
-
5
- const router: Router = Router();
6
-
7
- function asyncHandler(
8
- fn: (req: Request, res: Response, next: NextFunction) => Promise<void>
9
- ): (req: Request, res: Response, next: NextFunction) => void {
10
- return (req, res, next) => {
11
- void fn(req, res, next).catch(next);
12
- };
13
- }
14
-
15
- router.post('/register', asyncHandler(register));
16
- router.post('/login', asyncHandler(login));
17
- router.get('/me', requireAuth, me);
18
-
19
- export default router;
1
+ import { Request, Response, NextFunction, Router } from 'express';
2
+ import { login, me, register } from '../controllers/authController';
3
+ {{#if useRateLimit}}
4
+ import { authLimiter } from '../middleware/rateLimit';
5
+ {{/if}}
6
+ import { requireAuth } from '../middleware/requireAuth';
7
+
8
+ const router: Router = Router();
9
+
10
+ function asyncHandler(
11
+ fn: (req: Request, res: Response, next: NextFunction) => Promise<void>
12
+ ): (req: Request, res: Response, next: NextFunction) => void {
13
+ return (req, res, next) => {
14
+ void fn(req, res, next).catch(next);
15
+ };
16
+ }
17
+
18
+ {{#if useRateLimit}}
19
+ router.post('/register', authLimiter, asyncHandler(register));
20
+ router.post('/login', authLimiter, asyncHandler(login));
21
+ {{else}}
22
+ router.post('/register', asyncHandler(register));
23
+ router.post('/login', asyncHandler(login));
24
+ {{/if}}
25
+ router.get('/me', requireAuth, me);
26
+
27
+ export default router;