create-rudder-app 0.3.0 → 0.4.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/index.js +100 -20
- package/dist/index.js.map +1 -1
- package/dist/templates/app/auth-controller.d.ts +2 -0
- package/dist/templates/app/auth-controller.d.ts.map +1 -0
- package/dist/templates/app/auth-controller.js +51 -0
- package/dist/templates/app/auth-controller.js.map +1 -0
- package/dist/templates/app/mcp-echo-server.d.ts +2 -0
- package/dist/templates/app/mcp-echo-server.d.ts.map +1 -0
- package/dist/templates/app/mcp-echo-server.js +13 -0
- package/dist/templates/app/mcp-echo-server.js.map +1 -0
- package/dist/templates/app/mcp-echo-tool.d.ts +2 -0
- package/dist/templates/app/mcp-echo-tool.d.ts.map +1 -0
- package/dist/templates/app/mcp-echo-tool.js +20 -0
- package/dist/templates/app/mcp-echo-tool.js.map +1 -0
- package/dist/templates/app/service-provider.d.ts +3 -0
- package/dist/templates/app/service-provider.d.ts.map +1 -0
- package/dist/templates/app/service-provider.js +27 -0
- package/dist/templates/app/service-provider.js.map +1 -0
- package/dist/templates/app/user-model.d.ts +2 -0
- package/dist/templates/app/user-model.d.ts.map +1 -0
- package/dist/templates/app/user-model.js +19 -0
- package/dist/templates/app/user-model.js.map +1 -0
- package/dist/templates/bootstrap/app.d.ts +3 -0
- package/dist/templates/bootstrap/app.d.ts.map +1 -0
- package/dist/templates/bootstrap/app.js +41 -0
- package/dist/templates/bootstrap/app.js.map +1 -0
- package/dist/templates/bootstrap/providers.d.ts +3 -0
- package/dist/templates/bootstrap/providers.d.ts.map +1 -0
- package/dist/templates/bootstrap/providers.js +27 -0
- package/dist/templates/bootstrap/providers.js.map +1 -0
- package/dist/templates/configs/ai.d.ts +2 -0
- package/dist/templates/configs/ai.d.ts.map +1 -0
- package/dist/templates/configs/ai.js +32 -0
- package/dist/templates/configs/ai.js.map +1 -0
- package/dist/templates/configs/app.d.ts +2 -0
- package/dist/templates/configs/app.d.ts.map +1 -0
- package/dist/templates/configs/app.js +12 -0
- package/dist/templates/configs/app.js.map +1 -0
- package/dist/templates/configs/auth.d.ts +3 -0
- package/dist/templates/configs/auth.d.ts.map +1 -0
- package/dist/templates/configs/auth.js +16 -0
- package/dist/templates/configs/auth.js.map +1 -0
- package/dist/templates/configs/cache.d.ts +2 -0
- package/dist/templates/configs/cache.d.ts.map +1 -0
- package/dist/templates/configs/cache.js +28 -0
- package/dist/templates/configs/cache.js.map +1 -0
- package/dist/templates/configs/cashier.d.ts +2 -0
- package/dist/templates/configs/cashier.d.ts.map +1 -0
- package/dist/templates/configs/cashier.js +22 -0
- package/dist/templates/configs/cashier.js.map +1 -0
- package/dist/templates/configs/crypt.d.ts +2 -0
- package/dist/templates/configs/crypt.d.ts.map +1 -0
- package/dist/templates/configs/crypt.js +16 -0
- package/dist/templates/configs/crypt.js.map +1 -0
- package/dist/templates/configs/database.d.ts +3 -0
- package/dist/templates/configs/database.d.ts.map +1 -0
- package/dist/templates/configs/database.js +28 -0
- package/dist/templates/configs/database.js.map +1 -0
- package/dist/templates/configs/hash.d.ts +2 -0
- package/dist/templates/configs/hash.d.ts.map +1 -0
- package/dist/templates/configs/hash.js +12 -0
- package/dist/templates/configs/hash.js.map +1 -0
- package/dist/templates/configs/horizon.d.ts +2 -0
- package/dist/templates/configs/horizon.d.ts.map +1 -0
- package/dist/templates/configs/horizon.js +30 -0
- package/dist/templates/configs/horizon.js.map +1 -0
- package/dist/templates/configs/index.d.ts +3 -0
- package/dist/templates/configs/index.d.ts.map +1 -0
- package/dist/templates/configs/index.js +96 -0
- package/dist/templates/configs/index.js.map +1 -0
- package/dist/templates/configs/localization.d.ts +2 -0
- package/dist/templates/configs/localization.d.ts.map +1 -0
- package/dist/templates/configs/localization.js +13 -0
- package/dist/templates/configs/localization.js.map +1 -0
- package/dist/templates/configs/log.d.ts +2 -0
- package/dist/templates/configs/log.d.ts.map +1 -0
- package/dist/templates/configs/log.js +40 -0
- package/dist/templates/configs/log.js.map +1 -0
- package/dist/templates/configs/mail.d.ts +2 -0
- package/dist/templates/configs/mail.d.ts.map +1 -0
- package/dist/templates/configs/mail.js +33 -0
- package/dist/templates/configs/mail.js.map +1 -0
- package/dist/templates/configs/passport.d.ts +2 -0
- package/dist/templates/configs/passport.d.ts.map +1 -0
- package/dist/templates/configs/passport.js +22 -0
- package/dist/templates/configs/passport.js.map +1 -0
- package/dist/templates/configs/pennant.d.ts +2 -0
- package/dist/templates/configs/pennant.d.ts.map +1 -0
- package/dist/templates/configs/pennant.js +16 -0
- package/dist/templates/configs/pennant.js.map +1 -0
- package/dist/templates/configs/pulse.d.ts +2 -0
- package/dist/templates/configs/pulse.d.ts.map +1 -0
- package/dist/templates/configs/pulse.js +21 -0
- package/dist/templates/configs/pulse.js.map +1 -0
- package/dist/templates/configs/queue.d.ts +2 -0
- package/dist/templates/configs/queue.d.ts.map +1 -0
- package/dist/templates/configs/queue.js +28 -0
- package/dist/templates/configs/queue.js.map +1 -0
- package/dist/templates/configs/sanctum.d.ts +2 -0
- package/dist/templates/configs/sanctum.d.ts.map +1 -0
- package/dist/templates/configs/sanctum.js +19 -0
- package/dist/templates/configs/sanctum.js.map +1 -0
- package/dist/templates/configs/server.d.ts +2 -0
- package/dist/templates/configs/server.d.ts.map +1 -0
- package/dist/templates/configs/server.js +15 -0
- package/dist/templates/configs/server.js.map +1 -0
- package/dist/templates/configs/session.d.ts +2 -0
- package/dist/templates/configs/session.d.ts.map +1 -0
- package/dist/templates/configs/session.js +26 -0
- package/dist/templates/configs/session.js.map +1 -0
- package/dist/templates/configs/socialite.d.ts +2 -0
- package/dist/templates/configs/socialite.d.ts.map +1 -0
- package/dist/templates/configs/socialite.js +27 -0
- package/dist/templates/configs/socialite.js.map +1 -0
- package/dist/templates/configs/storage.d.ts +2 -0
- package/dist/templates/configs/storage.d.ts.map +1 -0
- package/dist/templates/configs/storage.js +35 -0
- package/dist/templates/configs/storage.js.map +1 -0
- package/dist/templates/configs/sync.d.ts +3 -0
- package/dist/templates/configs/sync.d.ts.map +1 -0
- package/dist/templates/configs/sync.js +17 -0
- package/dist/templates/configs/sync.js.map +1 -0
- package/dist/templates/configs/telescope.d.ts +2 -0
- package/dist/templates/configs/telescope.d.ts.map +1 -0
- package/dist/templates/configs/telescope.js +25 -0
- package/dist/templates/configs/telescope.js.map +1 -0
- package/dist/templates/css/index.d.ts +3 -0
- package/dist/templates/css/index.d.ts.map +1 -0
- package/dist/templates/css/index.js +140 -0
- package/dist/templates/css/index.js.map +1 -0
- package/dist/templates/css/plain.d.ts +2 -0
- package/dist/templates/css/plain.d.ts.map +1 -0
- package/dist/templates/css/plain.js +373 -0
- package/dist/templates/css/plain.js.map +1 -0
- package/dist/templates/css/tailwind.d.ts +2 -0
- package/dist/templates/css/tailwind.d.ts.map +1 -0
- package/dist/templates/css/tailwind.js +176 -0
- package/dist/templates/css/tailwind.js.map +1 -0
- package/dist/templates/demos/bk-socket.d.ts +2 -0
- package/dist/templates/demos/bk-socket.d.ts.map +1 -0
- package/dist/templates/demos/bk-socket.js +95 -0
- package/dist/templates/demos/bk-socket.js.map +1 -0
- package/dist/templates/demos/contact.d.ts +3 -0
- package/dist/templates/demos/contact.d.ts.map +1 -0
- package/dist/templates/demos/contact.js +106 -0
- package/dist/templates/demos/contact.js.map +1 -0
- package/dist/templates/demos/index-view.d.ts +3 -0
- package/dist/templates/demos/index-view.d.ts.map +1 -0
- package/dist/templates/demos/index-view.js +67 -0
- package/dist/templates/demos/index-view.js.map +1 -0
- package/dist/templates/demos/live.d.ts +2 -0
- package/dist/templates/demos/live.d.ts.map +1 -0
- package/dist/templates/demos/live.js +97 -0
- package/dist/templates/demos/live.js.map +1 -0
- package/dist/templates/demos/registry.d.ts +13 -0
- package/dist/templates/demos/registry.d.ts.map +1 -0
- package/dist/templates/demos/registry.js +15 -0
- package/dist/templates/demos/registry.js.map +1 -0
- package/dist/templates/demos/ws.d.ts +2 -0
- package/dist/templates/demos/ws.d.ts.map +1 -0
- package/dist/templates/demos/ws.js +106 -0
- package/dist/templates/demos/ws.js.map +1 -0
- package/dist/templates/env.d.ts +7 -0
- package/dist/templates/env.d.ts.map +1 -0
- package/dist/templates/env.js +127 -0
- package/dist/templates/env.js.map +1 -0
- package/dist/templates/package-json.d.ts +3 -0
- package/dist/templates/package-json.d.ts.map +1 -0
- package/dist/templates/package-json.js +195 -0
- package/dist/templates/package-json.js.map +1 -0
- package/dist/templates/package-managers.d.ts +14 -0
- package/dist/templates/package-managers.d.ts.map +1 -0
- package/dist/templates/package-managers.js +49 -0
- package/dist/templates/package-managers.js.map +1 -0
- package/dist/templates/pages/ai-chat.d.ts +7 -0
- package/dist/templates/pages/ai-chat.d.ts.map +1 -0
- package/dist/templates/pages/ai-chat.js +285 -0
- package/dist/templates/pages/ai-chat.js.map +1 -0
- package/dist/templates/pages/demo.d.ts +4 -0
- package/dist/templates/pages/demo.d.ts.map +1 -0
- package/dist/templates/pages/demo.js +71 -0
- package/dist/templates/pages/demo.js.map +1 -0
- package/dist/templates/pages/error.d.ts +7 -0
- package/dist/templates/pages/error.d.ts.map +1 -0
- package/dist/templates/pages/error.js +148 -0
- package/dist/templates/pages/error.js.map +1 -0
- package/dist/templates/pages/index.d.ts +9 -0
- package/dist/templates/pages/index.d.ts.map +1 -0
- package/dist/templates/pages/index.js +311 -0
- package/dist/templates/pages/index.js.map +1 -0
- package/dist/templates/prisma/auth.d.ts +2 -0
- package/dist/templates/prisma/auth.d.ts.map +1 -0
- package/dist/templates/prisma/auth.js +22 -0
- package/dist/templates/prisma/auth.js.map +1 -0
- package/dist/templates/prisma/base.d.ts +3 -0
- package/dist/templates/prisma/base.d.ts.map +1 -0
- package/dist/templates/prisma/base.js +14 -0
- package/dist/templates/prisma/base.js.map +1 -0
- package/dist/templates/prisma/config.d.ts +3 -0
- package/dist/templates/prisma/config.d.ts.map +1 -0
- package/dist/templates/prisma/config.js +15 -0
- package/dist/templates/prisma/config.js.map +1 -0
- package/dist/templates/prisma/notification.d.ts +2 -0
- package/dist/templates/prisma/notification.d.ts.map +1 -0
- package/dist/templates/prisma/notification.js +16 -0
- package/dist/templates/prisma/notification.js.map +1 -0
- package/dist/templates/prisma/passport.d.ts +2 -0
- package/dist/templates/prisma/passport.d.ts.map +1 -0
- package/dist/templates/prisma/passport.js +69 -0
- package/dist/templates/prisma/passport.js.map +1 -0
- package/dist/templates/routes/api.d.ts +3 -0
- package/dist/templates/routes/api.d.ts.map +1 -0
- package/dist/templates/routes/api.js +118 -0
- package/dist/templates/routes/api.js.map +1 -0
- package/dist/templates/routes/console.d.ts +2 -0
- package/dist/templates/routes/console.d.ts.map +1 -0
- package/dist/templates/routes/console.js +22 -0
- package/dist/templates/routes/console.js.map +1 -0
- package/dist/templates/routes/web.d.ts +4 -0
- package/dist/templates/routes/web.d.ts.map +1 -0
- package/dist/templates/routes/web.js +108 -0
- package/dist/templates/routes/web.js.map +1 -0
- package/dist/templates/server.d.ts +2 -0
- package/dist/templates/server.d.ts.map +1 -0
- package/dist/templates/server.js +10 -0
- package/dist/templates/server.js.map +1 -0
- package/dist/templates/tsconfig.d.ts +3 -0
- package/dist/templates/tsconfig.d.ts.map +1 -0
- package/dist/templates/tsconfig.js +33 -0
- package/dist/templates/tsconfig.js.map +1 -0
- package/dist/templates/views/welcome.d.ts +6 -0
- package/dist/templates/views/welcome.d.ts.map +1 -0
- package/dist/templates/views/welcome.js +396 -0
- package/dist/templates/views/welcome.js.map +1 -0
- package/dist/templates/vite.d.ts +3 -0
- package/dist/templates/vite.d.ts.map +1 -0
- package/dist/templates/vite.js +61 -0
- package/dist/templates/vite.js.map +1 -0
- package/dist/templates.d.ts +28 -17
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +99 -3779
- package/dist/templates.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export function demosContactView(ctx) {
|
|
2
|
+
// CSRF is only enforced when @rudderjs/auth is installed (CsrfMiddleware
|
|
3
|
+
// wraps the /api/contact route in routes/api.ts). Without auth, the
|
|
4
|
+
// unprotected form just succeeds.
|
|
5
|
+
const sendsCsrf = ctx.packages.auth ? 'true' : 'false';
|
|
6
|
+
return `import '@/index.css'
|
|
7
|
+
import { useState } from 'react'
|
|
8
|
+
import { getCsrfToken } from '@rudderjs/middleware'
|
|
9
|
+
|
|
10
|
+
interface FormFields { name: string; email: string; message: string }
|
|
11
|
+
interface FormErrors { name?: string; email?: string; message?: string }
|
|
12
|
+
|
|
13
|
+
export default function ContactDemo() {
|
|
14
|
+
const [fields, setFields] = useState<FormFields>({ name: '', email: '', message: '' })
|
|
15
|
+
const [errors, setErrors] = useState<FormErrors>({})
|
|
16
|
+
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle')
|
|
17
|
+
const [message, setMessage] = useState('')
|
|
18
|
+
|
|
19
|
+
function setField(key: keyof FormFields, value: string) {
|
|
20
|
+
setFields(f => ({ ...f, [key]: value }))
|
|
21
|
+
if (errors[key]) setErrors(e => ({ ...e, [key]: undefined }))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function submit(e: React.FormEvent) {
|
|
25
|
+
e.preventDefault()
|
|
26
|
+
setStatus('loading')
|
|
27
|
+
setErrors({})
|
|
28
|
+
|
|
29
|
+
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
|
|
30
|
+
if (${sendsCsrf}) headers['X-CSRF-Token'] = getCsrfToken()
|
|
31
|
+
|
|
32
|
+
const res = await fetch('/api/contact', {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers,
|
|
35
|
+
body: JSON.stringify(fields),
|
|
36
|
+
})
|
|
37
|
+
const data = await res.json() as { ok?: boolean; message?: string; errors?: FormErrors }
|
|
38
|
+
|
|
39
|
+
if (res.ok) {
|
|
40
|
+
setStatus('success')
|
|
41
|
+
setMessage(data.message ?? 'Thanks!')
|
|
42
|
+
setFields({ name: '', email: '', message: '' })
|
|
43
|
+
} else if (res.status === 422) {
|
|
44
|
+
setStatus('error')
|
|
45
|
+
setErrors(data.errors ?? {})
|
|
46
|
+
} else {
|
|
47
|
+
setStatus('error')
|
|
48
|
+
setMessage(\`\${res.status} — \${data.message ?? 'Request failed.'}\`)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className="page">
|
|
54
|
+
<nav className="page-nav">
|
|
55
|
+
<div className="brand">
|
|
56
|
+
<span className="brand-dot" />
|
|
57
|
+
RudderJS
|
|
58
|
+
</div>
|
|
59
|
+
<div className="nav-right">
|
|
60
|
+
<a href="/demos" className="nav-link">← Demos</a>
|
|
61
|
+
</div>
|
|
62
|
+
</nav>
|
|
63
|
+
|
|
64
|
+
<section className="hero">
|
|
65
|
+
<h1 className="hero-title">Contact</h1>
|
|
66
|
+
<p className="hero-lead">
|
|
67
|
+
POSTs to <code className="inline-code">/api/contact</code>${ctx.packages.auth
|
|
68
|
+
? ' with an X-CSRF-Token header.'
|
|
69
|
+
: '. Add @rudderjs/auth to require CSRF.'}{' '}
|
|
70
|
+
Server-side validated with Zod.
|
|
71
|
+
</p>
|
|
72
|
+
</section>
|
|
73
|
+
|
|
74
|
+
<section className="feature-section" style={{ maxWidth: '32rem', margin: '0 auto' }}>
|
|
75
|
+
<form onSubmit={submit} className="form-card">
|
|
76
|
+
<div>
|
|
77
|
+
<label className="form-label" htmlFor="name">Name</label>
|
|
78
|
+
<input id="name" className="form-input" value={fields.name}
|
|
79
|
+
onChange={e => setField('name', e.target.value)} />
|
|
80
|
+
{errors.name && <p className="form-error">{errors.name}</p>}
|
|
81
|
+
</div>
|
|
82
|
+
<div>
|
|
83
|
+
<label className="form-label" htmlFor="email">Email</label>
|
|
84
|
+
<input id="email" type="email" className="form-input" value={fields.email}
|
|
85
|
+
onChange={e => setField('email', e.target.value)} />
|
|
86
|
+
{errors.email && <p className="form-error">{errors.email}</p>}
|
|
87
|
+
</div>
|
|
88
|
+
<div>
|
|
89
|
+
<label className="form-label" htmlFor="message">Message</label>
|
|
90
|
+
<textarea id="message" rows={4} className="form-input" value={fields.message}
|
|
91
|
+
onChange={e => setField('message', e.target.value)} />
|
|
92
|
+
{errors.message && <p className="form-error">{errors.message}</p>}
|
|
93
|
+
</div>
|
|
94
|
+
<button type="submit" className="form-submit" disabled={status === 'loading'}>
|
|
95
|
+
{status === 'loading' ? 'Sending…' : 'Send message'}
|
|
96
|
+
</button>
|
|
97
|
+
{status === 'success' && <p className="form-success">{message}</p>}
|
|
98
|
+
{status === 'error' && message && <p className="form-error">{message}</p>}
|
|
99
|
+
</form>
|
|
100
|
+
</section>
|
|
101
|
+
</div>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=contact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact.js","sourceRoot":"","sources":["../../../src/templates/demos/contact.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,GAAoB;IACnD,yEAAyE;IACzE,oEAAoE;IACpE,kCAAkC;IAClC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IAEtD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;UAwBC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sEAqCmD,GAAG,CAAC,QAAQ,CAAC,IAAI;QAC/E,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChD,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-view.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/index-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAE7E,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAkE3D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { shouldScaffoldDemo } from '../../templates.js';
|
|
2
|
+
export function demosIndexView(ctx) {
|
|
3
|
+
const cards = [
|
|
4
|
+
{
|
|
5
|
+
title: 'Contact form',
|
|
6
|
+
desc: 'CSRF-protected form with Zod validation. Demonstrates getCsrfToken() and FormRequest-style error handling.',
|
|
7
|
+
href: '/demos/contact',
|
|
8
|
+
pkgs: '@rudderjs/middleware · @rudderjs/core',
|
|
9
|
+
show: shouldScaffoldDemo(ctx, 'contact'),
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
title: 'WebSocket chat',
|
|
13
|
+
desc: 'Real-time chat + presence using @rudderjs/broadcast — multi-channel pub/sub over a single WebSocket connection.',
|
|
14
|
+
href: '/demos/ws',
|
|
15
|
+
pkgs: '@rudderjs/broadcast',
|
|
16
|
+
show: shouldScaffoldDemo(ctx, 'ws'),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: 'Collaborative editor',
|
|
20
|
+
desc: 'Yjs CRDT live document with awareness cursors. Open in two tabs to see real-time sync over @rudderjs/sync.',
|
|
21
|
+
href: '/demos/live',
|
|
22
|
+
pkgs: '@rudderjs/sync',
|
|
23
|
+
show: shouldScaffoldDemo(ctx, 'live'),
|
|
24
|
+
},
|
|
25
|
+
].filter(c => c.show);
|
|
26
|
+
const cardsJsx = cards.map(c => ` <a key="${c.href}" href="${c.href}" className="feature-card">
|
|
27
|
+
<h3 className="feature-title">${c.title}</h3>
|
|
28
|
+
<p className="feature-desc">${c.desc}</p>
|
|
29
|
+
<p className="feature-desc" style={{ fontSize: '0.7rem', opacity: 0.7 }}>${c.pkgs}</p>
|
|
30
|
+
</a>`).join('\n');
|
|
31
|
+
return `import '@/index.css'
|
|
32
|
+
|
|
33
|
+
// Override the id-derived URL ('/demos/index') so SPA nav matches the controller ('/demos').
|
|
34
|
+
export const route = '/demos'
|
|
35
|
+
|
|
36
|
+
export default function DemosIndex() {
|
|
37
|
+
return (
|
|
38
|
+
<div className="page">
|
|
39
|
+
<nav className="page-nav">
|
|
40
|
+
<div className="brand">
|
|
41
|
+
<span className="brand-dot" />
|
|
42
|
+
RudderJS
|
|
43
|
+
</div>
|
|
44
|
+
<div className="nav-right">
|
|
45
|
+
<a href="/" className="nav-link">Home</a>
|
|
46
|
+
</div>
|
|
47
|
+
</nav>
|
|
48
|
+
|
|
49
|
+
<section className="hero">
|
|
50
|
+
<h1 className="hero-title">Demos</h1>
|
|
51
|
+
<p className="hero-lead">
|
|
52
|
+
Small, focused examples of what the framework can do. Each one is a single
|
|
53
|
+
controller returning <code className="inline-code">view('demos.<name>')</code>.
|
|
54
|
+
</p>
|
|
55
|
+
</section>
|
|
56
|
+
|
|
57
|
+
<section className="feature-section">
|
|
58
|
+
<div className="feature-grid">
|
|
59
|
+
${cardsJsx}
|
|
60
|
+
</div>
|
|
61
|
+
</section>
|
|
62
|
+
</div>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=index-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-view.js","sourceRoot":"","sources":["../../../src/templates/demos/index-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAwB,MAAM,oBAAoB,CAAA;AAE7E,MAAM,UAAU,cAAc,CAAC,GAAoB;IACjD,MAAM,KAAK,GAAiF;QAC1F;YACE,KAAK,EAAE,cAAc;YACrB,IAAI,EAAG,4GAA4G;YACnH,IAAI,EAAG,gBAAgB;YACvB,IAAI,EAAG,uCAAuC;YAC9C,IAAI,EAAG,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC;SAC1C;QACD;YACE,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAG,iHAAiH;YACxH,IAAI,EAAG,WAAW;YAClB,IAAI,EAAG,qBAAqB;YAC5B,IAAI,EAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC;SACrC;QACD;YACE,KAAK,EAAE,sBAAsB;YAC7B,IAAI,EAAG,4GAA4G;YACnH,IAAI,EAAG,aAAa;YACpB,IAAI,EAAG,gBAAgB;YACvB,IAAI,EAAG,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC;SACvC;KACF,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAErB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,IAAI;0CAClC,CAAC,CAAC,KAAK;wCACT,CAAC,CAAC,IAAI;qFACuC,CAAC,CAAC,IAAI;aAC9E,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEvB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BP,QAAQ;;;;;;CAMT,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/live.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,IAAI,MAAM,CA+FtC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export function demosLiveView() {
|
|
2
|
+
return `import '@/index.css'
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
|
+
import * as Y from 'yjs'
|
|
5
|
+
import { WebsocketProvider } from 'y-websocket'
|
|
6
|
+
|
|
7
|
+
function getWsUrl() {
|
|
8
|
+
if (typeof window === 'undefined') return ''
|
|
9
|
+
return \`ws://\${window.location.host}/ws-sync\`
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function LiveDemo() {
|
|
13
|
+
const [connected, setConnected] = useState(false)
|
|
14
|
+
const [text, setText] = useState('')
|
|
15
|
+
const [users, setUsers] = useState<{ name: string; color: string }[]>([])
|
|
16
|
+
const [myName] = useState(() => \`User-\${Math.floor(Math.random() * 1000)}\`)
|
|
17
|
+
const [myColor] = useState(() => \`hsl(\${Math.floor(Math.random() * 360)}, 70%, 50%)\`)
|
|
18
|
+
|
|
19
|
+
const docRef = useRef<Y.Doc | null>(null)
|
|
20
|
+
const provRef = useRef<WebsocketProvider | null>(null)
|
|
21
|
+
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const doc = new Y.Doc()
|
|
25
|
+
const ytext = doc.getText('content')
|
|
26
|
+
const provider = new WebsocketProvider(getWsUrl(), 'live-demo', doc)
|
|
27
|
+
|
|
28
|
+
docRef.current = doc
|
|
29
|
+
provRef.current = provider
|
|
30
|
+
|
|
31
|
+
ytext.observe(() => setText(ytext.toString()))
|
|
32
|
+
provider.on('status', ({ status }: { status: string }) => setConnected(status === 'connected'))
|
|
33
|
+
provider.awareness.setLocalStateField('user', { name: myName, color: myColor })
|
|
34
|
+
|
|
35
|
+
const syncUsers = () => {
|
|
36
|
+
const states = [...provider.awareness.getStates().values()] as { user?: { name: string; color: string } }[]
|
|
37
|
+
setUsers(states.map(s => s.user).filter((u): u is { name: string; color: string } => Boolean(u)))
|
|
38
|
+
}
|
|
39
|
+
provider.awareness.on('change', syncUsers)
|
|
40
|
+
syncUsers()
|
|
41
|
+
|
|
42
|
+
return () => { provider.destroy(); doc.destroy() }
|
|
43
|
+
}, [myName, myColor])
|
|
44
|
+
|
|
45
|
+
function onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
|
|
46
|
+
const ytext = docRef.current?.getText('content')
|
|
47
|
+
if (!ytext) return
|
|
48
|
+
docRef.current?.transact(() => {
|
|
49
|
+
ytext.delete(0, ytext.length)
|
|
50
|
+
ytext.insert(0, e.target.value)
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="page">
|
|
56
|
+
<nav className="page-nav">
|
|
57
|
+
<div className="brand">
|
|
58
|
+
<span className="brand-dot" />
|
|
59
|
+
RudderJS
|
|
60
|
+
</div>
|
|
61
|
+
<div className="nav-right">
|
|
62
|
+
<a href="/demos" className="nav-link">← Demos</a>
|
|
63
|
+
</div>
|
|
64
|
+
</nav>
|
|
65
|
+
|
|
66
|
+
<section className="hero">
|
|
67
|
+
<h1 className="hero-title">Collaborative editor</h1>
|
|
68
|
+
<p className="hero-lead">
|
|
69
|
+
Yjs CRDT over @rudderjs/sync. Open this page in two tabs to see real-time updates.{' '}
|
|
70
|
+
{connected ? '🟢 connected' : '⚪ connecting…'}
|
|
71
|
+
</p>
|
|
72
|
+
</section>
|
|
73
|
+
|
|
74
|
+
<section className="feature-section" style={{ maxWidth: '40rem', margin: '0 auto' }}>
|
|
75
|
+
<p className="form-label">Active users:</p>
|
|
76
|
+
<ul style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginBottom: '1rem' }}>
|
|
77
|
+
{users.map((u, i) => (
|
|
78
|
+
<li key={i} className="inline-code" style={{ borderLeft: \`3px solid \${u.color}\`, paddingLeft: '0.5rem' }}>
|
|
79
|
+
{u.name}
|
|
80
|
+
</li>
|
|
81
|
+
))}
|
|
82
|
+
</ul>
|
|
83
|
+
<textarea
|
|
84
|
+
ref={textareaRef}
|
|
85
|
+
className="form-input"
|
|
86
|
+
rows={10}
|
|
87
|
+
value={text}
|
|
88
|
+
onChange={onChange}
|
|
89
|
+
placeholder="Start typing…"
|
|
90
|
+
/>
|
|
91
|
+
</section>
|
|
92
|
+
</div>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../../src/templates/demos/live.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6FR,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TemplateContext } from '../../templates.js';
|
|
2
|
+
export interface DemoSpec {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
hint?: string;
|
|
6
|
+
/** Package keys that must all be selected for this demo to scaffold. */
|
|
7
|
+
requires?: ReadonlyArray<keyof TemplateContext['packages']>;
|
|
8
|
+
/** True if this demo requires a database/ORM. */
|
|
9
|
+
requiresOrm?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEMOS: ReadonlyArray<DemoSpec>;
|
|
12
|
+
export declare function availableDemos(orm: TemplateContext['orm'], packages: TemplateContext['packages']): DemoSpec[];
|
|
13
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAS,MAAM,CAAA;IACpB,KAAK,EAAS,MAAM,CAAA;IACpB,IAAI,CAAC,EAAS,MAAM,CAAA;IACpB,wEAAwE;IACxE,QAAQ,CAAC,EAAK,aAAa,CAAC,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC,CAAA;IAC9D,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,QAAQ,CAIzC,CAAA;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,GACpC,QAAQ,EAAE,CAMZ"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const DEMOS = [
|
|
2
|
+
{ value: 'contact', label: 'Contact form', hint: 'CSRF + Zod validation' },
|
|
3
|
+
{ value: 'ws', label: 'WebSocket chat', hint: 'requires WebSocket / Broadcast', requires: ['broadcast'] },
|
|
4
|
+
{ value: 'live', label: 'Yjs collaboration', hint: 'requires Sync', requires: ['sync'] },
|
|
5
|
+
];
|
|
6
|
+
export function availableDemos(orm, packages) {
|
|
7
|
+
return DEMOS.filter(d => {
|
|
8
|
+
if (d.requiresOrm && orm === false)
|
|
9
|
+
return false;
|
|
10
|
+
if (d.requires)
|
|
11
|
+
return d.requires.every(p => packages[p]);
|
|
12
|
+
return true;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/templates/demos/registry.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,KAAK,GAA4B;IAC5C,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAO,IAAI,EAAE,uBAAuB,EAAE;IAC/E,EAAE,KAAK,EAAE,IAAI,EAAO,KAAK,EAAE,gBAAgB,EAAK,IAAI,EAAE,gCAAgC,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;IACjH,EAAE,KAAK,EAAE,MAAM,EAAK,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,eAAe,EAAmB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;CAC7G,CAAA;AAED,MAAM,UAAU,cAAc,CAC5B,GAA2B,EAC3B,QAAqC;IAErC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACtB,IAAI,CAAC,CAAC,WAAW,IAAI,GAAG,KAAK,KAAK;YAAE,OAAO,KAAK,CAAA;QAChD,IAAI,CAAC,CAAC,QAAQ;YAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACzD,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/ws.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,IAAI,MAAM,CAwGpC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export function demosWsView() {
|
|
2
|
+
return `import '@/index.css'
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { BKSocket } from '@/BKSocket'
|
|
5
|
+
|
|
6
|
+
type Message = { user: string; text: string; ts: number }
|
|
7
|
+
type Member = { id: string; name: string }
|
|
8
|
+
|
|
9
|
+
function getWsUrl() {
|
|
10
|
+
if (typeof window === 'undefined') return ''
|
|
11
|
+
return \`ws://\${window.location.host}/ws\`
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function WsDemo() {
|
|
15
|
+
const [me, setMe] = useState('')
|
|
16
|
+
const socketRef = useRef<BKSocket | null>(null)
|
|
17
|
+
const [connected, setConnected] = useState(false)
|
|
18
|
+
const [messages, setMessages] = useState<Message[]>([])
|
|
19
|
+
const [members, setMembers] = useState<Member[]>([])
|
|
20
|
+
const [input, setInput] = useState('')
|
|
21
|
+
|
|
22
|
+
useEffect(() => { setMe(\`User-\${Math.floor(Math.random() * 1000)}\`) }, [])
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!me) return
|
|
26
|
+
const socket = new BKSocket(getWsUrl())
|
|
27
|
+
socketRef.current = socket
|
|
28
|
+
|
|
29
|
+
const chat = socket.channel('chat')
|
|
30
|
+
chat.on('message', d => setMessages(prev => [...prev, d as Message]))
|
|
31
|
+
|
|
32
|
+
const room = socket.presence('lobby', 'demo-token')
|
|
33
|
+
room.on('presence.members', d => {
|
|
34
|
+
setMembers(d as Member[])
|
|
35
|
+
setConnected(true)
|
|
36
|
+
})
|
|
37
|
+
room.on('presence.joined', d => {
|
|
38
|
+
const u = d as Member
|
|
39
|
+
setMembers(prev => [...prev.filter(m => m.id !== u.id), u])
|
|
40
|
+
})
|
|
41
|
+
room.on('presence.left', d => {
|
|
42
|
+
const id = (d as { id: string }).id
|
|
43
|
+
setMembers(prev => prev.filter(m => m.id !== id))
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
return () => { socket.close() }
|
|
47
|
+
}, [me])
|
|
48
|
+
|
|
49
|
+
async function send() {
|
|
50
|
+
if (!input.trim()) return
|
|
51
|
+
await fetch('/api/ws/broadcast', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/json' },
|
|
54
|
+
body: JSON.stringify({ user: me, text: input.trim() }),
|
|
55
|
+
})
|
|
56
|
+
setInput('')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div className="page">
|
|
61
|
+
<nav className="page-nav">
|
|
62
|
+
<div className="brand">
|
|
63
|
+
<span className="brand-dot" />
|
|
64
|
+
RudderJS
|
|
65
|
+
</div>
|
|
66
|
+
<div className="nav-right">
|
|
67
|
+
<a href="/demos" className="nav-link">← Demos</a>
|
|
68
|
+
</div>
|
|
69
|
+
</nav>
|
|
70
|
+
|
|
71
|
+
<section className="hero">
|
|
72
|
+
<h1 className="hero-title">WebSocket chat</h1>
|
|
73
|
+
<p className="hero-lead">
|
|
74
|
+
Pub/sub + presence over a single WebSocket. Connected as <strong>{me}</strong>.{' '}
|
|
75
|
+
{connected ? '🟢 connected' : '⚪ connecting…'}
|
|
76
|
+
</p>
|
|
77
|
+
</section>
|
|
78
|
+
|
|
79
|
+
<section className="feature-section" style={{ maxWidth: '40rem', margin: '0 auto' }}>
|
|
80
|
+
<p className="form-label">Members ({members.length})</p>
|
|
81
|
+
<ul style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginBottom: '1rem' }}>
|
|
82
|
+
{members.map(m => (
|
|
83
|
+
<li key={m.id} className="inline-code">{m.name}</li>
|
|
84
|
+
))}
|
|
85
|
+
</ul>
|
|
86
|
+
|
|
87
|
+
<div style={{ minHeight: '12rem', marginBottom: '1rem' }}>
|
|
88
|
+
{messages.map((m, i) => (
|
|
89
|
+
<p key={i} style={{ margin: '0.25rem 0' }}>
|
|
90
|
+
<strong>{m.user}:</strong> {m.text}
|
|
91
|
+
</p>
|
|
92
|
+
))}
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<form onSubmit={e => { e.preventDefault(); void send() }} style={{ display: 'flex', gap: '0.5rem' }}>
|
|
96
|
+
<input className="form-input" value={input}
|
|
97
|
+
onChange={e => setInput(e.target.value)} placeholder="Say something…" />
|
|
98
|
+
<button type="submit" className="form-submit" style={{ width: 'auto' }}>Send</button>
|
|
99
|
+
</form>
|
|
100
|
+
</section>
|
|
101
|
+
</div>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=ws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws.js","sourceRoot":"","sources":["../../../src/templates/demos/ws.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGR,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TemplateContext } from '../templates.js';
|
|
2
|
+
export declare function dotenv(ctx: TemplateContext): string;
|
|
3
|
+
export declare function dotenvExample(ctx: TemplateContext): string;
|
|
4
|
+
export declare function envDts(): string;
|
|
5
|
+
export declare function gitignore(): string;
|
|
6
|
+
export declare function pnpmWorkspace(): string;
|
|
7
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/templates/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,wBAAgB,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAuDnD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAwD1D;AAED,wBAAgB,MAAM,IAAI,MAAM,CAO/B;AAED,wBAAgB,SAAS,IAAI,MAAM,CASlC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export function dotenv(ctx) {
|
|
2
|
+
const lines = [
|
|
3
|
+
`APP_NAME=${ctx.name}`,
|
|
4
|
+
'APP_ENV=development',
|
|
5
|
+
'APP_DEBUG=true',
|
|
6
|
+
'APP_URL=http://localhost:3000',
|
|
7
|
+
'',
|
|
8
|
+
'PORT=3000',
|
|
9
|
+
];
|
|
10
|
+
if (ctx.orm) {
|
|
11
|
+
lines.push('');
|
|
12
|
+
if (ctx.db === 'sqlite')
|
|
13
|
+
lines.push('DATABASE_URL="file:./dev.db"');
|
|
14
|
+
else if (ctx.db === 'postgresql')
|
|
15
|
+
lines.push('DATABASE_URL="postgresql://user:password@localhost:5432/mydb"');
|
|
16
|
+
else
|
|
17
|
+
lines.push('DATABASE_URL="mysql://user:password@localhost:3306/mydb"');
|
|
18
|
+
}
|
|
19
|
+
if (ctx.packages.auth) {
|
|
20
|
+
lines.push('');
|
|
21
|
+
lines.push(`AUTH_SECRET=${ctx.authSecret}`);
|
|
22
|
+
}
|
|
23
|
+
if (ctx.packages.crypt) {
|
|
24
|
+
lines.push('');
|
|
25
|
+
lines.push(`APP_KEY=base64:${ctx.appKey}`);
|
|
26
|
+
}
|
|
27
|
+
if (ctx.packages.ai) {
|
|
28
|
+
lines.push('');
|
|
29
|
+
lines.push('AI_MODEL=anthropic/claude-sonnet-4-5');
|
|
30
|
+
lines.push('ANTHROPIC_API_KEY=');
|
|
31
|
+
lines.push('# OPENAI_API_KEY=');
|
|
32
|
+
lines.push('# GOOGLE_AI_API_KEY=');
|
|
33
|
+
lines.push('# OLLAMA_BASE_URL=http://localhost:11434');
|
|
34
|
+
}
|
|
35
|
+
if (ctx.packages.socialite) {
|
|
36
|
+
lines.push('');
|
|
37
|
+
lines.push('GITHUB_CLIENT_ID=');
|
|
38
|
+
lines.push('GITHUB_CLIENT_SECRET=');
|
|
39
|
+
lines.push('GITHUB_REDIRECT_URL=http://localhost:3000/auth/github/callback');
|
|
40
|
+
lines.push('GOOGLE_CLIENT_ID=');
|
|
41
|
+
lines.push('GOOGLE_CLIENT_SECRET=');
|
|
42
|
+
lines.push('GOOGLE_REDIRECT_URL=http://localhost:3000/auth/google/callback');
|
|
43
|
+
}
|
|
44
|
+
if (ctx.packages.cashierPaddle) {
|
|
45
|
+
lines.push('');
|
|
46
|
+
lines.push('PADDLE_API_KEY=');
|
|
47
|
+
lines.push('PADDLE_CLIENT_SIDE_TOKEN=');
|
|
48
|
+
lines.push('PADDLE_WEBHOOK_SECRET=');
|
|
49
|
+
lines.push('PADDLE_SANDBOX=true');
|
|
50
|
+
}
|
|
51
|
+
return lines.join('\n') + '\n';
|
|
52
|
+
}
|
|
53
|
+
export function dotenvExample(ctx) {
|
|
54
|
+
const lines = [
|
|
55
|
+
`APP_NAME=${ctx.name}`,
|
|
56
|
+
'APP_ENV=development',
|
|
57
|
+
'APP_DEBUG=false',
|
|
58
|
+
'APP_URL=http://localhost:3000',
|
|
59
|
+
'',
|
|
60
|
+
'PORT=3000',
|
|
61
|
+
];
|
|
62
|
+
if (ctx.orm) {
|
|
63
|
+
lines.push('');
|
|
64
|
+
if (ctx.db === 'sqlite')
|
|
65
|
+
lines.push('DATABASE_URL="file:./dev.db"');
|
|
66
|
+
else if (ctx.db === 'postgresql')
|
|
67
|
+
lines.push('DATABASE_URL="postgresql://user:password@localhost:5432/mydb"');
|
|
68
|
+
else
|
|
69
|
+
lines.push('DATABASE_URL="mysql://user:password@localhost:3306/mydb"');
|
|
70
|
+
}
|
|
71
|
+
if (ctx.packages.auth) {
|
|
72
|
+
lines.push('');
|
|
73
|
+
lines.push('AUTH_SECRET=please-set-a-real-32-char-secret-here');
|
|
74
|
+
}
|
|
75
|
+
if (ctx.packages.crypt) {
|
|
76
|
+
lines.push('');
|
|
77
|
+
lines.push('# Generate with: node -e "console.log(\'base64:\' + require(\'crypto\').randomBytes(32).toString(\'base64\'))"');
|
|
78
|
+
lines.push('APP_KEY=');
|
|
79
|
+
}
|
|
80
|
+
if (ctx.packages.ai) {
|
|
81
|
+
lines.push('');
|
|
82
|
+
lines.push('AI_MODEL=anthropic/claude-sonnet-4-5');
|
|
83
|
+
lines.push('ANTHROPIC_API_KEY=');
|
|
84
|
+
lines.push('# OPENAI_API_KEY=');
|
|
85
|
+
lines.push('# GOOGLE_AI_API_KEY=');
|
|
86
|
+
lines.push('# OLLAMA_BASE_URL=http://localhost:11434');
|
|
87
|
+
}
|
|
88
|
+
if (ctx.packages.socialite) {
|
|
89
|
+
lines.push('');
|
|
90
|
+
lines.push('GITHUB_CLIENT_ID=');
|
|
91
|
+
lines.push('GITHUB_CLIENT_SECRET=');
|
|
92
|
+
lines.push('GITHUB_REDIRECT_URL=http://localhost:3000/auth/github/callback');
|
|
93
|
+
lines.push('GOOGLE_CLIENT_ID=');
|
|
94
|
+
lines.push('GOOGLE_CLIENT_SECRET=');
|
|
95
|
+
lines.push('GOOGLE_REDIRECT_URL=http://localhost:3000/auth/google/callback');
|
|
96
|
+
}
|
|
97
|
+
if (ctx.packages.cashierPaddle) {
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push('PADDLE_API_KEY=');
|
|
100
|
+
lines.push('PADDLE_CLIENT_SIDE_TOKEN=');
|
|
101
|
+
lines.push('PADDLE_WEBHOOK_SECRET=');
|
|
102
|
+
lines.push('PADDLE_SANDBOX=true');
|
|
103
|
+
}
|
|
104
|
+
return lines.join('\n') + '\n';
|
|
105
|
+
}
|
|
106
|
+
export function envDts() {
|
|
107
|
+
return `import type { Configs } from './config/index.js'
|
|
108
|
+
|
|
109
|
+
declare module '@rudderjs/core' {
|
|
110
|
+
interface AppConfig extends Configs {}
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
export function gitignore() {
|
|
115
|
+
return `node_modules/
|
|
116
|
+
dist/
|
|
117
|
+
.env
|
|
118
|
+
*.db
|
|
119
|
+
*.db-journal
|
|
120
|
+
prisma/generated/
|
|
121
|
+
bootstrap/cache/
|
|
122
|
+
`;
|
|
123
|
+
}
|
|
124
|
+
export function pnpmWorkspace() {
|
|
125
|
+
return `# Standalone project — prevents pnpm from merging with a parent workspace\npackages: []\n`;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/templates/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json.d.ts","sourceRoot":"","sources":["../../src/templates/package-json.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAE1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA4KxD"}
|