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.
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/bin/create-stack.js +277 -0
- package/package.json +60 -0
- package/tools/templates/backend/go-echo/backend/.env.example +10 -0
- package/tools/templates/backend/go-echo/backend/cmd/server/main.go.ejs +57 -0
- package/tools/templates/backend/go-echo/backend/go.mod.ejs +10 -0
- package/tools/templates/backend/go-echo/backend/internal/handlers/example.go +15 -0
- package/tools/templates/backend/go-echo/backend/internal/handlers/health.go +13 -0
- package/tools/templates/backend/java-spring/backend/.env.example +10 -0
- package/tools/templates/backend/java-spring/backend/pom.xml.ejs +64 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/Application.java.ejs +11 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/config/SecurityConfig.java.ejs +64 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/ExampleController.java +19 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/HealthController.java +15 -0
- package/tools/templates/backend/java-spring/backend/src/main/resources/application.yml.ejs +20 -0
- package/tools/templates/backend/node-express/backend/.env.example +10 -0
- package/tools/templates/backend/node-express/backend/.eslintrc.json +21 -0
- package/tools/templates/backend/node-express/backend/.prettierrc +10 -0
- package/tools/templates/backend/node-express/backend/Dockerfile +52 -0
- package/tools/templates/backend/node-express/backend/README.md +68 -0
- package/tools/templates/backend/node-express/backend/package.json.ejs +37 -0
- package/tools/templates/backend/node-express/backend/src/index.ts.ejs +75 -0
- package/tools/templates/backend/node-express/backend/src/routes/health.ts +54 -0
- package/tools/templates/backend/node-express/backend/tsconfig.json +17 -0
- package/tools/templates/backend/python-fastapi/backend/.env.example +18 -0
- package/tools/templates/backend/python-fastapi/backend/README.md +73 -0
- package/tools/templates/backend/python-fastapi/backend/app/__init__.py +1 -0
- package/tools/templates/backend/python-fastapi/backend/app/main.py.ejs +68 -0
- package/tools/templates/backend/python-fastapi/backend/requirements.txt.ejs +22 -0
- package/tools/templates/base/.dockerignore +16 -0
- package/tools/templates/base/.env.example +31 -0
- package/tools/templates/base/.github/workflows/ci.yml.ejs +124 -0
- package/tools/templates/base/.github/workflows/deploy-separate.yml.example +144 -0
- package/tools/templates/base/.vscode/extensions.json +17 -0
- package/tools/templates/base/.vscode/settings.json +49 -0
- package/tools/templates/base/Makefile +98 -0
- package/tools/templates/base/README.md.ejs +118 -0
- package/tools/templates/base/docker-compose.yml.ejs +49 -0
- package/tools/templates/base/package.json.ejs +30 -0
- package/tools/templates/base/scripts/split-repos.sh +189 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/pom.xml.ejs +81 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/application.yml.ejs +39 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/db/migration/V1__init.sql +17 -0
- package/tools/templates/db/postgres/backend/node-express/backend/.env.example +10 -0
- package/tools/templates/db/postgres/backend/node-express/backend/package.json.ejs +32 -0
- package/tools/templates/db/postgres/backend/node-express/backend/prisma/schema.prisma.ejs +39 -0
- package/tools/templates/frontend/angular/frontend/.env.example +9 -0
- package/tools/templates/frontend/angular/frontend/angular.json +66 -0
- package/tools/templates/frontend/angular/frontend/package.json.ejs +31 -0
- package/tools/templates/frontend/angular/frontend/src/app/app.component.ts +30 -0
- package/tools/templates/frontend/angular/frontend/src/app/app.routes.ts +18 -0
- package/tools/templates/frontend/angular/frontend/src/app/components/home.component.ts +24 -0
- package/tools/templates/frontend/angular/frontend/src/app/services/api.service.ts +48 -0
- package/tools/templates/frontend/angular/frontend/src/favicon.ico +1 -0
- package/tools/templates/frontend/angular/frontend/src/index.html +13 -0
- package/tools/templates/frontend/angular/frontend/src/main.ts +10 -0
- package/tools/templates/frontend/angular/frontend/src/styles.css +31 -0
- package/tools/templates/frontend/angular/frontend/tsconfig.app.json +9 -0
- package/tools/templates/frontend/angular/frontend/tsconfig.json +27 -0
- package/tools/templates/frontend/nextjs/frontend/.env.example +9 -0
- package/tools/templates/frontend/nextjs/frontend/next.config.js +37 -0
- package/tools/templates/frontend/nextjs/frontend/package.json.ejs +25 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/globals.css +31 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/layout.tsx +36 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/page.tsx +19 -0
- package/tools/templates/frontend/nextjs/frontend/src/lib/api.ts +45 -0
- package/tools/templates/frontend/nextjs/frontend/tsconfig.json +27 -0
- package/tools/templates/frontend/react/frontend/.env.example +9 -0
- package/tools/templates/frontend/react/frontend/.eslintrc.json +32 -0
- package/tools/templates/frontend/react/frontend/.prettierrc +10 -0
- package/tools/templates/frontend/react/frontend/Dockerfile +37 -0
- package/tools/templates/frontend/react/frontend/README.md +54 -0
- package/tools/templates/frontend/react/frontend/index.html +13 -0
- package/tools/templates/frontend/react/frontend/nginx.conf +35 -0
- package/tools/templates/frontend/react/frontend/package.json.ejs +41 -0
- package/tools/templates/frontend/react/frontend/public/vite.svg +4 -0
- package/tools/templates/frontend/react/frontend/src/App.css +65 -0
- package/tools/templates/frontend/react/frontend/src/App.jsx +41 -0
- package/tools/templates/frontend/react/frontend/src/assets/react.svg +7 -0
- package/tools/templates/frontend/react/frontend/src/components/ErrorBoundary.jsx +62 -0
- package/tools/templates/frontend/react/frontend/src/components/Home.jsx +58 -0
- package/tools/templates/frontend/react/frontend/src/components/__tests__/Home.test.jsx +74 -0
- package/tools/templates/frontend/react/frontend/src/index.css +31 -0
- package/tools/templates/frontend/react/frontend/src/lib/api.js +42 -0
- package/tools/templates/frontend/react/frontend/src/lib/env.js +58 -0
- package/tools/templates/frontend/react/frontend/src/main.jsx +16 -0
- package/tools/templates/frontend/react/frontend/src/setupTests.js +8 -0
- package/tools/templates/frontend/react/frontend/vite.config.js +30 -0
- package/tools/templates/frontend/react/frontend/vitest.config.js +20 -0
- package/tools/templates/frontend/svelte/frontend/.env.example +9 -0
- package/tools/templates/frontend/svelte/frontend/package.json.ejs +21 -0
- package/tools/templates/frontend/svelte/frontend/src/app.html +12 -0
- package/tools/templates/frontend/svelte/frontend/src/lib/api.ts +45 -0
- package/tools/templates/frontend/svelte/frontend/src/routes/+layout.svelte +56 -0
- package/tools/templates/frontend/svelte/frontend/src/routes/+page.svelte +20 -0
- package/tools/templates/frontend/svelte/frontend/static/favicon.png +1 -0
- package/tools/templates/frontend/svelte/frontend/svelte.config.js +10 -0
- package/tools/templates/frontend/svelte/frontend/vite.config.js +9 -0
- package/tools/templates/frontend/vue/frontend/.env.example +9 -0
- package/tools/templates/frontend/vue/frontend/index.html +13 -0
- package/tools/templates/frontend/vue/frontend/package.json.ejs +20 -0
- package/tools/templates/frontend/vue/frontend/src/App.vue +60 -0
- package/tools/templates/frontend/vue/frontend/src/lib/api.js +42 -0
- package/tools/templates/frontend/vue/frontend/src/main.js +33 -0
- package/tools/templates/frontend/vue/frontend/src/views/ApiTest.vue +39 -0
- package/tools/templates/frontend/vue/frontend/src/views/Home.vue +30 -0
- package/tools/templates/frontend/vue/frontend/vite.config.js +9 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/controller/AdminController.java +41 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/entity/User.java +55 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/repository/UserRepository.java +8 -0
- package/tools/templates/modules/admin/frontend/svelte/frontend/src/routes/dashboard/+page.svelte +93 -0
- package/tools/templates/modules/auth/backend/node-express/backend/src/middleware/auth.ts +42 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/hooks.client.ts +3 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/lib/auth.ts +104 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/callback/+page.svelte +18 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/login/+page.svelte +12 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/index.ts.ejs +69 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/routes/chatbot.ts.ejs +37 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/services/chatbotService.ts +124 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/main.py.ejs +69 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/routes/chatbot.py +38 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/services/chatbot_service.py +123 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/requirements.txt +1 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/App.jsx.ejs +74 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.css +198 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.jsx +113 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/controller/ContactController.java +29 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/entity/ContactMessage.java +66 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/repository/ContactMessageRepository.java +8 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/resources/db/migration/V2__contact.sql +7 -0
- package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte +80 -0
- package/tools/templates/modules/payments/backend/java-spring/backend/src/main/java/com/app/controller/PaymentController.java +69 -0
- package/tools/templates/modules/payments/backend/node-express/backend/src/routes/payments.ts +30 -0
- package/tools/templates/modules/payments/backend/node-express/backend/src/routes/webhook.ts +36 -0
- package/tools/templates/modules/payments/frontend/svelte/frontend/src/lib/payments.ts +28 -0
package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getToken } from '$lib/auth';
|
|
3
|
+
|
|
4
|
+
let name = '';
|
|
5
|
+
let email = '';
|
|
6
|
+
let message = '';
|
|
7
|
+
let submitted = false;
|
|
8
|
+
|
|
9
|
+
async function handleSubmit() {
|
|
10
|
+
const API_BASE = import.meta.env.PUBLIC_API_BASE || 'http://localhost:8080';
|
|
11
|
+
const token = await getToken();
|
|
12
|
+
|
|
13
|
+
const response = await fetch(`${API_BASE}/api/contact`, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
'Authorization': `Bearer ${token}`
|
|
18
|
+
},
|
|
19
|
+
body: JSON.stringify({ name, email, message })
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (response.ok) {
|
|
23
|
+
submitted = true;
|
|
24
|
+
name = '';
|
|
25
|
+
email = '';
|
|
26
|
+
message = '';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<h1>Contact Us</h1>
|
|
32
|
+
|
|
33
|
+
{#if submitted}
|
|
34
|
+
<p style="color: green;">Thank you! Your message has been sent.</p>
|
|
35
|
+
{/if}
|
|
36
|
+
|
|
37
|
+
<form on:submit|preventDefault={handleSubmit}>
|
|
38
|
+
<div>
|
|
39
|
+
<label for="name">Name:</label>
|
|
40
|
+
<input type="text" id="name" bind:value={name} required />
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div>
|
|
44
|
+
<label for="email">Email:</label>
|
|
45
|
+
<input type="email" id="email" bind:value={email} required />
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div>
|
|
49
|
+
<label for="message">Message:</label>
|
|
50
|
+
<textarea id="message" bind:value={message} rows="5" required></textarea>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<button type="submit">Send Message</button>
|
|
54
|
+
</form>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
form {
|
|
58
|
+
max-width: 500px;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
gap: 1rem;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
input, textarea {
|
|
65
|
+
width: 100%;
|
|
66
|
+
padding: 0.5rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button {
|
|
70
|
+
padding: 0.75rem;
|
|
71
|
+
background: #333;
|
|
72
|
+
color: white;
|
|
73
|
+
border: none;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
button:hover {
|
|
78
|
+
background: #555;
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.app.controller;
|
|
2
|
+
|
|
3
|
+
import com.stripe.Stripe;
|
|
4
|
+
import com.stripe.exception.StripeException;
|
|
5
|
+
import com.stripe.model.Event;
|
|
6
|
+
import com.stripe.model.checkout.Session;
|
|
7
|
+
import com.stripe.net.Webhook;
|
|
8
|
+
import com.stripe.param.checkout.SessionCreateParams;
|
|
9
|
+
import org.springframework.beans.factory.annotation.Value;
|
|
10
|
+
import org.springframework.http.ResponseEntity;
|
|
11
|
+
import org.springframework.web.bind.annotation.*;
|
|
12
|
+
|
|
13
|
+
import java.util.Map;
|
|
14
|
+
|
|
15
|
+
@RestController
|
|
16
|
+
public class PaymentController {
|
|
17
|
+
|
|
18
|
+
@Value("${STRIPE_SECRET_KEY:}")
|
|
19
|
+
private String stripeSecretKey;
|
|
20
|
+
|
|
21
|
+
@Value("${STRIPE_WEBHOOK_SECRET:}")
|
|
22
|
+
private String webhookSecret;
|
|
23
|
+
|
|
24
|
+
@PostMapping("/api/payments/create-checkout-session")
|
|
25
|
+
public ResponseEntity<?> createCheckoutSession(@RequestBody Map<String, String> body) {
|
|
26
|
+
Stripe.apiKey = stripeSecretKey;
|
|
27
|
+
|
|
28
|
+
String priceId = body.getOrDefault("priceId", "price_PLACEHOLDER");
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
SessionCreateParams params = SessionCreateParams.builder()
|
|
32
|
+
.setMode(SessionCreateParams.Mode.PAYMENT)
|
|
33
|
+
.setSuccessUrl(body.getOrDefault("successUrl", "http://localhost:5173/success"))
|
|
34
|
+
.setCancelUrl(body.getOrDefault("cancelUrl", "http://localhost:5173/cancel"))
|
|
35
|
+
.addLineItem(
|
|
36
|
+
SessionCreateParams.LineItem.builder()
|
|
37
|
+
.setPrice(priceId)
|
|
38
|
+
.setQuantity(1L)
|
|
39
|
+
.build()
|
|
40
|
+
)
|
|
41
|
+
.build();
|
|
42
|
+
|
|
43
|
+
Session session = Session.create(params);
|
|
44
|
+
return ResponseEntity.ok(Map.of("url", session.getUrl()));
|
|
45
|
+
} catch (StripeException e) {
|
|
46
|
+
return ResponseEntity.status(500).body(Map.of("error", e.getMessage()));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@PostMapping("/stripe/webhook")
|
|
51
|
+
public ResponseEntity<String> handleWebhook(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader) {
|
|
52
|
+
try {
|
|
53
|
+
Event event = Webhook.constructEvent(payload, sigHeader, webhookSecret);
|
|
54
|
+
|
|
55
|
+
switch (event.getType()) {
|
|
56
|
+
case "checkout.session.completed":
|
|
57
|
+
// Handle successful payment
|
|
58
|
+
System.out.println("Payment successful: " + event.getId());
|
|
59
|
+
break;
|
|
60
|
+
default:
|
|
61
|
+
System.out.println("Unhandled event type: " + event.getType());
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return ResponseEntity.ok("");
|
|
65
|
+
} catch (Exception e) {
|
|
66
|
+
return ResponseEntity.status(400).body("Webhook error: " + e.getMessage());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Router, Request, Response } from 'express';
|
|
2
|
+
import Stripe from 'stripe';
|
|
3
|
+
|
|
4
|
+
const router = Router();
|
|
5
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', { apiVersion: '2024-06-20' });
|
|
6
|
+
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || '';
|
|
7
|
+
|
|
8
|
+
router.post('/payments/create-checkout-session', async (req: Request, res: Response) => {
|
|
9
|
+
try {
|
|
10
|
+
const { priceId = 'price_PLACEHOLDER', successUrl = 'http://localhost:5173/success', cancelUrl = 'http://localhost:5173/cancel' } = req.body;
|
|
11
|
+
|
|
12
|
+
const session = await stripe.checkout.sessions.create({
|
|
13
|
+
mode: 'payment',
|
|
14
|
+
success_url: successUrl,
|
|
15
|
+
cancel_url: cancelUrl,
|
|
16
|
+
line_items: [
|
|
17
|
+
{
|
|
18
|
+
price: priceId,
|
|
19
|
+
quantity: 1
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
res.json({ url: session.url });
|
|
25
|
+
} catch (error: any) {
|
|
26
|
+
res.status(500).json({ error: error.message });
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default router;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Router, Request, Response } from 'express';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import Stripe from 'stripe';
|
|
4
|
+
|
|
5
|
+
const router = Router();
|
|
6
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', { apiVersion: '2024-06-20' });
|
|
7
|
+
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || '';
|
|
8
|
+
|
|
9
|
+
// Stripe webhooks need raw body
|
|
10
|
+
router.post('/stripe/webhook', express.raw({ type: 'application/json' }), async (req: Request, res: Response) => {
|
|
11
|
+
const sig = req.headers['stripe-signature'];
|
|
12
|
+
|
|
13
|
+
if (!sig) {
|
|
14
|
+
return res.status(400).send('Missing signature');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
|
|
19
|
+
|
|
20
|
+
switch (event.type) {
|
|
21
|
+
case 'checkout.session.completed':
|
|
22
|
+
console.log('Payment successful:', event.id);
|
|
23
|
+
// Handle successful payment
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
console.log('Unhandled event type:', event.type);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
res.json({ received: true });
|
|
30
|
+
} catch (err: any) {
|
|
31
|
+
console.error('Webhook error:', err.message);
|
|
32
|
+
return res.status(400).send(`Webhook Error: ${err.message}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default router;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getToken } from './auth';
|
|
2
|
+
|
|
3
|
+
const API_BASE = import.meta.env.PUBLIC_API_BASE || 'http://localhost:8080';
|
|
4
|
+
|
|
5
|
+
export async function createCheckoutSession(priceId: string) {
|
|
6
|
+
const token = await getToken();
|
|
7
|
+
|
|
8
|
+
const response = await fetch(`${API_BASE}/api/payments/create-checkout-session`, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
'Authorization': `Bearer ${token}`
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({
|
|
15
|
+
priceId,
|
|
16
|
+
successUrl: `${window.location.origin}/success`,
|
|
17
|
+
cancelUrl: `${window.location.origin}/cancel`
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const data = await response.json();
|
|
22
|
+
|
|
23
|
+
if (data.url) {
|
|
24
|
+
window.location.href = data.url;
|
|
25
|
+
} else {
|
|
26
|
+
throw new Error('Failed to create checkout session');
|
|
27
|
+
}
|
|
28
|
+
}
|