create-rudder-app 0.5.0 → 0.6.1

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-rudder-app
2
2
 
3
- **Spin up a production-ready [RudderJS](https://github.com/rudderjs/rudder) app in under 60 seconds** — with auth that works, a database wired, SSR views rendering, and optional AI / OAuth / real-time / cache / queue, all bootstrapped through Vite + Vike.
3
+ **Spin up a production-ready [RudderJS](https://github.com/rudderjs/rudder) app in under 60 seconds** — with auth that works, a database wired, SSR views rendering, and your pick from 25 opt-in packages, all bootstrapped through Vite + Vike.
4
4
 
5
5
  ```bash
6
6
  pnpm create rudder-app my-app
@@ -29,15 +29,16 @@ Skip `[name]` to be prompted for one.
29
29
 
30
30
  ## What you get out of the box
31
31
 
32
- With the **default choices** (Prisma + SQLite + Auth + Cache + React + Tailwind + shadcn/ui), you get a working fullstack app you can register into, log into, and sign out of — without writing any code:
32
+ With the **default choices** (Prisma + SQLite + Auth + React + Tailwind + shadcn/ui + Contact demo), you get a working fullstack app you can register into, log into, and sign out of — without writing any code:
33
33
 
34
34
  - **Welcome page at `/`** — controller-returned view, Tailwind + shadcn styled, with Log in / Register links or a signed-in user + Sign out button.
35
35
  - **Auth flow that works** — `/login`, `/register`, `/forgot-password`, `/reset-password` pages vendored into `app/Views/Auth/` (so you can customize them freely) and wired to `POST /api/auth/sign-in/email` / `sign-up/email` / `sign-out` / `request-password-reset` / `reset-password` endpoints.
36
36
  - **Database ready** — Prisma schema with a `User` + `PasswordResetToken` model, SQLite by default, a `User` ORM model.
37
- - **Session-based auth** — cookie sessions via `@rudderjs/session`, `AuthMiddleware` applied globally, ghost-user-safe (see the [Request Lifecycle guide](https://github.com/rudderjs/rudder/blob/main/docs/guide/lifecycle.md)).
38
- - **Rate limiting** — 10 req/min on auth endpoints out of the box.
37
+ - **Session-based auth** — cookie sessions via `@rudderjs/session`, `AuthMiddleware` applied to the `web` group, ghost-user-safe (see the [Request Lifecycle guide](https://github.com/rudderjs/rudder/blob/main/docs/guide/lifecycle.md)).
38
+ - **Rate limiting** — 60 req/min globally, 10 req/min on auth endpoints out of the box.
39
39
  - **Bootstrap you can read** — `bootstrap/app.ts` in 25 lines, `bootstrap/providers.ts` shows auto-discovery, `config/` has one file per concern.
40
40
  - **Rudder CLI** — `pnpm rudder --help` lists framework commands; `routes/console.ts` shows you how to add your own.
41
+ - **`/demos` index** — every demo you ticked appears as a card linking to its page; new demos picked up automatically from the shared registry.
41
42
 
42
43
  If you tick **AI** you get a `/ai-chat` demo. If you tick **MCP**, `POST /mcp/echo`. If you tick **Passport**, a full OAuth 2 server at `/oauth/authorize` / `/oauth/token`. Everything is opt-in and pay-as-you-go.
43
44
 
@@ -45,51 +46,104 @@ If you tick **AI** you get a `/ai-chat` demo. If you tick **MCP**, `POST /mcp/ec
45
46
 
46
47
  ## Prompts
47
48
 
48
- The installer walks you through up to 9 prompts (several are conditional):
49
+ The installer walks you through up to 10 prompts (several are conditional):
49
50
 
50
51
  | # | Prompt | Options | Default | Condition |
51
52
  |---|--------|---------|---------|-----------|
52
53
  | 1 | Project name | any string | — | always (skipped if passed as argv) |
53
54
  | 2 | Database ORM | Prisma · Drizzle · None | Prisma | always |
54
55
  | 3 | Database driver | SQLite · PostgreSQL · MySQL | SQLite | only if ORM selected |
55
- | 4 | Package checklist | multiselect (see below) | Auth + Cache | always |
56
+ | 4 | Packages | categorized multiselect (see below) | Authentication | always |
56
57
  | 5 | Frontend frameworks | React · Vue · Solid (multiselect) | React | always |
57
58
  | 6 | Primary framework | single select from chosen frameworks | — | only if >1 framework selected |
58
59
  | 7 | Add Tailwind CSS? | yes / no | yes | always |
59
60
  | 8 | Add shadcn/ui? | yes / no | yes | only if React + Tailwind |
60
- | 9 | Install dependencies? | yes / no | yes | always |
61
+ | 9 | Demos | multiselect filtered by previous picks | Contact form | only when at least one available |
62
+ | 10 | Install dependencies? | yes / no | yes | always |
61
63
 
62
- > **Not sure what to pick?** Accept every default — it produces the most-used stack (Prisma + SQLite + Auth + Cache + React + Tailwind + shadcn/ui) and is the best-tested path. You can always add packages later.
64
+ > **Not sure what to pick?** Accept every default — it produces the most-used stack (Prisma + SQLite + Auth + React + Tailwind + shadcn/ui + Contact demo) and is the best-tested path. You can always add packages later.
65
+
66
+ ### Tier A — silent install
67
+
68
+ `@rudderjs/session`, `@rudderjs/hash`, and `@rudderjs/cache` are installed unconditionally. They're required by the default bootstrap (rate-limit middleware needs cache; auth needs hash + session) so making them explicit-but-silent prevents broken projects when you don't tick Authentication.
63
69
 
64
70
  ### Package checklist (prompt 4)
65
71
 
66
- | Choice | Description | Package |
67
- |--------|-------------|---------|
68
- | Authentication | Login, register, sessions | `@rudderjs/auth` |
69
- | Cache | Memory + Redis drivers | `@rudderjs/cache` |
70
- | Queue | Background jobs | `@rudderjs/queue` |
71
- | Storage | File uploads (local + S3) | `@rudderjs/storage` |
72
- | Mail | SMTP + log driver | `@rudderjs/mail` |
73
- | Notifications | Multi-channel notifications | `@rudderjs/notification` |
74
- | Scheduler | Cron-like task scheduling | `@rudderjs/schedule` |
75
- | WebSocket | Real-time channels | `@rudderjs/broadcast` |
76
- | Sync (Yjs CRDT) | Real-time collaborative document sync | `@rudderjs/sync` |
77
- | AI | LLM providers (Anthropic, OpenAI, Google, Ollama, Groq, DeepSeek, xAI, Mistral, Azure) | `@rudderjs/ai` |
78
- | MCP | Model Context Protocol servers — expose tools/resources to LLMs | `@rudderjs/mcp` |
79
- | Passport (OAuth2) | OAuth 2 server with JWT — **requires Auth + Prisma** | `@rudderjs/passport` |
80
- | Localization | i18n — `trans()`, `setLocale()` | `@rudderjs/localization` |
81
- | Telescope | Debug dashboard | `@rudderjs/telescope` |
82
- | Boost (AI coding DX) | Expose project internals to Claude Code / Cursor / Copilot via MCP | `@rudderjs/boost` (devDep) |
83
- | Demos | Sample views (contact, ws, live) under `/demos` — **react primary only** | — |
72
+ Eight categories, 25 visible rows, one pre-checked. Picking ORM=none filters out the four DB-gated rows (Authentication, Sanctum, Passport, Cashier-Paddle).
73
+
74
+ ```
75
+ ─── Auth & Users ───
76
+ Authentication login, register, sessions
77
+ Sanctum API tokens (SHA-256 + abilities)
78
+ Passport OAuth 2 server requires Auth + Prisma
79
+ Socialite social login (GitHub, Google, Facebook, Apple)
80
+
81
+ ─── Infrastructure ───
82
+ Queue background jobs
83
+ Storage file uploads (local + S3)
84
+ Scheduler cron-like task scheduling
85
+ Image resize, crop, convert (sharp wrapper)
86
+
87
+ ─── Communication ───
88
+ Mail SMTP + log driver
89
+ Notifications multi-channel
90
+ WebSocket / Broadcast real-time channels
91
+ Sync (Yjs CRDT) collaborative documents
92
+
93
+ ─── AI ───
94
+ AI 11 LLM providers (Anthropic, OpenAI, …)
95
+ MCP Model Context Protocol — expose tools to LLMs
96
+ Boost AI coding DX (Claude Code / Cursor / Copilot)
97
+
98
+ ─── Internationalization ───
99
+ Localization i18n — trans(), setLocale()
100
+
101
+ ─── Product & Features ───
102
+ Cashier-Paddle subscriptions + checkout — requires Auth + Prisma
103
+ Pennant feature flags
104
+
105
+ ─── Observability ───
106
+ Telescope debug dashboard
107
+ Pulse metrics dashboard
108
+ Horizon queue monitoring
109
+
110
+ ─── Utilities ───
111
+ Crypt AES-256-CBC + HMAC encryption
112
+ HTTP fluent fetch client (retries, timeouts, pools)
113
+ Process shell execution (run, pool, pipe)
114
+ Concurrency parallel execution via worker threads
115
+ ```
84
116
 
85
117
  Package-specific behavior:
86
118
 
87
119
  - **AI** — generates `config/ai.ts`, AI chat demo at `/ai-chat`, `POST /api/ai/chat`.
88
- - **MCP** — generates `app/Mcp/EchoServer.ts` and wires `POST /mcp/echo`.
89
- - **Passport** — generates `config/passport.ts`, OAuth 2 routes (`/oauth/authorize`, `/oauth/token`, etc.), and `OAuthClient` + `OAuthAccessToken` Prisma models. Fails fast if Auth or Prisma isn't also selected.
90
- - **Demos** — generates `app/Views/Demos/{Index,Contact}.tsx` plus `Ws.tsx` (when Broadcast is selected) and `Live.tsx` (when Sync is selected). Index page lives at `/demos`. Skipped silently when the primary framework isn't React.
91
-
92
- Only selected packages get their dependencies, providers, config files, and schema files. Always-included base packages: `core`, `router`, `server-hono`, `middleware`, `vite`, `rudder`, `cli`, `log`. `session` + `hash` are pulled in automatically with Authentication.
120
+ - **MCP** — generates `app/Mcp/EchoServer.ts` + `EchoTool.ts` and wires `POST /mcp/echo`.
121
+ - **Passport** — generates `config/passport.ts`, OAuth 2 routes (`/oauth/authorize`, `/oauth/token`, etc.), and `OAuthClient` + `OAuthAccessToken` Prisma models. Filtered out when ORM=none.
122
+
123
+ ### Demos (prompt 9)
124
+
125
+ Each demo is a small view + one API endpoint, gated on the relevant package. The list is sourced from a single registry at `src/templates/demos/registry.ts` (also exported as `create-rudder-app/demos-registry` so the framework's own playground consumes it).
126
+
127
+ | Demo | Gate | What it shows |
128
+ |------|------|---------------|
129
+ | Contact form | always | CSRF + Zod validation, FormRequest-style errors |
130
+ | Cache counter | always | `Cache.get` + `Cache.set` round-trip |
131
+ | Todos | ORM | CRUD wired through ORM model + interactive UI |
132
+ | Queue dispatch | Queue | `ExampleJob.dispatch().send()` → handler logs |
133
+ | Mail send | Mail | `Mail.to(addr).send(new DemoMail(...))` via log driver |
134
+ | Notifications | Notifications + Mail | `notify(Notification.route('mail', addr), ...)` |
135
+ | Localization | Localization | locale switcher + `runWithLocale` + `trans()` |
136
+ | HTTP client | HTTP | `Http.retry(3, 200).timeout(5000).get(url)` against a public API |
137
+ | Avatar resize | Storage + Image | upload → 256×256 WebP via `@rudderjs/image` |
138
+ | Worker threads | Concurrency | sequential vs parallel `fib(n)` via `Concurrency.run()` |
139
+ | System info | Process | three shell commands via `Process.run()` and `Process.pool()` |
140
+ | Feature flags | Pennant + Auth | boolean / value / scoped / Lottery features + `FeatureMiddleware` |
141
+ | WebSocket chat | Broadcast | real-time chat + presence over a single WS |
142
+ | Yjs collaboration | Sync | CRDT live document with awareness cursors |
143
+
144
+ Demos are silently skipped when the primary framework isn't React (the templates ship React only for now).
145
+
146
+ Always-included base packages: `core`, `router`, `server-hono`, `middleware`, `vite`, `console`, `cli`, `log`, plus the Tier A trio above.
93
147
 
94
148
  ---
95
149
 
@@ -102,11 +156,16 @@ my-app/
102
156
  │ └── providers.ts # [...(await defaultProviders()), ...app providers]
103
157
  ├── config/ # app, server, log + per-package configs (auth, cache, session, …)
104
158
  ├── app/
105
- │ ├── Models/User.ts # (if Auth)
106
- │ ├── Views/ # (if Auth) Welcome + Auth/{Login,Register,...} vendored
107
- │ ├── Mcp/EchoServer.ts # (if MCP)
108
- ├── Providers/AppServiceProvider.ts
109
- └── Middleware/RequestIdMiddleware.ts
159
+ │ ├── Http/Controllers/AuthController.ts # (if Auth)
160
+ │ ├── Models/User.ts # (if Auth)
161
+ │ ├── Views/ # (if Auth) Welcome + Auth/{Login,Register,...} vendored
162
+ │ # + Demos/<picked>.tsx
163
+ ├── Mcp/{EchoServer,EchoTool}.ts # (if MCP)
164
+ │ ├── Modules/Todo/ # (if Todos demo)
165
+ │ ├── Jobs/ExampleJob.ts # (if Queue demo)
166
+ │ ├── Mail/DemoMail.ts # (if Mail demo)
167
+ │ ├── Notifications/WelcomeNotification.ts # (if Notifications demo)
168
+ │ └── Providers/AppServiceProvider.ts
110
169
  ├── routes/
111
170
  │ ├── api.ts # JSON API routes (+ auth endpoints if Auth, + OAuth2 if Passport)
112
171
  │ ├── web.ts # Vike page routes + registerAuthRoutes() (if Auth)
@@ -123,9 +182,12 @@ my-app/
123
182
  │ ├── auth.prisma # (if Auth) User + PasswordResetToken
124
183
  │ ├── passport.prisma # (if Passport) OAuthClient + OAuthAccessToken
125
184
  │ ├── notification.prisma # (if Notifications)
126
- │ └── modules.prisma # placeholder for per-feature modules
185
+ │ └── modules.prisma # per-feature module schemas (Todo, …)
127
186
  ├── drizzle/ # (if Drizzle) schema directory
128
- ├── src/index.css # (if Tailwind)
187
+ ├── lang/{en,es,ar}/ # (if Localization demo) message files
188
+ ├── src/
189
+ │ ├── index.css # (if Tailwind) — semantic classes work without Tailwind too
190
+ │ └── RudderSocket.ts # (if Broadcast) — vendored client helper
129
191
  ├── vite.config.ts
130
192
  ├── tsconfig.json
131
193
  ├── .env + .env.example
@@ -158,9 +220,11 @@ my-app/
158
220
 
159
221
  | Selection | `src/index.css` content |
160
222
  |-----------|------------------------|
161
- | Tailwind + shadcn | Full shadcn CSS variables + `@import "shadcn/tailwind.css"` |
162
- | Tailwind only | `@import "tailwindcss"; @import "tw-animate-css";` |
163
- | No Tailwind | File not generated |
223
+ | Tailwind + shadcn | shadcn CSS variables + `@import "shadcn/tailwind.css"` + semantic-class `@apply` rules |
224
+ | Tailwind only | `@import "tailwindcss"; @import "tw-animate-css";` + semantic-class `@apply` rules |
225
+ | No Tailwind | hand-authored CSS same semantic class names so JSX never branches on the flag |
226
+
227
+ Demos use the same semantic class vocabulary across all three variants — `.page`, `.feature-card`, `.form-input`, `.demo-card`, `.chat-bubble`, etc. — so they look right whether or not you ship Tailwind.
164
228
  </details>
165
229
 
166
230
  <details>
@@ -245,6 +309,16 @@ pnpm rudder vendor:publish --tag=auth-views-react # or auth-views-vue
245
309
  ```
246
310
  </details>
247
311
 
312
+ <details>
313
+ <summary><strong>APP_KEY length error after enabling Crypt</strong></summary>
314
+
315
+ `@rudderjs/crypt` requires exactly 32 bytes for AES-256. The scaffolder generates a valid key in `.env` but if you replace it, make sure the base64-decoded value is 32 bytes:
316
+
317
+ ```bash
318
+ node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
319
+ ```
320
+ </details>
321
+
248
322
  ---
249
323
 
250
324
  ## Related
@@ -262,11 +336,14 @@ git clone https://github.com/rudderjs/rudder.git
262
336
  cd rudder/create-rudder-app
263
337
  pnpm install
264
338
  pnpm build
265
- node dist/index.js # launches the interactive CLI from source
266
- pnpm test # 111 template tests
339
+ node dist/index.js # launches the interactive CLI from source
340
+ pnpm test # 169 template tests + snapshot baseline
341
+ pnpm smoke # default end-to-end smoke
342
+ pnpm smoke --profile=no-db # ORM=none + observability survivability
343
+ pnpm smoke --profile=demos-all # every demo at once
267
344
  ```
268
345
 
269
- Template logic lives in `src/templates.ts` (pure — returns `Record<path, content>`, no filesystem). The entrypoint `src/index.ts` handles prompts + writes + installs. Adding a new package option touches both files + `templates.test.ts`.
346
+ Template logic lives in `src/templates.ts` (pure — returns `Record<path, content>`, no filesystem) plus modular `src/templates/{configs,demos,prisma,…}/`. The entrypoint `src/index.ts` handles prompts + writes + installs. Adding a new package option touches `templates/configs/`, `templates/package-json.ts`, and `src/index.ts`. Adding a new demo means one entry in `src/templates/demos/registry.ts` plus a per-demo template module — the playground's `/demos` index picks it up automatically via the `create-rudder-app/demos-registry` subpath export.
270
347
 
271
348
  ---
272
349
 
@@ -1 +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"}
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;AAG7E,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA6C3D"}
@@ -1,110 +1,14 @@
1
1
  import { shouldScaffoldDemo } from '../../templates.js';
2
+ import { DEMOS, demoHref, demoTitle } from './registry.js';
2
3
  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');
4
+ const cards = DEMOS
5
+ .filter(d => shouldScaffoldDemo(ctx, d.value))
6
+ .map(d => ` <a key="${demoHref(d)}" href="${demoHref(d)}" className="feature-card">
7
+ <h3 className="feature-title">${demoTitle(d)}</h3>
8
+ <p className="feature-desc">${escapeJsxText(d.description)}</p>
9
+ <p className="feature-desc" style={{ fontSize: '0.7rem', opacity: 0.7 }}>${d.packages.join(' · ')}</p>
10
+ </a>`)
11
+ .join('\n');
108
12
  return `import '@/index.css'
109
13
 
110
14
  // Override the id-derived URL ('/demos/index') so SPA nav matches the controller ('/demos').
@@ -133,7 +37,7 @@ export default function DemosIndex() {
133
37
 
134
38
  <section className="feature-section">
135
39
  <div className="feature-grid">
136
- ${cardsJsx}
40
+ ${cards}
137
41
  </div>
138
42
  </section>
139
43
  </div>
@@ -141,4 +45,10 @@ ${cardsJsx}
141
45
  }
142
46
  `;
143
47
  }
48
+ // Description strings live as plain text in the registry, but they're emitted
49
+ // inside JSX text nodes. Escape '<' and '>' so a raw '<name>' (e.g. in the
50
+ // localization description) doesn't get parsed as a JSX element.
51
+ function escapeJsxText(s) {
52
+ return s.replace(/</g, '&lt;').replace(/>/g, '&gt;');
53
+ }
144
54
  //# sourceMappingURL=index-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-view.js","sourceRoot":"","sources":["../../../src/templates/demos/index-view.ts"],"names":[],"mappings":"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"}
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;AAC7E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE1D,MAAM,UAAU,cAAc,CAAC,GAAoB;IACjD,MAAM,KAAK,GAAG,KAAK;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;SAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,QAAQ,CAAC,CAAC,CAAC,WAAW,QAAQ,CAAC,CAAC,CAAC;0CACxB,SAAS,CAAC,CAAC,CAAC;wCACd,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;qFACiB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;aAC9F,CAAC;SACT,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BP,KAAK;;;;;;CAMN,CAAA;AACD,CAAC;AAED,8EAA8E;AAC9E,2EAA2E;AAC3E,iEAAiE;AACjE,SAAS,aAAa,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACtD,CAAC"}
@@ -1,13 +1,26 @@
1
1
  import type { TemplateContext } from '../../templates.js';
2
2
  export interface DemoSpec {
3
+ /** Stable id used in URLs, file names, and the prompt multiselect. */
3
4
  value: string;
5
+ /** Short label shown in the @clack/prompts multiselect. */
4
6
  label: string;
7
+ /** Single-line hint shown next to the label in the prompt. */
5
8
  hint?: string;
9
+ /** Card title shown on /demos. Falls back to `label` when omitted. */
10
+ title?: string;
11
+ /** Long description shown on the /demos card in the scaffolded app + playground. */
12
+ description: string;
13
+ /** Packages this demo exercises — rendered under each /demos card. */
14
+ packages: ReadonlyArray<string>;
6
15
  /** Package keys that must all be selected for this demo to scaffold. */
7
16
  requires?: ReadonlyArray<keyof TemplateContext['packages']>;
8
17
  /** True if this demo requires a database/ORM. */
9
18
  requiresOrm?: boolean;
10
19
  }
20
+ /** Card title used on /demos — falls back to `label` when not overridden. */
21
+ export declare function demoTitle(spec: DemoSpec): string;
11
22
  export declare const DEMOS: ReadonlyArray<DemoSpec>;
12
23
  export declare function availableDemos(orm: TemplateContext['orm'], packages: TemplateContext['packages']): DemoSpec[];
24
+ /** Default href for a demo card — `/demos/<value>`. */
25
+ export declare function demoHref(spec: Pick<DemoSpec, 'value'>): string;
13
26
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +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,CAezC,CAAA;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,GACpC,QAAQ,EAAE,CAMZ"}
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,sEAAsE;IACtE,KAAK,EAAS,MAAM,CAAA;IACpB,2DAA2D;IAC3D,KAAK,EAAS,MAAM,CAAA;IACpB,8DAA8D;IAC9D,IAAI,CAAC,EAAS,MAAM,CAAA;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAQ,MAAM,CAAA;IACpB,oFAAoF;IACpF,WAAW,EAAG,MAAM,CAAA;IACpB,sEAAsE;IACtE,QAAQ,EAAM,aAAa,CAAC,MAAM,CAAC,CAAA;IACnC,wEAAwE;IACxE,QAAQ,CAAC,EAAK,aAAa,CAAC,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC,CAAA;IAC9D,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEhD;AAED,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,QAAQ,CAiHzC,CAAA;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,EAC3B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,GACpC,QAAQ,EAAE,CAMZ;AAED,uDAAuD;AACvD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,CAE9D"}
@@ -1,18 +1,120 @@
1
+ /** Card title used on /demos — falls back to `label` when not overridden. */
2
+ export function demoTitle(spec) {
3
+ return spec.title ?? spec.label;
4
+ }
1
5
  export const DEMOS = [
2
- { value: 'contact', label: 'Contact form', hint: 'CSRF + Zod validation' },
3
- { value: 'cache', label: 'Cache counter', hint: 'Cache.get + Cache.set round-trip' },
4
- { value: 'todos', label: 'Todos CRUD', hint: 'requires ORM', requiresOrm: true },
5
- { value: 'queue', label: 'Queue dispatch', hint: 'requires Queue', requires: ['queue'] },
6
- { value: 'mail', label: 'Mail send', hint: 'requires Mail', requires: ['mail'] },
7
- { value: 'notifications', label: 'Notifications', hint: 'requires Notifications + Mail', requires: ['notifications', 'mail'] },
8
- { value: 'localization', label: 'Localization', hint: 'requires Localization', requires: ['localization'] },
9
- { value: 'http', label: 'HTTP client', hint: 'requires HTTP', requires: ['http'] },
10
- { value: 'avatar', label: 'Avatar resize', hint: 'requires Storage + Image', requires: ['storage', 'image'] },
11
- { value: 'fibonacci', label: 'Worker threads', hint: 'requires Concurrency', requires: ['concurrency'] },
12
- { value: 'system-info', label: 'System info', hint: 'requires Process', requires: ['process'] },
13
- { value: 'pennant', label: 'Feature flags', hint: 'requires Pennant + Auth', requires: ['pennant', 'auth'] },
14
- { value: 'ws', label: 'WebSocket chat', hint: 'requires WebSocket / Broadcast', requires: ['broadcast'] },
15
- { value: 'sync', label: 'Yjs collaboration', hint: 'requires Sync', requires: ['sync'] },
6
+ {
7
+ value: 'contact',
8
+ label: 'Contact form',
9
+ hint: 'CSRF + Zod validation',
10
+ description: 'CSRF-protected form with Zod validation. Demonstrates getCsrfToken() and FormRequest-style error handling.',
11
+ packages: ['@rudderjs/middleware', '@rudderjs/core'],
12
+ },
13
+ {
14
+ value: 'cache',
15
+ label: 'Cache counter',
16
+ hint: 'Cache.get + Cache.set round-trip',
17
+ description: 'Click "Bump" to read the current value via Cache.get, increment it, and write it back via Cache.set. Default driver is in-memory.',
18
+ packages: ['@rudderjs/cache'],
19
+ },
20
+ {
21
+ value: 'todos',
22
+ label: 'Todos CRUD',
23
+ title: 'Todos',
24
+ hint: 'requires ORM',
25
+ description: 'ORM + interactive UI. Controller loads initial data, the view hydrates and POSTs to /api/todos/* for live updates.',
26
+ packages: ['@rudderjs/orm', '@rudderjs/router'],
27
+ requiresOrm: true,
28
+ },
29
+ {
30
+ value: 'queue',
31
+ label: 'Queue dispatch',
32
+ hint: 'requires Queue',
33
+ description: 'Dispatch ExampleJob via @rudderjs/queue. The handler logs to the server terminal — install @rudderjs/horizon for a UI.',
34
+ packages: ['@rudderjs/queue'],
35
+ requires: ['queue'],
36
+ },
37
+ {
38
+ value: 'mail',
39
+ label: 'Mail send',
40
+ hint: 'requires Mail',
41
+ description: 'Send a DemoMail via @rudderjs/mail. Default driver is log — output lands in the dev server terminal.',
42
+ packages: ['@rudderjs/mail'],
43
+ requires: ['mail'],
44
+ },
45
+ {
46
+ value: 'notifications',
47
+ label: 'Notifications',
48
+ hint: 'requires Notifications + Mail',
49
+ description: "Dispatch a WelcomeNotification via notify(). The notification's via() picks the channel(s); mail routes through the log driver.",
50
+ packages: ['@rudderjs/notification', '@rudderjs/mail'],
51
+ requires: ['notifications', 'mail'],
52
+ },
53
+ {
54
+ value: 'localization',
55
+ label: 'Localization',
56
+ hint: 'requires Localization',
57
+ description: 'Locale switcher resolves the same keys server-side via trans(). Strings live in lang/<locale>/messages.json.',
58
+ packages: ['@rudderjs/localization'],
59
+ requires: ['localization'],
60
+ },
61
+ {
62
+ value: 'http',
63
+ label: 'HTTP client',
64
+ hint: 'requires HTTP',
65
+ description: 'Server-side Http.retry(3, 200).timeout(5000).get(url) against a public API. The 500 endpoint exercises the retry path.',
66
+ packages: ['@rudderjs/http'],
67
+ requires: ['http'],
68
+ },
69
+ {
70
+ value: 'avatar',
71
+ label: 'Avatar resize',
72
+ hint: 'requires Storage + Image',
73
+ description: 'Upload an image — server resizes it to 256×256 WebP via @rudderjs/image and saves to public storage. Side-by-side compare.',
74
+ packages: ['@rudderjs/image', '@rudderjs/storage'],
75
+ requires: ['storage', 'image'],
76
+ },
77
+ {
78
+ value: 'fibonacci',
79
+ label: 'Worker threads',
80
+ hint: 'requires Concurrency',
81
+ description: 'Compute fib(n) sequentially on the main thread vs across @rudderjs/concurrency worker pool. Watch the parallel cost stay flat as you crank N.',
82
+ packages: ['@rudderjs/concurrency'],
83
+ requires: ['concurrency'],
84
+ },
85
+ {
86
+ value: 'system-info',
87
+ label: 'System info',
88
+ hint: 'requires Process',
89
+ description: 'Three shell commands (git, node, uptime) executed via @rudderjs/process. Compares sequential vs parallel cost using Process.pool().',
90
+ packages: ['@rudderjs/process'],
91
+ requires: ['process'],
92
+ },
93
+ {
94
+ value: 'pennant',
95
+ label: 'Feature flags',
96
+ hint: 'requires Pennant + Auth',
97
+ description: 'Boolean, value, scoped, and Lottery features resolved against the current user. Sub-route guarded by FeatureMiddleware to demonstrate 403 blocking.',
98
+ packages: ['@rudderjs/pennant'],
99
+ requires: ['pennant', 'auth'],
100
+ },
101
+ {
102
+ value: 'ws',
103
+ label: 'WebSocket chat',
104
+ hint: 'requires WebSocket / Broadcast',
105
+ description: 'Real-time chat + presence using @rudderjs/broadcast — multi-channel pub/sub over a single WebSocket connection.',
106
+ packages: ['@rudderjs/broadcast'],
107
+ requires: ['broadcast'],
108
+ },
109
+ {
110
+ value: 'sync',
111
+ label: 'Yjs collaboration',
112
+ title: 'Collaborative editor',
113
+ hint: 'requires Sync',
114
+ description: 'Yjs CRDT live document with awareness cursors. Open in two tabs to see real-time sync over @rudderjs/sync.',
115
+ packages: ['@rudderjs/sync'],
116
+ requires: ['sync'],
117
+ },
16
118
  ];
17
119
  export function availableDemos(orm, packages) {
18
120
  return DEMOS.filter(d => {
@@ -23,4 +125,8 @@ export function availableDemos(orm, packages) {
23
125
  return true;
24
126
  });
25
127
  }
128
+ /** Default href for a demo card — `/demos/<value>`. */
129
+ export function demoHref(spec) {
130
+ return `/demos/${spec.value}`;
131
+ }
26
132
  //# sourceMappingURL=registry.js.map
@@ -1 +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,EAAQ,KAAK,EAAE,cAAc,EAAO,IAAI,EAAE,uBAAuB,EAAE;IACrF,EAAE,KAAK,EAAE,OAAO,EAAU,KAAK,EAAE,eAAe,EAAM,IAAI,EAAE,kCAAkC,EAAE;IAChG,EAAE,KAAK,EAAE,OAAO,EAAU,KAAK,EAAE,YAAY,EAAS,IAAI,EAAE,cAAc,EAAoB,WAAW,EAAE,IAAI,EAAE;IACjH,EAAE,KAAK,EAAE,OAAO,EAAU,KAAK,EAAE,gBAAgB,EAAK,IAAI,EAAE,gBAAgB,EAAkB,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;IACnH,EAAE,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,WAAW,EAAU,IAAI,EAAE,eAAe,EAAmB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;IAClH,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAM,IAAI,EAAE,+BAA+B,EAAG,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE;IACnI,EAAE,KAAK,EAAE,cAAc,EAAG,KAAK,EAAE,cAAc,EAAO,IAAI,EAAE,uBAAuB,EAAW,QAAQ,EAAE,CAAC,cAAc,CAAC,EAAE;IAC1H,EAAE,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,aAAa,EAAQ,IAAI,EAAE,eAAe,EAAmB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;IAClH,EAAE,KAAK,EAAE,QAAQ,EAAS,KAAK,EAAE,eAAe,EAAM,IAAI,EAAE,0BAA0B,EAAQ,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;IAC9H,EAAE,KAAK,EAAE,WAAW,EAAM,KAAK,EAAE,gBAAgB,EAAK,IAAI,EAAE,sBAAsB,EAAY,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IACzH,EAAE,KAAK,EAAE,aAAa,EAAI,KAAK,EAAE,aAAa,EAAQ,IAAI,EAAE,kBAAkB,EAAgB,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE;IACrH,EAAE,KAAK,EAAE,SAAS,EAAQ,KAAK,EAAE,eAAe,EAAM,IAAI,EAAE,yBAAyB,EAAS,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE;IAC7H,EAAE,KAAK,EAAE,IAAI,EAAa,KAAK,EAAE,gBAAgB,EAAK,IAAI,EAAE,gCAAgC,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;IACvH,EAAE,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,eAAe,EAAmB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;CACnH,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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/templates/demos/registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-rudder-app",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,6 +19,10 @@
19
19
  "exports": {
20
20
  ".": {
21
21
  "import": "./dist/index.js"
22
+ },
23
+ "./demos-registry": {
24
+ "types": "./dist/templates/demos/registry.d.ts",
25
+ "import": "./dist/templates/demos/registry.js"
22
26
  }
23
27
  },
24
28
  "dependencies": {