leedstack 3.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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/bin/create-stack.js +277 -0
  4. package/package.json +60 -0
  5. package/tools/templates/backend/go-echo/backend/.env.example +10 -0
  6. package/tools/templates/backend/go-echo/backend/cmd/server/main.go.ejs +57 -0
  7. package/tools/templates/backend/go-echo/backend/go.mod.ejs +10 -0
  8. package/tools/templates/backend/go-echo/backend/internal/handlers/example.go +15 -0
  9. package/tools/templates/backend/go-echo/backend/internal/handlers/health.go +13 -0
  10. package/tools/templates/backend/java-spring/backend/.env.example +10 -0
  11. package/tools/templates/backend/java-spring/backend/pom.xml.ejs +64 -0
  12. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/Application.java.ejs +11 -0
  13. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/config/SecurityConfig.java.ejs +64 -0
  14. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/ExampleController.java +19 -0
  15. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/HealthController.java +15 -0
  16. package/tools/templates/backend/java-spring/backend/src/main/resources/application.yml.ejs +20 -0
  17. package/tools/templates/backend/node-express/backend/.env.example +10 -0
  18. package/tools/templates/backend/node-express/backend/.eslintrc.json +21 -0
  19. package/tools/templates/backend/node-express/backend/.prettierrc +10 -0
  20. package/tools/templates/backend/node-express/backend/Dockerfile +52 -0
  21. package/tools/templates/backend/node-express/backend/README.md +68 -0
  22. package/tools/templates/backend/node-express/backend/package.json.ejs +37 -0
  23. package/tools/templates/backend/node-express/backend/src/index.ts.ejs +75 -0
  24. package/tools/templates/backend/node-express/backend/src/routes/health.ts +54 -0
  25. package/tools/templates/backend/node-express/backend/tsconfig.json +17 -0
  26. package/tools/templates/backend/python-fastapi/backend/.env.example +18 -0
  27. package/tools/templates/backend/python-fastapi/backend/README.md +73 -0
  28. package/tools/templates/backend/python-fastapi/backend/app/__init__.py +1 -0
  29. package/tools/templates/backend/python-fastapi/backend/app/main.py.ejs +68 -0
  30. package/tools/templates/backend/python-fastapi/backend/requirements.txt.ejs +22 -0
  31. package/tools/templates/base/.dockerignore +16 -0
  32. package/tools/templates/base/.env.example +31 -0
  33. package/tools/templates/base/.github/workflows/ci.yml.ejs +124 -0
  34. package/tools/templates/base/.github/workflows/deploy-separate.yml.example +144 -0
  35. package/tools/templates/base/.vscode/extensions.json +17 -0
  36. package/tools/templates/base/.vscode/settings.json +49 -0
  37. package/tools/templates/base/Makefile +98 -0
  38. package/tools/templates/base/README.md.ejs +118 -0
  39. package/tools/templates/base/docker-compose.yml.ejs +49 -0
  40. package/tools/templates/base/package.json.ejs +30 -0
  41. package/tools/templates/base/scripts/split-repos.sh +189 -0
  42. package/tools/templates/db/postgres/backend/java-spring/backend/pom.xml.ejs +81 -0
  43. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/application.yml.ejs +39 -0
  44. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/db/migration/V1__init.sql +17 -0
  45. package/tools/templates/db/postgres/backend/node-express/backend/.env.example +10 -0
  46. package/tools/templates/db/postgres/backend/node-express/backend/package.json.ejs +32 -0
  47. package/tools/templates/db/postgres/backend/node-express/backend/prisma/schema.prisma.ejs +39 -0
  48. package/tools/templates/frontend/angular/frontend/.env.example +9 -0
  49. package/tools/templates/frontend/angular/frontend/angular.json +66 -0
  50. package/tools/templates/frontend/angular/frontend/package.json.ejs +31 -0
  51. package/tools/templates/frontend/angular/frontend/src/app/app.component.ts +30 -0
  52. package/tools/templates/frontend/angular/frontend/src/app/app.routes.ts +18 -0
  53. package/tools/templates/frontend/angular/frontend/src/app/components/home.component.ts +24 -0
  54. package/tools/templates/frontend/angular/frontend/src/app/services/api.service.ts +48 -0
  55. package/tools/templates/frontend/angular/frontend/src/favicon.ico +1 -0
  56. package/tools/templates/frontend/angular/frontend/src/index.html +13 -0
  57. package/tools/templates/frontend/angular/frontend/src/main.ts +10 -0
  58. package/tools/templates/frontend/angular/frontend/src/styles.css +31 -0
  59. package/tools/templates/frontend/angular/frontend/tsconfig.app.json +9 -0
  60. package/tools/templates/frontend/angular/frontend/tsconfig.json +27 -0
  61. package/tools/templates/frontend/nextjs/frontend/.env.example +9 -0
  62. package/tools/templates/frontend/nextjs/frontend/next.config.js +37 -0
  63. package/tools/templates/frontend/nextjs/frontend/package.json.ejs +25 -0
  64. package/tools/templates/frontend/nextjs/frontend/src/app/globals.css +31 -0
  65. package/tools/templates/frontend/nextjs/frontend/src/app/layout.tsx +36 -0
  66. package/tools/templates/frontend/nextjs/frontend/src/app/page.tsx +19 -0
  67. package/tools/templates/frontend/nextjs/frontend/src/lib/api.ts +45 -0
  68. package/tools/templates/frontend/nextjs/frontend/tsconfig.json +27 -0
  69. package/tools/templates/frontend/react/frontend/.env.example +9 -0
  70. package/tools/templates/frontend/react/frontend/.eslintrc.json +32 -0
  71. package/tools/templates/frontend/react/frontend/.prettierrc +10 -0
  72. package/tools/templates/frontend/react/frontend/Dockerfile +37 -0
  73. package/tools/templates/frontend/react/frontend/README.md +54 -0
  74. package/tools/templates/frontend/react/frontend/index.html +13 -0
  75. package/tools/templates/frontend/react/frontend/nginx.conf +35 -0
  76. package/tools/templates/frontend/react/frontend/package.json.ejs +41 -0
  77. package/tools/templates/frontend/react/frontend/public/vite.svg +4 -0
  78. package/tools/templates/frontend/react/frontend/src/App.css +65 -0
  79. package/tools/templates/frontend/react/frontend/src/App.jsx +41 -0
  80. package/tools/templates/frontend/react/frontend/src/assets/react.svg +7 -0
  81. package/tools/templates/frontend/react/frontend/src/components/ErrorBoundary.jsx +62 -0
  82. package/tools/templates/frontend/react/frontend/src/components/Home.jsx +58 -0
  83. package/tools/templates/frontend/react/frontend/src/components/__tests__/Home.test.jsx +74 -0
  84. package/tools/templates/frontend/react/frontend/src/index.css +31 -0
  85. package/tools/templates/frontend/react/frontend/src/lib/api.js +42 -0
  86. package/tools/templates/frontend/react/frontend/src/lib/env.js +58 -0
  87. package/tools/templates/frontend/react/frontend/src/main.jsx +16 -0
  88. package/tools/templates/frontend/react/frontend/src/setupTests.js +8 -0
  89. package/tools/templates/frontend/react/frontend/vite.config.js +30 -0
  90. package/tools/templates/frontend/react/frontend/vitest.config.js +20 -0
  91. package/tools/templates/frontend/svelte/frontend/.env.example +9 -0
  92. package/tools/templates/frontend/svelte/frontend/package.json.ejs +21 -0
  93. package/tools/templates/frontend/svelte/frontend/src/app.html +12 -0
  94. package/tools/templates/frontend/svelte/frontend/src/lib/api.ts +45 -0
  95. package/tools/templates/frontend/svelte/frontend/src/routes/+layout.svelte +56 -0
  96. package/tools/templates/frontend/svelte/frontend/src/routes/+page.svelte +20 -0
  97. package/tools/templates/frontend/svelte/frontend/static/favicon.png +1 -0
  98. package/tools/templates/frontend/svelte/frontend/svelte.config.js +10 -0
  99. package/tools/templates/frontend/svelte/frontend/vite.config.js +9 -0
  100. package/tools/templates/frontend/vue/frontend/.env.example +9 -0
  101. package/tools/templates/frontend/vue/frontend/index.html +13 -0
  102. package/tools/templates/frontend/vue/frontend/package.json.ejs +20 -0
  103. package/tools/templates/frontend/vue/frontend/src/App.vue +60 -0
  104. package/tools/templates/frontend/vue/frontend/src/lib/api.js +42 -0
  105. package/tools/templates/frontend/vue/frontend/src/main.js +33 -0
  106. package/tools/templates/frontend/vue/frontend/src/views/ApiTest.vue +39 -0
  107. package/tools/templates/frontend/vue/frontend/src/views/Home.vue +30 -0
  108. package/tools/templates/frontend/vue/frontend/vite.config.js +9 -0
  109. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/controller/AdminController.java +41 -0
  110. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/entity/User.java +55 -0
  111. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/repository/UserRepository.java +8 -0
  112. package/tools/templates/modules/admin/frontend/svelte/frontend/src/routes/dashboard/+page.svelte +93 -0
  113. package/tools/templates/modules/auth/backend/node-express/backend/src/middleware/auth.ts +42 -0
  114. package/tools/templates/modules/auth/frontend/svelte/frontend/src/hooks.client.ts +3 -0
  115. package/tools/templates/modules/auth/frontend/svelte/frontend/src/lib/auth.ts +104 -0
  116. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/callback/+page.svelte +18 -0
  117. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/login/+page.svelte +12 -0
  118. package/tools/templates/modules/chatbot/backend/node-express/backend/src/index.ts.ejs +69 -0
  119. package/tools/templates/modules/chatbot/backend/node-express/backend/src/routes/chatbot.ts.ejs +37 -0
  120. package/tools/templates/modules/chatbot/backend/node-express/backend/src/services/chatbotService.ts +124 -0
  121. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/main.py.ejs +69 -0
  122. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/routes/chatbot.py +38 -0
  123. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/services/chatbot_service.py +123 -0
  124. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/requirements.txt +1 -0
  125. package/tools/templates/modules/chatbot/frontend/react/frontend/src/App.jsx.ejs +74 -0
  126. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.css +198 -0
  127. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.jsx +113 -0
  128. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/controller/ContactController.java +29 -0
  129. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/entity/ContactMessage.java +66 -0
  130. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/repository/ContactMessageRepository.java +8 -0
  131. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/resources/db/migration/V2__contact.sql +7 -0
  132. package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte +80 -0
  133. package/tools/templates/modules/payments/backend/java-spring/backend/src/main/java/com/app/controller/PaymentController.java +69 -0
  134. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/payments.ts +30 -0
  135. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/webhook.ts +36 -0
  136. package/tools/templates/modules/payments/frontend/svelte/frontend/src/lib/payments.ts +28 -0
@@ -0,0 +1,39 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ model User {
11
+ id BigInt @id @default(autoincrement())
12
+ email String @unique @db.VarChar(255)
13
+ name String? @db.VarChar(120)
14
+ createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
15
+
16
+ roles UserRole[]
17
+
18
+ @@map("users")
19
+ }
20
+
21
+ model Role {
22
+ id Int @id @default(autoincrement())
23
+ name String @unique @db.VarChar(30)
24
+
25
+ users UserRole[]
26
+
27
+ @@map("roles")
28
+ }
29
+
30
+ model UserRole {
31
+ userId BigInt @map("user_id")
32
+ roleId Int @map("role_id")
33
+
34
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
35
+ role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
36
+
37
+ @@id([userId, roleId])
38
+ @@map("user_roles")
39
+ }
@@ -0,0 +1,9 @@
1
+ NG_APP_API_BASE=http://localhost:8080
2
+ <% if (modules.auth) { -%>
3
+ NG_APP_AUTH0_DOMAIN=your-tenant.us.auth0.com
4
+ NG_APP_AUTH0_CLIENT_ID=your_spa_client_id
5
+ NG_APP_AUTH0_AUDIENCE=https://api.<%= appSlug %>
6
+ <% } -%>
7
+ <% if (modules.payments) { -%>
8
+ NG_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
9
+ <% } -%>
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "newProjectRoot": "projects",
5
+ "projects": {
6
+ "<%= appSlug %>-frontend": {
7
+ "projectType": "application",
8
+ "schematics": {
9
+ "@schematics/angular:component": {
10
+ "standalone": true
11
+ }
12
+ },
13
+ "root": "",
14
+ "sourceRoot": "src",
15
+ "prefix": "app",
16
+ "architect": {
17
+ "build": {
18
+ "builder": "@angular-devkit/build-angular:application",
19
+ "options": {
20
+ "outputPath": "dist",
21
+ "index": "src/index.html",
22
+ "browser": "src/main.ts",
23
+ "polyfills": ["zone.js"],
24
+ "tsConfig": "tsconfig.app.json",
25
+ "assets": ["src/favicon.ico", "src/assets"],
26
+ "styles": ["src/styles.css"],
27
+ "scripts": []
28
+ },
29
+ "configurations": {
30
+ "production": {
31
+ "budgets": [
32
+ {
33
+ "type": "initial",
34
+ "maximumWarning": "500kb",
35
+ "maximumError": "1mb"
36
+ }
37
+ ],
38
+ "outputHashing": "all"
39
+ },
40
+ "development": {
41
+ "optimization": false,
42
+ "extractLicenses": false,
43
+ "sourceMap": true
44
+ }
45
+ },
46
+ "defaultConfiguration": "production"
47
+ },
48
+ "serve": {
49
+ "builder": "@angular-devkit/build-angular:dev-server",
50
+ "configurations": {
51
+ "production": {
52
+ "buildTarget": "<%= appSlug %>-frontend:build:production"
53
+ },
54
+ "development": {
55
+ "buildTarget": "<%= appSlug %>-frontend:build:development"
56
+ }
57
+ },
58
+ "defaultConfiguration": "development",
59
+ "options": {
60
+ "port": 5173
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "<%= appSlug %>-frontend",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "ng serve",
7
+ "build": "ng build",
8
+ "watch": "ng build --watch --configuration development",
9
+ "test": "ng test"
10
+ },
11
+ "dependencies": {
12
+ "@angular/animations": "^19.0.0",
13
+ "@angular/common": "^19.0.0",
14
+ "@angular/compiler": "^19.0.0",
15
+ "@angular/core": "^19.0.0",
16
+ "@angular/forms": "^19.0.0",
17
+ "@angular/platform-browser": "^19.0.0",
18
+ "@angular/platform-browser-dynamic": "^19.0.0",
19
+ "@angular/router": "^19.0.0",
20
+ "@auth0/auth0-spa-js": "^2.1.3",
21
+ "rxjs": "^7.8.1",
22
+ "tslib": "^2.7.0",
23
+ "zone.js": "^0.15.0"
24
+ },
25
+ "devDependencies": {
26
+ "@angular-devkit/build-angular": "^19.0.0",
27
+ "@angular/cli": "^19.0.0",
28
+ "@angular/compiler-cli": "^19.0.0",
29
+ "typescript": "~5.6.3"
30
+ }
31
+ }
@@ -0,0 +1,30 @@
1
+ import { Component } from '@angular/core';
2
+ import { RouterOutlet, RouterLink } from '@angular/router';
3
+
4
+ @Component({
5
+ selector: 'app-root',
6
+ standalone: true,
7
+ imports: [RouterOutlet, RouterLink],
8
+ template: `
9
+ <div class="app">
10
+ <nav>
11
+ <a routerLink="/">Home</a>
12
+ <% if (modules.contact) { -%>
13
+ <a routerLink="/contact">Contact</a>
14
+ <% } -%>
15
+ <% if (modules.auth) { -%>
16
+ <a routerLink="/login">Login</a>
17
+ <% } -%>
18
+ <% if (modules.admin) { -%>
19
+ <a routerLink="/dashboard">Dashboard</a>
20
+ <% } -%>
21
+ </nav>
22
+ <main>
23
+ <router-outlet />
24
+ </main>
25
+ </div>
26
+ `
27
+ })
28
+ export class AppComponent {
29
+ title = '<%= appName %>';
30
+ }
@@ -0,0 +1,18 @@
1
+ import { Routes } from '@angular/router';
2
+ import { HomeComponent } from './components/home.component';
3
+ <% if (modules.contact) { -%>
4
+ import { ContactComponent } from './components/contact.component';
5
+ <% } -%>
6
+ <% if (modules.admin) { -%>
7
+ import { DashboardComponent } from './components/dashboard.component';
8
+ <% } -%>
9
+
10
+ export const routes: Routes = [
11
+ { path: '', component: HomeComponent },
12
+ <% if (modules.contact) { -%>
13
+ { path: 'contact', component: ContactComponent },
14
+ <% } -%>
15
+ <% if (modules.admin) { -%>
16
+ { path: 'dashboard', component: DashboardComponent },
17
+ <% } -%>
18
+ ];
@@ -0,0 +1,24 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'app-home',
5
+ standalone: true,
6
+ template: `
7
+ <div>
8
+ <h1>Welcome to <%= AppName %></h1>
9
+ <p>This is a full-stack application built with:</p>
10
+ <ul>
11
+ <li>Frontend: <%= frontend %></li>
12
+ <li>Backend: <%= backend %></li>
13
+ <li>Database: <%= db %></li>
14
+ <% if (modules.auth) { -%>
15
+ <li>Auth: <%= auth %></li>
16
+ <% } -%>
17
+ <% if (modules.payments) { -%>
18
+ <li>Payments: <%= payments %></li>
19
+ <% } -%>
20
+ </ul>
21
+ </div>
22
+ `
23
+ })
24
+ export class HomeComponent {}
@@ -0,0 +1,48 @@
1
+ import { Injectable } from '@angular/core';
2
+
3
+ @Injectable({
4
+ providedIn: 'root'
5
+ })
6
+ export class ApiService {
7
+ private readonly apiBase = 'http://localhost:8080'; // Configure via environment
8
+
9
+ /**
10
+ * Fetch wrapper that automatically adds API base URL
11
+ */
12
+ async fetch<T = any>(endpoint: string, options: RequestInit = {}): Promise<T> {
13
+ const url = `${this.apiBase}${endpoint}`;
14
+
15
+ const config: RequestInit = {
16
+ ...options,
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ ...options.headers,
20
+ },
21
+ };
22
+
23
+ const response = await fetch(url, config);
24
+
25
+ if (!response.ok) {
26
+ throw new Error(`API Error: ${response.statusText}`);
27
+ }
28
+
29
+ return response.json();
30
+ }
31
+
32
+ /**
33
+ * Example usage in components:
34
+ *
35
+ * constructor(private api: ApiService) {}
36
+ *
37
+ * async ngOnInit() {
38
+ * // GET request
39
+ * const data = await this.api.fetch('/api/example');
40
+ *
41
+ * // POST request
42
+ * const result = await this.api.fetch('/api/contact', {
43
+ * method: 'POST',
44
+ * body: JSON.stringify({ name: 'John', email: 'john@example.com' })
45
+ * });
46
+ * }
47
+ */
48
+ }
@@ -0,0 +1 @@
1
+ <!-- Placeholder favicon -->
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title><%= AppName %></title>
6
+ <base href="/">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
9
+ </head>
10
+ <body>
11
+ <app-root></app-root>
12
+ </body>
13
+ </html>
@@ -0,0 +1,10 @@
1
+ import { bootstrapApplication } from '@angular/platform-browser';
2
+ import { provideRouter } from '@angular/router';
3
+ import { AppComponent } from './app/app.component';
4
+ import { routes } from './app/app.routes';
5
+
6
+ bootstrapApplication(AppComponent, {
7
+ providers: [
8
+ provideRouter(routes)
9
+ ]
10
+ }).catch(err => console.error(err));
@@ -0,0 +1,31 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
4
+ }
5
+
6
+ .app {
7
+ display: flex;
8
+ flex-direction: column;
9
+ min-height: 100vh;
10
+ }
11
+
12
+ nav {
13
+ display: flex;
14
+ gap: 1rem;
15
+ padding: 1rem;
16
+ background: #f0f0f0;
17
+ }
18
+
19
+ nav a {
20
+ text-decoration: none;
21
+ color: #333;
22
+ }
23
+
24
+ nav a:hover {
25
+ text-decoration: underline;
26
+ }
27
+
28
+ main {
29
+ flex: 1;
30
+ padding: 2rem;
31
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./out-tsc/app",
5
+ "types": []
6
+ },
7
+ "files": ["src/main.ts"],
8
+ "include": ["src/**/*.d.ts"]
9
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "compileOnSave": false,
3
+ "compilerOptions": {
4
+ "outDir": "./dist/out-tsc",
5
+ "strict": true,
6
+ "noImplicitOverride": true,
7
+ "noPropertyAccessFromIndexSignature": true,
8
+ "noImplicitReturns": true,
9
+ "noFallthroughCasesInSwitch": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "sourceMap": true,
13
+ "declaration": false,
14
+ "experimentalDecorators": true,
15
+ "moduleResolution": "bundler",
16
+ "importHelpers": true,
17
+ "target": "ES2022",
18
+ "module": "ES2022",
19
+ "lib": ["ES2022", "dom"]
20
+ },
21
+ "angularCompilerOptions": {
22
+ "enableI18nLegacyMessageIdFormat": false,
23
+ "strictInjectionParameters": true,
24
+ "strictInputAccessModifiers": true,
25
+ "strictTemplates": true
26
+ }
27
+ }
@@ -0,0 +1,9 @@
1
+ NEXT_PUBLIC_API_BASE=http://localhost:8080
2
+ <% if (modules.auth) { -%>
3
+ NEXT_PUBLIC_AUTH0_DOMAIN=your-tenant.us.auth0.com
4
+ NEXT_PUBLIC_AUTH0_CLIENT_ID=your_spa_client_id
5
+ NEXT_PUBLIC_AUTH0_AUDIENCE=https://api.<%= appSlug %>
6
+ <% } -%>
7
+ <% if (modules.payments) { -%>
8
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
9
+ <% } -%>
@@ -0,0 +1,37 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ swcMinify: true,
5
+ compiler: {
6
+ removeConsole: process.env.NODE_ENV === 'production'
7
+ },
8
+ poweredByHeader: false,
9
+ compress: true,
10
+ images: {
11
+ formats: ['image/avif', 'image/webp'],
12
+ deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
13
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
14
+ },
15
+ webpack: (config, { isServer }) => {
16
+ // Performance optimizations
17
+ config.optimization.minimize = true;
18
+
19
+ return config;
20
+ },
21
+ experimental: {
22
+ optimizeCss: true,
23
+ optimizePackageImports: ['react', 'react-dom'],
24
+ },
25
+ // Enable faster builds in development
26
+ ...(process.env.NODE_ENV === 'development' && {
27
+ webpack: (config) => {
28
+ config.watchOptions = {
29
+ poll: 1000,
30
+ aggregateTimeout: 300,
31
+ };
32
+ return config;
33
+ },
34
+ }),
35
+ }
36
+
37
+ module.exports = nextConfig
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "<%= appSlug %>-frontend",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev -p 5173",
7
+ "build": "next build",
8
+ "start": "next start -p 5173",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "react": "^19.0.0",
13
+ "react-dom": "^19.0.0",
14
+ "next": "^15.1.0",
15
+ "@auth0/auth0-spa-js": "^2.1.3"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.6.3",
19
+ "@types/node": "^22.0.0",
20
+ "@types/react": "^19.0.0",
21
+ "@types/react-dom": "^19.0.0",
22
+ "eslint": "^9.0.0",
23
+ "eslint-config-next": "^15.1.0"
24
+ }
25
+ }
@@ -0,0 +1,31 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
4
+ }
5
+
6
+ .app {
7
+ display: flex;
8
+ flex-direction: column;
9
+ min-height: 100vh;
10
+ }
11
+
12
+ nav {
13
+ display: flex;
14
+ gap: 1rem;
15
+ padding: 1rem;
16
+ background: #f0f0f0;
17
+ }
18
+
19
+ nav a {
20
+ text-decoration: none;
21
+ color: #333;
22
+ }
23
+
24
+ nav a:hover {
25
+ text-decoration: underline;
26
+ }
27
+
28
+ main {
29
+ flex: 1;
30
+ padding: 2rem;
31
+ }
@@ -0,0 +1,36 @@
1
+ import type { Metadata } from 'next';
2
+ import Link from 'next/link';
3
+ import './globals.css';
4
+
5
+ export const metadata: Metadata = {
6
+ title: '<%= AppName %>',
7
+ description: 'Generated by create-stack',
8
+ };
9
+
10
+ export default function RootLayout({
11
+ children,
12
+ }: {
13
+ children: React.ReactNode;
14
+ }) {
15
+ return (
16
+ <html lang="en">
17
+ <body>
18
+ <div className="app">
19
+ <nav>
20
+ <Link href="/">Home</Link>
21
+ <% if (modules.contact) { -%>
22
+ <Link href="/contact">Contact</Link>
23
+ <% } -%>
24
+ <% if (modules.auth) { -%>
25
+ <Link href="/login">Login</Link>
26
+ <% } -%>
27
+ <% if (modules.admin) { -%>
28
+ <Link href="/dashboard">Dashboard</Link>
29
+ <% } -%>
30
+ </nav>
31
+ <main>{children}</main>
32
+ </div>
33
+ </body>
34
+ </html>
35
+ );
36
+ }
@@ -0,0 +1,19 @@
1
+ export default function Home() {
2
+ return (
3
+ <div>
4
+ <h1>Welcome to <%= AppName %></h1>
5
+ <p>This is a full-stack application built with:</p>
6
+ <ul>
7
+ <li>Frontend: <%= frontend %></li>
8
+ <li>Backend: <%= backend %></li>
9
+ <li>Database: <%= db %></li>
10
+ <% if (modules.auth) { -%>
11
+ <li>Auth: <%= auth %></li>
12
+ <% } -%>
13
+ <% if (modules.payments) { -%>
14
+ <li>Payments: <%= payments %></li>
15
+ <% } -%>
16
+ </ul>
17
+ </div>
18
+ );
19
+ }
@@ -0,0 +1,45 @@
1
+ // API base URL from environment
2
+ const API_BASE = process.env.NEXT_PUBLIC_API_BASE || 'http://localhost:8080';
3
+
4
+ /**
5
+ * Fetch wrapper that automatically adds API base URL
6
+ * @param endpoint - API endpoint (e.g., '/api/example')
7
+ * @param options - Fetch options
8
+ */
9
+ export async function apiFetch<T = any>(
10
+ endpoint: string,
11
+ options: RequestInit = {}
12
+ ): Promise<T> {
13
+ const url = `${API_BASE}${endpoint}`;
14
+
15
+ const config: RequestInit = {
16
+ ...options,
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ ...options.headers,
20
+ },
21
+ };
22
+
23
+ const response = await fetch(url, config);
24
+
25
+ if (!response.ok) {
26
+ throw new Error(`API Error: ${response.statusText}`);
27
+ }
28
+
29
+ return response.json();
30
+ }
31
+
32
+ /**
33
+ * Example usage in components:
34
+ *
35
+ * import { apiFetch } from '@/lib/api';
36
+ *
37
+ * // GET request
38
+ * const data = await apiFetch('/api/example');
39
+ *
40
+ * // POST request
41
+ * const result = await apiFetch('/api/contact', {
42
+ * method: 'POST',
43
+ * body: JSON.stringify({ name: 'John', email: 'john@example.com' })
44
+ * });
45
+ */
@@ -0,0 +1,27 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }
@@ -0,0 +1,9 @@
1
+ VITE_API_BASE=http://localhost:8080
2
+ <% if (modules.auth) { -%>
3
+ VITE_AUTH0_DOMAIN=your-tenant.us.auth0.com
4
+ VITE_AUTH0_CLIENT_ID=your_spa_client_id
5
+ VITE_AUTH0_AUDIENCE=https://api.<%= appSlug %>
6
+ <% } -%>
7
+ <% if (modules.payments) { -%>
8
+ VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
9
+ <% } -%>
@@ -0,0 +1,32 @@
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:react/recommended",
5
+ "plugin:react/jsx-runtime",
6
+ "plugin:react-hooks/recommended"
7
+ ],
8
+ "parserOptions": {
9
+ "ecmaVersion": "latest",
10
+ "sourceType": "module",
11
+ "ecmaFeatures": {
12
+ "jsx": true
13
+ }
14
+ },
15
+ "settings": {
16
+ "react": {
17
+ "version": "detect"
18
+ }
19
+ },
20
+ "rules": {
21
+ "react-hooks/rules-of-hooks": "error",
22
+ "react-hooks/exhaustive-deps": "warn",
23
+ "no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
24
+ "no-console": ["warn", { "allow": ["warn", "error"] }],
25
+ "react/prop-types": "off"
26
+ },
27
+ "env": {
28
+ "browser": true,
29
+ "es2021": true,
30
+ "node": true
31
+ }
32
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": true,
5
+ "printWidth": 100,
6
+ "tabWidth": 2,
7
+ "useTabs": false,
8
+ "arrowParens": "avoid",
9
+ "endOfLine": "lf"
10
+ }