create-rudder-app 0.3.1 → 0.5.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 (283) hide show
  1. package/dist/index.js +98 -20
  2. package/dist/index.js.map +1 -1
  3. package/dist/templates/app/auth-controller.d.ts +2 -0
  4. package/dist/templates/app/auth-controller.d.ts.map +1 -0
  5. package/dist/templates/app/auth-controller.js +51 -0
  6. package/dist/templates/app/auth-controller.js.map +1 -0
  7. package/dist/templates/app/mcp-echo-server.d.ts +2 -0
  8. package/dist/templates/app/mcp-echo-server.d.ts.map +1 -0
  9. package/dist/templates/app/mcp-echo-server.js +13 -0
  10. package/dist/templates/app/mcp-echo-server.js.map +1 -0
  11. package/dist/templates/app/mcp-echo-tool.d.ts +2 -0
  12. package/dist/templates/app/mcp-echo-tool.d.ts.map +1 -0
  13. package/dist/templates/app/mcp-echo-tool.js +20 -0
  14. package/dist/templates/app/mcp-echo-tool.js.map +1 -0
  15. package/dist/templates/app/service-provider.d.ts +3 -0
  16. package/dist/templates/app/service-provider.d.ts.map +1 -0
  17. package/dist/templates/app/service-provider.js +48 -0
  18. package/dist/templates/app/service-provider.js.map +1 -0
  19. package/dist/templates/app/user-model.d.ts +2 -0
  20. package/dist/templates/app/user-model.d.ts.map +1 -0
  21. package/dist/templates/app/user-model.js +19 -0
  22. package/dist/templates/app/user-model.js.map +1 -0
  23. package/dist/templates/bootstrap/app.d.ts +3 -0
  24. package/dist/templates/bootstrap/app.d.ts.map +1 -0
  25. package/dist/templates/bootstrap/app.js +41 -0
  26. package/dist/templates/bootstrap/app.js.map +1 -0
  27. package/dist/templates/bootstrap/providers.d.ts +3 -0
  28. package/dist/templates/bootstrap/providers.d.ts.map +1 -0
  29. package/dist/templates/bootstrap/providers.js +27 -0
  30. package/dist/templates/bootstrap/providers.js.map +1 -0
  31. package/dist/templates/configs/ai.d.ts +2 -0
  32. package/dist/templates/configs/ai.d.ts.map +1 -0
  33. package/dist/templates/configs/ai.js +32 -0
  34. package/dist/templates/configs/ai.js.map +1 -0
  35. package/dist/templates/configs/app.d.ts +2 -0
  36. package/dist/templates/configs/app.d.ts.map +1 -0
  37. package/dist/templates/configs/app.js +12 -0
  38. package/dist/templates/configs/app.js.map +1 -0
  39. package/dist/templates/configs/auth.d.ts +3 -0
  40. package/dist/templates/configs/auth.d.ts.map +1 -0
  41. package/dist/templates/configs/auth.js +16 -0
  42. package/dist/templates/configs/auth.js.map +1 -0
  43. package/dist/templates/configs/cache.d.ts +2 -0
  44. package/dist/templates/configs/cache.d.ts.map +1 -0
  45. package/dist/templates/configs/cache.js +28 -0
  46. package/dist/templates/configs/cache.js.map +1 -0
  47. package/dist/templates/configs/crypt.d.ts +2 -0
  48. package/dist/templates/configs/crypt.d.ts.map +1 -0
  49. package/dist/templates/configs/crypt.js +16 -0
  50. package/dist/templates/configs/crypt.js.map +1 -0
  51. package/dist/templates/configs/database.d.ts +3 -0
  52. package/dist/templates/configs/database.d.ts.map +1 -0
  53. package/dist/templates/configs/database.js +28 -0
  54. package/dist/templates/configs/database.js.map +1 -0
  55. package/dist/templates/configs/hash.d.ts +2 -0
  56. package/dist/templates/configs/hash.d.ts.map +1 -0
  57. package/dist/templates/configs/hash.js +12 -0
  58. package/dist/templates/configs/hash.js.map +1 -0
  59. package/dist/templates/configs/horizon.d.ts +2 -0
  60. package/dist/templates/configs/horizon.d.ts.map +1 -0
  61. package/dist/templates/configs/horizon.js +30 -0
  62. package/dist/templates/configs/horizon.js.map +1 -0
  63. package/dist/templates/configs/index.d.ts +3 -0
  64. package/dist/templates/configs/index.d.ts.map +1 -0
  65. package/dist/templates/configs/index.js +92 -0
  66. package/dist/templates/configs/index.js.map +1 -0
  67. package/dist/templates/configs/localization.d.ts +2 -0
  68. package/dist/templates/configs/localization.d.ts.map +1 -0
  69. package/dist/templates/configs/localization.js +13 -0
  70. package/dist/templates/configs/localization.js.map +1 -0
  71. package/dist/templates/configs/log.d.ts +2 -0
  72. package/dist/templates/configs/log.d.ts.map +1 -0
  73. package/dist/templates/configs/log.js +40 -0
  74. package/dist/templates/configs/log.js.map +1 -0
  75. package/dist/templates/configs/mail.d.ts +2 -0
  76. package/dist/templates/configs/mail.d.ts.map +1 -0
  77. package/dist/templates/configs/mail.js +33 -0
  78. package/dist/templates/configs/mail.js.map +1 -0
  79. package/dist/templates/configs/passport.d.ts +2 -0
  80. package/dist/templates/configs/passport.d.ts.map +1 -0
  81. package/dist/templates/configs/passport.js +22 -0
  82. package/dist/templates/configs/passport.js.map +1 -0
  83. package/dist/templates/configs/pennant.d.ts +2 -0
  84. package/dist/templates/configs/pennant.d.ts.map +1 -0
  85. package/dist/templates/configs/pennant.js +16 -0
  86. package/dist/templates/configs/pennant.js.map +1 -0
  87. package/dist/templates/configs/pulse.d.ts +2 -0
  88. package/dist/templates/configs/pulse.d.ts.map +1 -0
  89. package/dist/templates/configs/pulse.js +21 -0
  90. package/dist/templates/configs/pulse.js.map +1 -0
  91. package/dist/templates/configs/queue.d.ts +2 -0
  92. package/dist/templates/configs/queue.d.ts.map +1 -0
  93. package/dist/templates/configs/queue.js +28 -0
  94. package/dist/templates/configs/queue.js.map +1 -0
  95. package/dist/templates/configs/sanctum.d.ts +2 -0
  96. package/dist/templates/configs/sanctum.d.ts.map +1 -0
  97. package/dist/templates/configs/sanctum.js +19 -0
  98. package/dist/templates/configs/sanctum.js.map +1 -0
  99. package/dist/templates/configs/server.d.ts +2 -0
  100. package/dist/templates/configs/server.d.ts.map +1 -0
  101. package/dist/templates/configs/server.js +15 -0
  102. package/dist/templates/configs/server.js.map +1 -0
  103. package/dist/templates/configs/session.d.ts +2 -0
  104. package/dist/templates/configs/session.d.ts.map +1 -0
  105. package/dist/templates/configs/session.js +26 -0
  106. package/dist/templates/configs/session.js.map +1 -0
  107. package/dist/templates/configs/socialite.d.ts +2 -0
  108. package/dist/templates/configs/socialite.d.ts.map +1 -0
  109. package/dist/templates/configs/socialite.js +27 -0
  110. package/dist/templates/configs/socialite.js.map +1 -0
  111. package/dist/templates/configs/storage.d.ts +2 -0
  112. package/dist/templates/configs/storage.d.ts.map +1 -0
  113. package/dist/templates/configs/storage.js +35 -0
  114. package/dist/templates/configs/storage.js.map +1 -0
  115. package/dist/templates/configs/sync.d.ts +3 -0
  116. package/dist/templates/configs/sync.d.ts.map +1 -0
  117. package/dist/templates/configs/sync.js +17 -0
  118. package/dist/templates/configs/sync.js.map +1 -0
  119. package/dist/templates/configs/telescope.d.ts +2 -0
  120. package/dist/templates/configs/telescope.d.ts.map +1 -0
  121. package/dist/templates/configs/telescope.js +25 -0
  122. package/dist/templates/configs/telescope.js.map +1 -0
  123. package/dist/templates/css/index.d.ts +3 -0
  124. package/dist/templates/css/index.d.ts.map +1 -0
  125. package/dist/templates/css/index.js +140 -0
  126. package/dist/templates/css/index.js.map +1 -0
  127. package/dist/templates/css/plain.d.ts +2 -0
  128. package/dist/templates/css/plain.d.ts.map +1 -0
  129. package/dist/templates/css/plain.js +373 -0
  130. package/dist/templates/css/plain.js.map +1 -0
  131. package/dist/templates/css/tailwind.d.ts +2 -0
  132. package/dist/templates/css/tailwind.d.ts.map +1 -0
  133. package/dist/templates/css/tailwind.js +176 -0
  134. package/dist/templates/css/tailwind.js.map +1 -0
  135. package/dist/templates/demos/avatar.d.ts +3 -0
  136. package/dist/templates/demos/avatar.d.ts.map +1 -0
  137. package/dist/templates/demos/avatar.js +182 -0
  138. package/dist/templates/demos/avatar.js.map +1 -0
  139. package/dist/templates/demos/cache.d.ts +3 -0
  140. package/dist/templates/demos/cache.d.ts.map +1 -0
  141. package/dist/templates/demos/cache.js +99 -0
  142. package/dist/templates/demos/cache.js.map +1 -0
  143. package/dist/templates/demos/contact.d.ts +3 -0
  144. package/dist/templates/demos/contact.d.ts.map +1 -0
  145. package/dist/templates/demos/contact.js +106 -0
  146. package/dist/templates/demos/contact.js.map +1 -0
  147. package/dist/templates/demos/fibonacci.d.ts +7 -0
  148. package/dist/templates/demos/fibonacci.d.ts.map +1 -0
  149. package/dist/templates/demos/fibonacci.js +172 -0
  150. package/dist/templates/demos/fibonacci.js.map +1 -0
  151. package/dist/templates/demos/http.d.ts +3 -0
  152. package/dist/templates/demos/http.d.ts.map +1 -0
  153. package/dist/templates/demos/http.js +117 -0
  154. package/dist/templates/demos/http.js.map +1 -0
  155. package/dist/templates/demos/index-view.d.ts +3 -0
  156. package/dist/templates/demos/index-view.d.ts.map +1 -0
  157. package/dist/templates/demos/index-view.js +144 -0
  158. package/dist/templates/demos/index-view.js.map +1 -0
  159. package/dist/templates/demos/localization.d.ts +4 -0
  160. package/dist/templates/demos/localization.d.ts.map +1 -0
  161. package/dist/templates/demos/localization.js +130 -0
  162. package/dist/templates/demos/localization.js.map +1 -0
  163. package/dist/templates/demos/mail.d.ts +4 -0
  164. package/dist/templates/demos/mail.d.ts.map +1 -0
  165. package/dist/templates/demos/mail.js +127 -0
  166. package/dist/templates/demos/mail.js.map +1 -0
  167. package/dist/templates/demos/notifications.d.ts +4 -0
  168. package/dist/templates/demos/notifications.d.ts.map +1 -0
  169. package/dist/templates/demos/notifications.js +133 -0
  170. package/dist/templates/demos/notifications.js.map +1 -0
  171. package/dist/templates/demos/pennant.d.ts +8 -0
  172. package/dist/templates/demos/pennant.d.ts.map +1 -0
  173. package/dist/templates/demos/pennant.js +138 -0
  174. package/dist/templates/demos/pennant.js.map +1 -0
  175. package/dist/templates/demos/queue.d.ts +4 -0
  176. package/dist/templates/demos/queue.d.ts.map +1 -0
  177. package/dist/templates/demos/queue.js +107 -0
  178. package/dist/templates/demos/queue.js.map +1 -0
  179. package/dist/templates/demos/registry.d.ts +13 -0
  180. package/dist/templates/demos/registry.d.ts.map +1 -0
  181. package/dist/templates/demos/registry.js +26 -0
  182. package/dist/templates/demos/registry.js.map +1 -0
  183. package/dist/templates/demos/rudder-socket.d.ts +2 -0
  184. package/dist/templates/demos/rudder-socket.d.ts.map +1 -0
  185. package/dist/templates/demos/rudder-socket.js +95 -0
  186. package/dist/templates/demos/rudder-socket.js.map +1 -0
  187. package/dist/templates/demos/sync.d.ts +2 -0
  188. package/dist/templates/demos/sync.d.ts.map +1 -0
  189. package/dist/templates/demos/sync.js +97 -0
  190. package/dist/templates/demos/sync.js.map +1 -0
  191. package/dist/templates/demos/system-info.d.ts +3 -0
  192. package/dist/templates/demos/system-info.d.ts.map +1 -0
  193. package/dist/templates/demos/system-info.js +142 -0
  194. package/dist/templates/demos/system-info.js.map +1 -0
  195. package/dist/templates/demos/todos.d.ts +6 -0
  196. package/dist/templates/demos/todos.d.ts.map +1 -0
  197. package/dist/templates/demos/todos.js +246 -0
  198. package/dist/templates/demos/todos.js.map +1 -0
  199. package/dist/templates/demos/ws.d.ts +2 -0
  200. package/dist/templates/demos/ws.d.ts.map +1 -0
  201. package/dist/templates/demos/ws.js +106 -0
  202. package/dist/templates/demos/ws.js.map +1 -0
  203. package/dist/templates/env.d.ts +7 -0
  204. package/dist/templates/env.d.ts.map +1 -0
  205. package/dist/templates/env.js +113 -0
  206. package/dist/templates/env.js.map +1 -0
  207. package/dist/templates/package-json.d.ts +3 -0
  208. package/dist/templates/package-json.d.ts.map +1 -0
  209. package/dist/templates/package-json.js +193 -0
  210. package/dist/templates/package-json.js.map +1 -0
  211. package/dist/templates/package-managers.d.ts +14 -0
  212. package/dist/templates/package-managers.d.ts.map +1 -0
  213. package/dist/templates/package-managers.js +49 -0
  214. package/dist/templates/package-managers.js.map +1 -0
  215. package/dist/templates/pages/ai-chat.d.ts +7 -0
  216. package/dist/templates/pages/ai-chat.d.ts.map +1 -0
  217. package/dist/templates/pages/ai-chat.js +285 -0
  218. package/dist/templates/pages/ai-chat.js.map +1 -0
  219. package/dist/templates/pages/demo.d.ts +4 -0
  220. package/dist/templates/pages/demo.d.ts.map +1 -0
  221. package/dist/templates/pages/demo.js +71 -0
  222. package/dist/templates/pages/demo.js.map +1 -0
  223. package/dist/templates/pages/error.d.ts +7 -0
  224. package/dist/templates/pages/error.d.ts.map +1 -0
  225. package/dist/templates/pages/error.js +148 -0
  226. package/dist/templates/pages/error.js.map +1 -0
  227. package/dist/templates/pages/index.d.ts +9 -0
  228. package/dist/templates/pages/index.d.ts.map +1 -0
  229. package/dist/templates/pages/index.js +311 -0
  230. package/dist/templates/pages/index.js.map +1 -0
  231. package/dist/templates/prisma/auth.d.ts +2 -0
  232. package/dist/templates/prisma/auth.d.ts.map +1 -0
  233. package/dist/templates/prisma/auth.js +22 -0
  234. package/dist/templates/prisma/auth.js.map +1 -0
  235. package/dist/templates/prisma/base.d.ts +3 -0
  236. package/dist/templates/prisma/base.d.ts.map +1 -0
  237. package/dist/templates/prisma/base.js +14 -0
  238. package/dist/templates/prisma/base.js.map +1 -0
  239. package/dist/templates/prisma/config.d.ts +3 -0
  240. package/dist/templates/prisma/config.d.ts.map +1 -0
  241. package/dist/templates/prisma/config.js +15 -0
  242. package/dist/templates/prisma/config.js.map +1 -0
  243. package/dist/templates/prisma/notification.d.ts +2 -0
  244. package/dist/templates/prisma/notification.d.ts.map +1 -0
  245. package/dist/templates/prisma/notification.js +16 -0
  246. package/dist/templates/prisma/notification.js.map +1 -0
  247. package/dist/templates/prisma/passport.d.ts +2 -0
  248. package/dist/templates/prisma/passport.d.ts.map +1 -0
  249. package/dist/templates/prisma/passport.js +69 -0
  250. package/dist/templates/prisma/passport.js.map +1 -0
  251. package/dist/templates/routes/api.d.ts +3 -0
  252. package/dist/templates/routes/api.d.ts.map +1 -0
  253. package/dist/templates/routes/api.js +166 -0
  254. package/dist/templates/routes/api.js.map +1 -0
  255. package/dist/templates/routes/console.d.ts +2 -0
  256. package/dist/templates/routes/console.d.ts.map +1 -0
  257. package/dist/templates/routes/console.js +22 -0
  258. package/dist/templates/routes/console.js.map +1 -0
  259. package/dist/templates/routes/web.d.ts +4 -0
  260. package/dist/templates/routes/web.d.ts.map +1 -0
  261. package/dist/templates/routes/web.js +155 -0
  262. package/dist/templates/routes/web.js.map +1 -0
  263. package/dist/templates/server.d.ts +2 -0
  264. package/dist/templates/server.d.ts.map +1 -0
  265. package/dist/templates/server.js +10 -0
  266. package/dist/templates/server.js.map +1 -0
  267. package/dist/templates/tsconfig.d.ts +3 -0
  268. package/dist/templates/tsconfig.d.ts.map +1 -0
  269. package/dist/templates/tsconfig.js +33 -0
  270. package/dist/templates/tsconfig.js.map +1 -0
  271. package/dist/templates/views/welcome.d.ts +6 -0
  272. package/dist/templates/views/welcome.d.ts.map +1 -0
  273. package/dist/templates/views/welcome.js +396 -0
  274. package/dist/templates/views/welcome.js.map +1 -0
  275. package/dist/templates/vite.d.ts +3 -0
  276. package/dist/templates/vite.d.ts.map +1 -0
  277. package/dist/templates/vite.js +61 -0
  278. package/dist/templates/vite.js.map +1 -0
  279. package/dist/templates.d.ts +27 -17
  280. package/dist/templates.d.ts.map +1 -1
  281. package/dist/templates.js +158 -3778
  282. package/dist/templates.js.map +1 -1
  283. package/package.json +2 -2
@@ -0,0 +1,117 @@
1
+ // HTTP client demo — fluent fetch with retry + timeout against a public API.
2
+ export function demosHttpView() {
3
+ return `import { useState } from 'react'
4
+ import '@/index.css'
5
+
6
+ interface HttpResponseShape {
7
+ status: number
8
+ ok: boolean
9
+ durationMs: number
10
+ url: string
11
+ body: unknown
12
+ }
13
+
14
+ const ENDPOINTS = [
15
+ { url: 'https://jsonplaceholder.typicode.com/todos/1', label: 'Todo (works)' },
16
+ { url: 'https://jsonplaceholder.typicode.com/users/1', label: 'User (works)' },
17
+ { url: 'https://httpstat.us/500?sleep=300', label: 'Force 500 (retries 3×)' },
18
+ ]
19
+
20
+ export default function HttpDemo() {
21
+ const [url, setUrl] = useState(ENDPOINTS[0]!.url)
22
+ const [data, setData] = useState<HttpResponseShape | null>(null)
23
+ const [loading, setLoading] = useState(false)
24
+ const [error, setError] = useState<string | null>(null)
25
+
26
+ async function fetchUrl() {
27
+ setLoading(true); setError(null)
28
+ try {
29
+ const res = await fetch('/api/http/fetch?url=' + encodeURIComponent(url))
30
+ const body = await res.json() as HttpResponseShape | { message: string }
31
+ if (!res.ok) throw new Error((body as { message: string }).message ?? 'Failed')
32
+ setData(body as HttpResponseShape)
33
+ } catch (e) {
34
+ setError((e as Error).message)
35
+ } finally {
36
+ setLoading(false)
37
+ }
38
+ }
39
+
40
+ return (
41
+ <div className="page">
42
+ <nav className="page-nav">
43
+ <div className="brand">
44
+ <span className="brand-dot" />
45
+ RudderJS
46
+ </div>
47
+ <div className="nav-right">
48
+ <a href="/demos" className="nav-link">Demos</a>
49
+ <a href="/" className="nav-link">Home</a>
50
+ </div>
51
+ </nav>
52
+
53
+ <section className="hero">
54
+ <h1 className="hero-title">HTTP client</h1>
55
+ <p className="hero-lead">
56
+ Server-side <code className="inline-code">Http.retry(3, 200).timeout(5000).get(url)</code>{' '}
57
+ against a public API. Pick a URL — the 500 endpoint exercises the retry path.
58
+ </p>
59
+ </section>
60
+
61
+ <section className="feature-section" style={{ maxWidth: '40rem', margin: '0 auto' }}>
62
+ <div className="form-card">
63
+ <label className="form-label" htmlFor="http-url">URL</label>
64
+ <select id="http-url" className="form-input" value={url} onChange={e => setUrl(e.target.value)} style={{ marginBottom: '0.75rem' }}>
65
+ {ENDPOINTS.map(e => (
66
+ <option key={e.url} value={e.url}>{e.label}</option>
67
+ ))}
68
+ </select>
69
+ <button className="form-submit" onClick={fetchUrl} disabled={loading}>
70
+ {loading ? 'Fetching…' : 'Fetch'}
71
+ </button>
72
+ {error && (
73
+ <p className="form-error" style={{ marginTop: '1rem' }}>{error}</p>
74
+ )}
75
+ {data && (
76
+ <div style={{ marginTop: '1rem' }}>
77
+ <p className="feature-desc">
78
+ <strong>{data.status}</strong> · {data.durationMs}ms · ok={String(data.ok)}
79
+ </p>
80
+ <pre style={{ marginTop: '0.5rem', padding: '0.75rem', borderRadius: '0.375rem', background: 'var(--muted, #f4f4f5)', fontSize: '0.7rem', whiteSpace: 'pre-wrap', wordBreak: 'break-all' }}>
81
+ {JSON.stringify(data.body, null, 2).slice(0, 600)}
82
+ </pre>
83
+ </div>
84
+ )}
85
+ </div>
86
+ </section>
87
+ </div>
88
+ )
89
+ }
90
+ `;
91
+ }
92
+ export function demosHttpApiBlock() {
93
+ return `// GET /api/http/fetch?url=… — server-side HTTP with retry + timeout.
94
+ router.get('/api/http/fetch', async (req, res) => {
95
+ const url = (req.query as Record<string, string>)['url']
96
+ if (!url) return res.status(422).json({ message: 'url is required' })
97
+ if (!/^https?:\\/\\//.test(url)) return res.status(422).json({ message: 'url must be http(s)' })
98
+
99
+ const { Http } = await import('@rudderjs/http')
100
+ const t0 = Date.now()
101
+ try {
102
+ const response = await Http.retry(3, 200).timeout(5000).get(url)
103
+ let body: unknown = null
104
+ try { body = response.json() } catch { body = response.body.slice(0, 600) }
105
+ res.json({
106
+ status: response.status,
107
+ ok: response.ok(),
108
+ durationMs: Date.now() - t0,
109
+ url,
110
+ body,
111
+ })
112
+ } catch (e) {
113
+ res.status(502).json({ message: (e as Error).message ?? 'Request failed', durationMs: Date.now() - t0, url })
114
+ }
115
+ })`;
116
+ }
117
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/templates/demos/http.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;GAsBN,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type TemplateContext } from '../../templates.js';
2
+ export declare function demosIndexView(ctx: TemplateContext): string;
3
+ //# sourceMappingURL=index-view.d.ts.map
@@ -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,CA+I3D"}
@@ -0,0 +1,144 @@
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: 'Todos',
13
+ desc: 'ORM + interactive UI. Controller loads initial data, the view hydrates and POSTs to /api/todos/* for live updates.',
14
+ href: '/demos/todos',
15
+ pkgs: '@rudderjs/orm · @rudderjs/router',
16
+ show: shouldScaffoldDemo(ctx, 'todos'),
17
+ },
18
+ {
19
+ title: 'Avatar resize',
20
+ desc: 'Upload an image — server resizes it to 256×256 WebP via @rudderjs/image and saves to public storage. Side-by-side compare.',
21
+ href: '/demos/avatar',
22
+ pkgs: '@rudderjs/image · @rudderjs/storage',
23
+ show: shouldScaffoldDemo(ctx, 'avatar'),
24
+ },
25
+ {
26
+ title: 'System info',
27
+ desc: 'Three shell commands (git, node, uptime) executed via @rudderjs/process. Compares sequential vs parallel cost using Process.pool().',
28
+ href: '/demos/system-info',
29
+ pkgs: '@rudderjs/process',
30
+ show: shouldScaffoldDemo(ctx, 'system-info'),
31
+ },
32
+ {
33
+ title: 'Worker threads',
34
+ desc: 'Compute fib(n) sequentially on the main thread vs across @rudderjs/concurrency worker pool. Watch the parallel cost stay flat as you crank N.',
35
+ href: '/demos/fibonacci',
36
+ pkgs: '@rudderjs/concurrency',
37
+ show: shouldScaffoldDemo(ctx, 'fibonacci'),
38
+ },
39
+ {
40
+ title: 'Feature flags',
41
+ desc: 'Boolean, value, scoped, and Lottery features resolved against the current user. Sub-route guarded by FeatureMiddleware to demonstrate 403 blocking.',
42
+ href: '/demos/pennant',
43
+ pkgs: '@rudderjs/pennant',
44
+ show: shouldScaffoldDemo(ctx, 'pennant'),
45
+ },
46
+ {
47
+ title: 'Cache counter',
48
+ desc: 'Persistent view counter via Cache.get + Cache.set. Demonstrates the Cache facade with the in-memory driver.',
49
+ href: '/demos/cache',
50
+ pkgs: '@rudderjs/cache',
51
+ show: shouldScaffoldDemo(ctx, 'cache'),
52
+ },
53
+ {
54
+ title: 'Queue dispatch',
55
+ desc: 'Click to enqueue ExampleJob via @rudderjs/queue. The handler logs to the server terminal.',
56
+ href: '/demos/queue',
57
+ pkgs: '@rudderjs/queue',
58
+ show: shouldScaffoldDemo(ctx, 'queue'),
59
+ },
60
+ {
61
+ title: 'Mail send',
62
+ desc: 'Send a Mailable via Mail.to(...).send(). Default driver is "log" — output appears in the dev terminal.',
63
+ href: '/demos/mail',
64
+ pkgs: '@rudderjs/mail',
65
+ show: shouldScaffoldDemo(ctx, 'mail'),
66
+ },
67
+ {
68
+ title: 'Notifications',
69
+ desc: 'Multi-channel notification via notify(notifiable, notification). Mail channel uses the log driver.',
70
+ href: '/demos/notifications',
71
+ pkgs: '@rudderjs/notification · @rudderjs/mail',
72
+ show: shouldScaffoldDemo(ctx, 'notifications'),
73
+ },
74
+ {
75
+ title: 'Localization',
76
+ desc: 'Pick a locale to fetch the same keys via trans() server-side. Strings live in lang/<locale>/messages.json.',
77
+ href: '/demos/localization',
78
+ pkgs: '@rudderjs/localization',
79
+ show: shouldScaffoldDemo(ctx, 'localization'),
80
+ },
81
+ {
82
+ title: 'HTTP client',
83
+ desc: 'Server-side Http.retry(3, 200).timeout(5000).get(url) against a public API. The 500 endpoint exercises retry.',
84
+ href: '/demos/http',
85
+ pkgs: '@rudderjs/http',
86
+ show: shouldScaffoldDemo(ctx, 'http'),
87
+ },
88
+ {
89
+ title: 'WebSocket chat',
90
+ desc: 'Real-time chat + presence using @rudderjs/broadcast — multi-channel pub/sub over a single WebSocket connection.',
91
+ href: '/demos/ws',
92
+ pkgs: '@rudderjs/broadcast',
93
+ show: shouldScaffoldDemo(ctx, 'ws'),
94
+ },
95
+ {
96
+ title: 'Collaborative editor',
97
+ desc: 'Yjs CRDT live document with awareness cursors. Open in two tabs to see real-time sync over @rudderjs/sync.',
98
+ href: '/demos/sync',
99
+ pkgs: '@rudderjs/sync',
100
+ show: shouldScaffoldDemo(ctx, 'sync'),
101
+ },
102
+ ].filter(c => c.show);
103
+ const cardsJsx = cards.map(c => ` <a key="${c.href}" href="${c.href}" className="feature-card">
104
+ <h3 className="feature-title">${c.title}</h3>
105
+ <p className="feature-desc">${c.desc}</p>
106
+ <p className="feature-desc" style={{ fontSize: '0.7rem', opacity: 0.7 }}>${c.pkgs}</p>
107
+ </a>`).join('\n');
108
+ return `import '@/index.css'
109
+
110
+ // Override the id-derived URL ('/demos/index') so SPA nav matches the controller ('/demos').
111
+ export const route = '/demos'
112
+
113
+ export default function DemosIndex() {
114
+ return (
115
+ <div className="page">
116
+ <nav className="page-nav">
117
+ <div className="brand">
118
+ <span className="brand-dot" />
119
+ RudderJS
120
+ </div>
121
+ <div className="nav-right">
122
+ <a href="/" className="nav-link">Home</a>
123
+ </div>
124
+ </nav>
125
+
126
+ <section className="hero">
127
+ <h1 className="hero-title">Demos</h1>
128
+ <p className="hero-lead">
129
+ Small, focused examples of what the framework can do. Each one is a single
130
+ controller returning <code className="inline-code">view('demos.&lt;name&gt;')</code>.
131
+ </p>
132
+ </section>
133
+
134
+ <section className="feature-section">
135
+ <div className="feature-grid">
136
+ ${cardsJsx}
137
+ </div>
138
+ </section>
139
+ </div>
140
+ )
141
+ }
142
+ `;
143
+ }
144
+ //# 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":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function demosLocalizationView(): string;
2
+ export declare function demosLocalizationApiBlock(): string;
3
+ export declare function langMessages(locale: 'en' | 'es' | 'ar'): string;
4
+ //# sourceMappingURL=localization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/localization.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,IAAI,MAAM,CAkF9C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAkBlD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAuB/D"}
@@ -0,0 +1,130 @@
1
+ // Localization demo — language switcher hits /api/i18n?locale=…
2
+ // The route uses runWithLocale + setLocale + trans() to render strings.
3
+ // Lang files at lang/<locale>/messages.json.
4
+ export function demosLocalizationView() {
5
+ return `import { useEffect, useState } from 'react'
6
+ import '@/index.css'
7
+
8
+ interface I18nResponse {
9
+ locale: string
10
+ greeting: string
11
+ items: string
12
+ welcome: string
13
+ }
14
+
15
+ const LOCALES = [
16
+ { code: 'en', label: 'English' },
17
+ { code: 'es', label: 'Español' },
18
+ { code: 'ar', label: 'العربية' },
19
+ ]
20
+
21
+ export default function LocalizationDemo() {
22
+ const [locale, setLocale] = useState('en')
23
+ const [data, setData] = useState<I18nResponse | null>(null)
24
+
25
+ async function load(loc: string) {
26
+ const res = await fetch(\`/api/i18n?locale=\${loc}\`)
27
+ setData(await res.json() as I18nResponse)
28
+ }
29
+
30
+ useEffect(() => { load(locale) }, [locale])
31
+
32
+ return (
33
+ <div className="page">
34
+ <nav className="page-nav">
35
+ <div className="brand">
36
+ <span className="brand-dot" />
37
+ RudderJS
38
+ </div>
39
+ <div className="nav-right">
40
+ <a href="/demos" className="nav-link">Demos</a>
41
+ <a href="/" className="nav-link">Home</a>
42
+ </div>
43
+ </nav>
44
+
45
+ <section className="hero">
46
+ <h1 className="hero-title">Localization</h1>
47
+ <p className="hero-lead">
48
+ Pick a locale to fetch the same keys via{' '}
49
+ <code className="inline-code">trans()</code> on the server. Strings live in{' '}
50
+ <code className="inline-code">lang/&lt;locale&gt;/messages.json</code>.
51
+ </p>
52
+ </section>
53
+
54
+ <section className="feature-section" style={{ maxWidth: '32rem', margin: '0 auto' }}>
55
+ <div className="form-card">
56
+ <div style={{ marginBottom: '1rem' }}>
57
+ <label className="form-label" htmlFor="locale">Locale</label>
58
+ <select
59
+ id="locale"
60
+ className="form-input"
61
+ value={locale}
62
+ onChange={e => setLocale(e.target.value)}
63
+ >
64
+ {LOCALES.map(l => (
65
+ <option key={l.code} value={l.code}>{l.label} ({l.code})</option>
66
+ ))}
67
+ </select>
68
+ </div>
69
+
70
+ {data && (
71
+ <div style={{ display: 'grid', gap: '0.5rem' }}>
72
+ <p className="feature-desc"><strong>welcome:</strong> {data.welcome}</p>
73
+ <p className="feature-desc"><strong>greeting:</strong> {data.greeting}</p>
74
+ <p className="feature-desc"><strong>items (3):</strong> {data.items}</p>
75
+ <p className="feature-desc" style={{ fontSize: '0.7rem', opacity: 0.7 }}>
76
+ resolved server-side with locale = <code>{data.locale}</code>
77
+ </p>
78
+ </div>
79
+ )}
80
+ </div>
81
+ </section>
82
+ </div>
83
+ )
84
+ }
85
+ `;
86
+ }
87
+ export function demosLocalizationApiBlock() {
88
+ return `// GET /api/i18n?locale=… — resolves the same keys in the requested locale.
89
+ router.get('/api/i18n', async (req, res) => {
90
+ const { runWithLocale, setLocale, getLocale, trans } = await import('@rudderjs/localization')
91
+ const requested = (req.query as Record<string, string>)['locale'] ?? 'en'
92
+
93
+ const payload = await runWithLocale(requested, async () => {
94
+ setLocale(requested)
95
+ return {
96
+ locale: getLocale(),
97
+ welcome: await trans('messages.welcome'),
98
+ greeting: await trans('messages.greeting', { name: 'World' }),
99
+ items: await trans('messages.items', 3),
100
+ }
101
+ })
102
+
103
+ res.json(payload)
104
+ })`;
105
+ }
106
+ export function langMessages(locale) {
107
+ if (locale === 'es') {
108
+ return `{
109
+ "welcome": "¡Bienvenido a RudderJS!",
110
+ "greeting": "Hola, :name!",
111
+ "items": "{0} sin elementos|{1} un elemento|{n} :count elementos"
112
+ }
113
+ `;
114
+ }
115
+ if (locale === 'ar') {
116
+ return `{
117
+ "welcome": "مرحباً بك في RudderJS!",
118
+ "greeting": "مرحباً، :name!",
119
+ "items": "{0} لا توجد عناصر|{1} عنصر واحد|{n} :count عناصر"
120
+ }
121
+ `;
122
+ }
123
+ return `{
124
+ "welcome": "Welcome to RudderJS!",
125
+ "greeting": "Hello, :name!",
126
+ "items": "{0} no items|{1} one item|{n} :count items"
127
+ }
128
+ `;
129
+ }
130
+ //# sourceMappingURL=localization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localization.js","sourceRoot":"","sources":["../../../src/templates/demos/localization.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,wEAAwE;AACxE,6CAA6C;AAE7C,MAAM,UAAU,qBAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgFR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;;;;GAgBN,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO;;;;;CAKV,CAAA;IACC,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO;;;;;CAKV,CAAA;IACC,CAAC;IACD,OAAO;;;;;CAKR,CAAA;AACD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function demosMailView(): string;
2
+ export declare function demoMailable(): string;
3
+ export declare function demosMailApiBlock(): string;
4
+ //# sourceMappingURL=mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/mail.ts"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,IAAI,MAAM,CAqFtC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAkBrC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAkB1C"}
@@ -0,0 +1,127 @@
1
+ // Mail send demo — defines a Mailable and posts to /api/mail/send.
2
+ // Default driver is `log`, so the email lands in the dev terminal.
3
+ export function demosMailView() {
4
+ return `import { useState } from 'react'
5
+ import '@/index.css'
6
+
7
+ interface MailResponse {
8
+ ok: boolean
9
+ to: string
10
+ subject: string
11
+ driver: string
12
+ }
13
+
14
+ export default function MailDemo() {
15
+ const [to, setTo] = useState('user@example.com')
16
+ const [subject, setSubject] = useState('Hello from RudderJS')
17
+ const [data, setData] = useState<MailResponse | null>(null)
18
+ const [loading, setLoading] = useState(false)
19
+ const [error, setError] = useState<string | null>(null)
20
+
21
+ async function send() {
22
+ setLoading(true); setError(null)
23
+ try {
24
+ const res = await fetch('/api/mail/send', {
25
+ method: 'POST',
26
+ headers: { 'Content-Type': 'application/json' },
27
+ body: JSON.stringify({ to, subject }),
28
+ })
29
+ const body = await res.json() as MailResponse | { message: string }
30
+ if (!res.ok) throw new Error((body as { message: string }).message ?? 'Send failed')
31
+ setData(body as MailResponse)
32
+ } catch (e) {
33
+ setError((e as Error).message)
34
+ } finally {
35
+ setLoading(false)
36
+ }
37
+ }
38
+
39
+ return (
40
+ <div className="page">
41
+ <nav className="page-nav">
42
+ <div className="brand">
43
+ <span className="brand-dot" />
44
+ RudderJS
45
+ </div>
46
+ <div className="nav-right">
47
+ <a href="/demos" className="nav-link">Demos</a>
48
+ <a href="/" className="nav-link">Home</a>
49
+ </div>
50
+ </nav>
51
+
52
+ <section className="hero">
53
+ <h1 className="hero-title">Mail send</h1>
54
+ <p className="hero-lead">
55
+ Sends a <code className="inline-code">DemoMail</code> via{' '}
56
+ <code className="inline-code">@rudderjs/mail</code>. Default driver is{' '}
57
+ <code className="inline-code">log</code> — check the dev server terminal for output.
58
+ </p>
59
+ </section>
60
+
61
+ <section className="feature-section" style={{ maxWidth: '32rem', margin: '0 auto' }}>
62
+ <div className="form-card">
63
+ <div style={{ marginBottom: '1rem' }}>
64
+ <label className="form-label" htmlFor="mail-to">To</label>
65
+ <input id="mail-to" className="form-input" value={to} onChange={e => setTo(e.target.value)} />
66
+ </div>
67
+ <div style={{ marginBottom: '1rem' }}>
68
+ <label className="form-label" htmlFor="mail-subject">Subject</label>
69
+ <input id="mail-subject" className="form-input" value={subject} onChange={e => setSubject(e.target.value)} />
70
+ </div>
71
+ <button className="form-submit" onClick={send} disabled={loading}>
72
+ {loading ? 'Sending…' : 'Send mail'}
73
+ </button>
74
+ {error && (
75
+ <p className="form-error" style={{ marginTop: '1rem' }}>{error}</p>
76
+ )}
77
+ {data && (
78
+ <p className="form-success" style={{ marginTop: '1rem' }}>
79
+ Sent to <code>{data.to}</code> via <code>{data.driver}</code> driver — check the terminal.
80
+ </p>
81
+ )}
82
+ </div>
83
+ </section>
84
+ </div>
85
+ )
86
+ }
87
+ `;
88
+ }
89
+ export function demoMailable() {
90
+ return `import { Mailable } from '@rudderjs/mail'
91
+
92
+ /**
93
+ * Demo mailable — built dynamically from the to/subject the user enters.
94
+ * Replace with whatever copy your real templates need (HTML + text).
95
+ */
96
+ export class DemoMail extends Mailable {
97
+ constructor(private readonly heading: string) { super() }
98
+
99
+ build(): this {
100
+ return this
101
+ .subject(this.heading)
102
+ .html(\`<h1>\${this.heading}</h1><p>Sent from the RudderJS mail demo.</p>\`)
103
+ .text(\`\${this.heading}\\n\\nSent from the RudderJS mail demo.\`)
104
+ }
105
+ }
106
+ `;
107
+ }
108
+ export function demosMailApiBlock() {
109
+ return `// POST /api/mail/send — sends a DemoMail to the user-supplied address.
110
+ router.post('/api/mail/send', async (req, res) => {
111
+ const body = (req.body ?? {}) as { to?: string; subject?: string }
112
+ if (!body.to || !body.subject) {
113
+ return res.status(422).json({ message: 'Body must be { to, subject }' })
114
+ }
115
+ const { Mail } = await import('@rudderjs/mail')
116
+ const { DemoMail } = await import('../app/Mail/DemoMail.ts')
117
+ const { config } = await import('@rudderjs/core')
118
+ await Mail.to(body.to).send(new DemoMail(body.subject))
119
+ res.json({
120
+ ok: true,
121
+ to: body.to,
122
+ subject: body.subject,
123
+ driver: config<string>('mail.default', 'log'),
124
+ })
125
+ })`;
126
+ }
127
+ //# sourceMappingURL=mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.js","sourceRoot":"","sources":["../../../src/templates/demos/mail.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,mEAAmE;AAEnE,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO;;;;;;;;;;;;;;;;CAgBR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;GAgBN,CAAA;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function demosNotificationsView(): string;
2
+ export declare function demoNotification(): string;
3
+ export declare function demosNotificationsApiBlock(): string;
4
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/notifications.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,IAAI,MAAM,CAgF/C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAiCzC;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAcnD"}