better-ts-stack 2.0.2 → 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 (40) 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 +19 -22
  11. package/dist/prompts/index.js +2 -1
  12. package/dist/prompts/stack.js +21 -2
  13. package/dist/types/index.js +1 -0
  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 +2 -2
  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/tanstack/src/components/auth/sign-in-form.tsx +132 -134
  33. package/templates/modules/auth/tanstack/src/components/auth/sign-out-button.tsx +46 -48
  34. package/templates/modules/auth/tanstack/src/components/auth/sign-up-form.tsx +150 -152
  35. package/templates/modules/docker/.dockerignore +1 -0
  36. package/templates/modules/docker/Dockerfile.hbs +147 -136
  37. package/templates/modules/docker/docker-compose.yml.hbs +96 -1
  38. package/templates/modules/rate-limit/express/config.json +12 -0
  39. package/templates/modules/rate-limit/express/src/middleware/rateLimit.ts +21 -0
  40. package/templates/modules/rate-limit/nestjs/config.json +12 -0
@@ -7,4 +7,99 @@ services:
7
7
  - .env
8
8
  environment:
9
9
  - NODE_ENV=production
10
- restart: unless-stopped
10
+ {{#if (eq database 'prisma')}}
11
+ # Inside Docker the database is the "db" service, not localhost
12
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
13
+ {{/if}}
14
+ {{#if (eq database 'drizzle')}}
15
+ # Inside Docker the database is the "db" service, not localhost
16
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
17
+ {{/if}}
18
+ {{#if (eq database 'mongoose')}}
19
+ # Inside Docker the database is the "db" service, not localhost
20
+ - MONGODB_URI=mongodb://db:27017/myapp?directConnection=true
21
+ {{/if}}
22
+ {{#unless (eq database 'none')}}
23
+ depends_on:
24
+ db:
25
+ condition: service_healthy
26
+ {{/unless}}
27
+ restart: unless-stopped
28
+ {{#if (eq database 'prisma')}}
29
+
30
+ # PostgreSQL for local development. The port is published so migrations and
31
+ # the app can also reach it from your machine at localhost:5432
32
+ db:
33
+ image: postgres:17-alpine
34
+ environment:
35
+ POSTGRES_USER: postgres
36
+ POSTGRES_PASSWORD: postgres
37
+ POSTGRES_DB: postgres
38
+ ports:
39
+ - "5432:5432"
40
+ volumes:
41
+ - db-data:/var/lib/postgresql/data
42
+ healthcheck:
43
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
44
+ interval: 5s
45
+ timeout: 5s
46
+ retries: 10
47
+ restart: unless-stopped
48
+
49
+ volumes:
50
+ db-data:
51
+ {{/if}}
52
+ {{#if (eq database 'drizzle')}}
53
+
54
+ # PostgreSQL for local development. The port is published so migrations and
55
+ # the app can also reach it from your machine at localhost:5432
56
+ db:
57
+ image: postgres:17-alpine
58
+ environment:
59
+ POSTGRES_USER: postgres
60
+ POSTGRES_PASSWORD: postgres
61
+ POSTGRES_DB: postgres
62
+ ports:
63
+ - "5432:5432"
64
+ volumes:
65
+ - db-data:/var/lib/postgresql/data
66
+ healthcheck:
67
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
68
+ interval: 5s
69
+ timeout: 5s
70
+ retries: 10
71
+ restart: unless-stopped
72
+
73
+ volumes:
74
+ db-data:
75
+ {{/if}}
76
+ {{#if (eq database 'mongoose')}}
77
+
78
+ # MongoDB for local development, run as a one-node replica set because
79
+ # transactions need one. The health check starts the replica set on first
80
+ # run. The port is published so the app can also reach it from your machine
81
+ # at localhost:27017
82
+ db:
83
+ image: mongo:8
84
+ command: ["--replSet", "rs0", "--bind_ip_all"]
85
+ ports:
86
+ - "27017:27017"
87
+ volumes:
88
+ - db-data:/data/db
89
+ healthcheck:
90
+ test:
91
+ [
92
+ "CMD",
93
+ "mongosh",
94
+ "--quiet",
95
+ "--eval",
96
+ "try { rs.status().ok } catch (e) { rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'localhost:27017' }] }).ok }",
97
+ ]
98
+ interval: 5s
99
+ timeout: 10s
100
+ retries: 20
101
+ restart: unless-stopped
102
+
103
+ volumes:
104
+ db-data:
105
+ {{/if}}
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "rate-limit",
3
+ "name": "Rate limiting",
4
+ "description": "Per-IP request limits for Express with express-rate-limit",
5
+ "type": "feature",
6
+ "dependencies": {
7
+ "express-rate-limit": "^8.7.1"
8
+ },
9
+ "devDependencies": {},
10
+ "scripts": {},
11
+ "envVars": {}
12
+ }
@@ -0,0 +1,21 @@
1
+ import { rateLimit } from "express-rate-limit";
2
+
3
+ // Limits count requests per client IP. Behind a reverse proxy or load
4
+ // balancer, set app.set("trust proxy", 1) so the real client IP is used.
5
+ const FIFTEEN_MINUTES = 15 * 60 * 1000;
6
+
7
+ // Every route: 100 requests per IP in 15 minutes
8
+ export const apiLimiter = rateLimit({
9
+ windowMs: FIFTEEN_MINUTES,
10
+ limit: 100,
11
+ standardHeaders: "draft-8",
12
+ legacyHeaders: false,
13
+ });
14
+
15
+ // Sign-up and login: 10 attempts per IP in 15 minutes, against password guessing
16
+ export const authLimiter = rateLimit({
17
+ windowMs: FIFTEEN_MINUTES,
18
+ limit: 10,
19
+ standardHeaders: "draft-8",
20
+ legacyHeaders: false,
21
+ });
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "rate-limit",
3
+ "name": "Rate limiting",
4
+ "description": "Per-IP request limits for NestJS with @nestjs/throttler",
5
+ "type": "feature",
6
+ "dependencies": {
7
+ "@nestjs/throttler": "^6.7.1"
8
+ },
9
+ "devDependencies": {},
10
+ "scripts": {},
11
+ "envVars": {}
12
+ }