create-rudder-app 1.1.2 → 1.2.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.
Files changed (113) hide show
  1. package/dist/cli-flags.d.ts +0 -9
  2. package/dist/cli-flags.d.ts.map +1 -1
  3. package/dist/cli-flags.js +0 -8
  4. package/dist/cli-flags.js.map +1 -1
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/templates/app/service-provider.d.ts.map +1 -1
  8. package/dist/templates/app/service-provider.js +0 -15
  9. package/dist/templates/app/service-provider.js.map +1 -1
  10. package/dist/templates/components/site-header.d.ts.map +1 -1
  11. package/dist/templates/components/site-header.js +2 -8
  12. package/dist/templates/components/site-header.js.map +1 -1
  13. package/dist/templates/package-json.d.ts.map +1 -1
  14. package/dist/templates/package-json.js +4 -5
  15. package/dist/templates/package-json.js.map +1 -1
  16. package/dist/templates/pages/index.d.ts +13 -0
  17. package/dist/templates/pages/index.d.ts.map +1 -1
  18. package/dist/templates/pages/index.js +43 -0
  19. package/dist/templates/pages/index.js.map +1 -1
  20. package/dist/templates/routes/api.d.ts.map +1 -1
  21. package/dist/templates/routes/api.js +0 -99
  22. package/dist/templates/routes/api.js.map +1 -1
  23. package/dist/templates/routes/console.d.ts.map +1 -1
  24. package/dist/templates/routes/console.js +3 -4
  25. package/dist/templates/routes/console.js.map +1 -1
  26. package/dist/templates/routes/web.d.ts.map +1 -1
  27. package/dist/templates/routes/web.js +10 -83
  28. package/dist/templates/routes/web.js.map +1 -1
  29. package/dist/templates/routes-manifest.d.ts +2 -2
  30. package/dist/templates/routes-manifest.d.ts.map +1 -1
  31. package/dist/templates/routes-manifest.js +19 -22
  32. package/dist/templates/routes-manifest.js.map +1 -1
  33. package/dist/templates/views/welcome.d.ts +13 -0
  34. package/dist/templates/views/welcome.d.ts.map +1 -1
  35. package/dist/templates/views/welcome.js +53 -0
  36. package/dist/templates/views/welcome.js.map +1 -1
  37. package/dist/templates.d.ts +0 -9
  38. package/dist/templates.d.ts.map +1 -1
  39. package/dist/templates.js +38 -120
  40. package/dist/templates.js.map +1 -1
  41. package/package.json +1 -5
  42. package/dist/templates/demos/avatar.d.ts +0 -3
  43. package/dist/templates/demos/avatar.d.ts.map +0 -1
  44. package/dist/templates/demos/avatar.js +0 -174
  45. package/dist/templates/demos/avatar.js.map +0 -1
  46. package/dist/templates/demos/cache.d.ts +0 -3
  47. package/dist/templates/demos/cache.d.ts.map +0 -1
  48. package/dist/templates/demos/cache.js +0 -91
  49. package/dist/templates/demos/cache.js.map +0 -1
  50. package/dist/templates/demos/contact.d.ts +0 -3
  51. package/dist/templates/demos/contact.d.ts.map +0 -1
  52. package/dist/templates/demos/contact.js +0 -99
  53. package/dist/templates/demos/contact.js.map +0 -1
  54. package/dist/templates/demos/fibonacci.d.ts +0 -7
  55. package/dist/templates/demos/fibonacci.d.ts.map +0 -1
  56. package/dist/templates/demos/fibonacci.js +0 -164
  57. package/dist/templates/demos/fibonacci.js.map +0 -1
  58. package/dist/templates/demos/http.d.ts +0 -3
  59. package/dist/templates/demos/http.d.ts.map +0 -1
  60. package/dist/templates/demos/http.js +0 -109
  61. package/dist/templates/demos/http.js.map +0 -1
  62. package/dist/templates/demos/index-view.d.ts +0 -3
  63. package/dist/templates/demos/index-view.d.ts.map +0 -1
  64. package/dist/templates/demos/index-view.js +0 -47
  65. package/dist/templates/demos/index-view.js.map +0 -1
  66. package/dist/templates/demos/localization.d.ts +0 -4
  67. package/dist/templates/demos/localization.d.ts.map +0 -1
  68. package/dist/templates/demos/localization.js +0 -122
  69. package/dist/templates/demos/localization.js.map +0 -1
  70. package/dist/templates/demos/mail.d.ts +0 -4
  71. package/dist/templates/demos/mail.d.ts.map +0 -1
  72. package/dist/templates/demos/mail.js +0 -119
  73. package/dist/templates/demos/mail.js.map +0 -1
  74. package/dist/templates/demos/notifications.d.ts +0 -4
  75. package/dist/templates/demos/notifications.d.ts.map +0 -1
  76. package/dist/templates/demos/notifications.js +0 -125
  77. package/dist/templates/demos/notifications.js.map +0 -1
  78. package/dist/templates/demos/pennant.d.ts +0 -8
  79. package/dist/templates/demos/pennant.d.ts.map +0 -1
  80. package/dist/templates/demos/pennant.js +0 -135
  81. package/dist/templates/demos/pennant.js.map +0 -1
  82. package/dist/templates/demos/polymorphic.d.ts +0 -19
  83. package/dist/templates/demos/polymorphic.d.ts.map +0 -1
  84. package/dist/templates/demos/polymorphic.js +0 -663
  85. package/dist/templates/demos/polymorphic.js.map +0 -1
  86. package/dist/templates/demos/queue.d.ts +0 -4
  87. package/dist/templates/demos/queue.d.ts.map +0 -1
  88. package/dist/templates/demos/queue.js +0 -99
  89. package/dist/templates/demos/queue.js.map +0 -1
  90. package/dist/templates/demos/registry.d.ts +0 -26
  91. package/dist/templates/demos/registry.d.ts.map +0 -1
  92. package/dist/templates/demos/registry.js +0 -140
  93. package/dist/templates/demos/registry.js.map +0 -1
  94. package/dist/templates/demos/rudder-socket.d.ts +0 -2
  95. package/dist/templates/demos/rudder-socket.d.ts.map +0 -1
  96. package/dist/templates/demos/rudder-socket.js +0 -95
  97. package/dist/templates/demos/rudder-socket.js.map +0 -1
  98. package/dist/templates/demos/sync.d.ts +0 -2
  99. package/dist/templates/demos/sync.d.ts.map +0 -1
  100. package/dist/templates/demos/sync.js +0 -90
  101. package/dist/templates/demos/sync.js.map +0 -1
  102. package/dist/templates/demos/system-info.d.ts +0 -3
  103. package/dist/templates/demos/system-info.d.ts.map +0 -1
  104. package/dist/templates/demos/system-info.js +0 -134
  105. package/dist/templates/demos/system-info.js.map +0 -1
  106. package/dist/templates/demos/todos.d.ts +0 -6
  107. package/dist/templates/demos/todos.d.ts.map +0 -1
  108. package/dist/templates/demos/todos.js +0 -238
  109. package/dist/templates/demos/todos.js.map +0 -1
  110. package/dist/templates/demos/ws.d.ts +0 -2
  111. package/dist/templates/demos/ws.d.ts.map +0 -1
  112. package/dist/templates/demos/ws.js +0 -99
  113. package/dist/templates/demos/ws.js.map +0 -1
@@ -1,238 +0,0 @@
1
- // Todos demo — ORM + interactive CRUD via @rudderjs/router.
2
- //
3
- // Scaffolds five files under `app/Modules/Todo/` (Laravel-style self-contained
4
- // module) plus the React view, and wires them into AppServiceProvider's boot()
5
- // so the API routes register at app startup.
6
- export function demosTodosView() {
7
- return `import '@/index.css'
8
- import { SiteHeader } from 'App/Components/SiteHeader.js'
9
- import { useState, useRef } from 'react'
10
- import type { Todo } from '../../Modules/Todo/TodoSchema.js'
11
-
12
- interface TodosDemoProps {
13
- todos: Todo[]
14
- }
15
-
16
- export default function TodosDemo({ todos: initial }: TodosDemoProps) {
17
- const [todos, setTodos] = useState<Todo[]>(initial)
18
- const [loading, setLoading] = useState(false)
19
- const inputRef = useRef<HTMLInputElement>(null)
20
-
21
- async function addTodo() {
22
- const title = inputRef.current?.value.trim()
23
- if (!title) return
24
- setLoading(true)
25
- const res = await fetch('/api/todos', {
26
- method: 'POST',
27
- headers: { 'Content-Type': 'application/json' },
28
- body: JSON.stringify({ title }),
29
- })
30
- const { data } = await res.json() as { data: Todo }
31
- setTodos(prev => [data, ...prev])
32
- if (inputRef.current) inputRef.current.value = ''
33
- setLoading(false)
34
- }
35
-
36
- async function toggleTodo(todo: Todo) {
37
- const res = await fetch(\`/api/todos/\${todo.id}\`, {
38
- method: 'PATCH',
39
- headers: { 'Content-Type': 'application/json' },
40
- body: JSON.stringify({ completed: !todo.completed }),
41
- })
42
- const { data } = await res.json() as { data: Todo }
43
- setTodos(prev => prev.map(t => t.id === data.id ? data : t))
44
- }
45
-
46
- async function deleteTodo(id: string) {
47
- await fetch(\`/api/todos/\${id}\`, { method: 'DELETE' })
48
- setTodos(prev => prev.filter(t => t.id !== id))
49
- }
50
-
51
- const done = todos.filter(t => t.completed).length
52
- const pending = todos.length - done
53
-
54
- return (
55
- <div className="page">
56
- <SiteHeader />
57
-
58
- <section className="hero">
59
- <h1 className="hero-title">Todo List</h1>
60
- <p className="hero-lead">
61
- {pending} remaining · {done} completed
62
- </p>
63
- <p className="hero-meta">
64
- Rendered from <code className="inline-code">app/Views/Demos/Todos.tsx</code> via{' '}
65
- <code className="inline-code">view('demos.todos', &#123; todos &#125;)</code>.
66
- Initial data fetched by the controller, not the view.
67
- </p>
68
- </section>
69
-
70
- <section className="feature-section">
71
- <div className="demo-narrow">
72
- <div className="demo-card">
73
- <div className="input-row">
74
- <input
75
- ref={inputRef}
76
- className="form-input"
77
- placeholder="What needs to be done?"
78
- onKeyDown={e => e.key === 'Enter' && addTodo()}
79
- />
80
- <button className="button-primary" onClick={addTodo} disabled={loading}>
81
- {loading ? '...' : 'Add'}
82
- </button>
83
- </div>
84
- </div>
85
-
86
- <div className="demo-card">
87
- <div className="demo-card-header">
88
- <h2 className="demo-card-title">Tasks</h2>
89
- </div>
90
- <div className="demo-card-body">
91
- {todos.length === 0 && (
92
- <p className="empty-state">No todos yet. Add one above!</p>
93
- )}
94
- {todos.map(todo => (
95
- <div key={todo.id} className="list-row group">
96
- <input
97
- type="checkbox"
98
- className="checkbox-input"
99
- checked={todo.completed}
100
- onChange={() => toggleTodo(todo)}
101
- />
102
- <span className={\`list-row-text\${todo.completed ? ' list-row-text-done' : ''}\`}>
103
- {todo.title}
104
- </span>
105
- <button
106
- onClick={() => deleteTodo(todo.id)}
107
- className="list-row-delete"
108
- aria-label="Delete"
109
- >
110
-
111
- </button>
112
- </div>
113
- ))}
114
- </div>
115
- </div>
116
- </div>
117
- </section>
118
- </div>
119
- )
120
- }
121
- `;
122
- }
123
- export function todoModelPrisma() {
124
- return `model Todo {
125
- id String @id @default(cuid())
126
- title String
127
- completed Boolean @default(false)
128
- createdAt DateTime @default(now())
129
- updatedAt DateTime @updatedAt
130
- }
131
- `;
132
- }
133
- export function todoSchema() {
134
- return `import { z } from 'zod'
135
-
136
- export const TodoInputSchema = z.object({
137
- title: z.string().min(1, 'Title is required'),
138
- completed: z.boolean().optional().default(false),
139
- })
140
-
141
- export const TodoUpdateSchema = z.object({
142
- title: z.string().min(1).optional(),
143
- completed: z.boolean().optional(),
144
- })
145
-
146
- export type TodoInput = z.infer<typeof TodoInputSchema>
147
- export type TodoUpdate = z.infer<typeof TodoUpdateSchema>
148
-
149
- export interface Todo {
150
- id: string
151
- title: string
152
- completed: boolean
153
- createdAt: Date
154
- updatedAt: Date
155
- }
156
- `;
157
- }
158
- export function todoService() {
159
- return `import { Injectable, resolve } from '@rudderjs/core'
160
- import type { OrmAdapter } from '@rudderjs/orm'
161
- import type { Todo, TodoInput, TodoUpdate } from './TodoSchema.js'
162
-
163
- @Injectable()
164
- export class TodoService {
165
- private get db(): OrmAdapter {
166
- return resolve<OrmAdapter>('db')
167
- }
168
-
169
- findAll(): Promise<Todo[]> {
170
- return this.db.query<Todo>('todo').orderBy('createdAt', 'DESC').get()
171
- }
172
-
173
- findById(id: string): Promise<Todo | null> {
174
- return this.db.query<Todo>('todo').find(id)
175
- }
176
-
177
- create(input: TodoInput): Promise<Todo> {
178
- return this.db.query<Todo>('todo').create(input)
179
- }
180
-
181
- update(id: string, input: TodoUpdate): Promise<Todo> {
182
- return this.db.query<Todo>('todo').update(id, input as Partial<Todo>)
183
- }
184
-
185
- delete(id: string): Promise<void> {
186
- return this.db.query<Todo>('todo').delete(id)
187
- }
188
- }
189
- `;
190
- }
191
- export function todoServiceProvider() {
192
- return `import { ServiceProvider } from '@rudderjs/core'
193
- import { router } from '@rudderjs/router'
194
- import { TodoService } from './TodoService.js'
195
- import { TodoInputSchema, TodoUpdateSchema } from './TodoSchema.js'
196
-
197
- export class TodoServiceProvider extends ServiceProvider {
198
- register(): void {
199
- this.app.singleton(TodoService, () => new TodoService())
200
- }
201
-
202
- override async boot(): Promise<void> {
203
- const service = this.app.make<TodoService>(TodoService)
204
-
205
- router.get('/api/todos', async (_req, res) => {
206
- const todos = await service.findAll()
207
- res.json({ data: todos })
208
- })
209
-
210
- router.post('/api/todos', async (req, res) => {
211
- const parsed = TodoInputSchema.safeParse(req.body)
212
- if (!parsed.success) {
213
- res.status(422).json({ errors: parsed.error.flatten().fieldErrors })
214
- return
215
- }
216
- const todo = await service.create(parsed.data)
217
- res.status(201).json({ data: todo })
218
- })
219
-
220
- router.patch('/api/todos/:id', async (req, res) => {
221
- const parsed = TodoUpdateSchema.safeParse(req.body)
222
- if (!parsed.success) {
223
- res.status(422).json({ errors: parsed.error.flatten().fieldErrors })
224
- return
225
- }
226
- const todo = await service.update(req.params['id']!, parsed.data)
227
- res.json({ data: todo })
228
- })
229
-
230
- router.delete('/api/todos/:id', async (req, res) => {
231
- await service.delete(req.params['id']!)
232
- res.status(204).send('')
233
- })
234
- }
235
- }
236
- `;
237
- }
238
- //# sourceMappingURL=todos.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"todos.js","sourceRoot":"","sources":["../../../src/templates/demos/todos.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,6CAA6C;AAE7C,MAAM,UAAU,cAAc;IAC5B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO;;;;;;;CAOR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;CAsBR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CR,CAAA;AACD,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function demosWsView(): string;
2
- //# sourceMappingURL=ws.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../../src/templates/demos/ws.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,IAAI,MAAM,CAiGpC"}
@@ -1,99 +0,0 @@
1
- export function demosWsView() {
2
- return `import '@/index.css'
3
- import { SiteHeader } from 'App/Components/SiteHeader.js'
4
- import { useEffect, useRef, useState } from 'react'
5
- import { RudderSocket } from '@/RudderSocket'
6
-
7
- type Message = { user: string; text: string; ts: number }
8
- type Member = { id: string; name: string }
9
-
10
- function getWsUrl() {
11
- if (typeof window === 'undefined') return ''
12
- return \`ws://\${window.location.host}/ws\`
13
- }
14
-
15
- export default function WsDemo() {
16
- const [me, setMe] = useState('')
17
- const socketRef = useRef<RudderSocket | null>(null)
18
- const [connected, setConnected] = useState(false)
19
- const [messages, setMessages] = useState<Message[]>([])
20
- const [members, setMembers] = useState<Member[]>([])
21
- const [input, setInput] = useState('')
22
-
23
- useEffect(() => { setMe(\`User-\${Math.floor(Math.random() * 1000)}\`) }, [])
24
-
25
- useEffect(() => {
26
- if (!me) return
27
- const socket = new RudderSocket(getWsUrl())
28
- socketRef.current = socket
29
-
30
- const chat = socket.channel('chat')
31
- chat.on('message', d => setMessages(prev => [...prev, d as Message]))
32
-
33
- const room = socket.presence('lobby', 'demo-token')
34
- room.on('presence.members', d => {
35
- setMembers(d as Member[])
36
- setConnected(true)
37
- })
38
- room.on('presence.joined', d => {
39
- const u = d as Member
40
- setMembers(prev => [...prev.filter(m => m.id !== u.id), u])
41
- })
42
- room.on('presence.left', d => {
43
- const id = (d as { id: string }).id
44
- setMembers(prev => prev.filter(m => m.id !== id))
45
- })
46
-
47
- return () => { socket.disconnect() }
48
- }, [me])
49
-
50
- async function send() {
51
- if (!input.trim()) return
52
- await fetch('/api/ws/broadcast', {
53
- method: 'POST',
54
- headers: { 'Content-Type': 'application/json' },
55
- body: JSON.stringify({ user: me, text: input.trim() }),
56
- })
57
- setInput('')
58
- }
59
-
60
- return (
61
- <div className="page">
62
- <SiteHeader />
63
-
64
- <section className="hero">
65
- <h1 className="hero-title">WebSocket chat</h1>
66
- <p className="hero-lead">
67
- Pub/sub + presence over a single WebSocket. Connected as <strong>{me}</strong>.{' '}
68
- {connected ? '🟢 connected' : '⚪ connecting…'}
69
- </p>
70
- </section>
71
-
72
- <section className="feature-section" style={{ maxWidth: '40rem', margin: '0 auto' }}>
73
- <p className="form-label">Members ({members.length})</p>
74
- <ul style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginBottom: '1rem' }}>
75
- {members.map(m => (
76
- <li key={m.id} className="inline-code">{m.name}</li>
77
- ))}
78
- </ul>
79
-
80
- <div style={{ minHeight: '12rem', marginBottom: '1rem' }}>
81
- {messages.map((m, i) => (
82
- <p key={i} style={{ margin: '0.25rem 0' }}>
83
- <strong>{m.user}:</strong> {m.text}
84
- </p>
85
- ))}
86
- </div>
87
-
88
- <form onSubmit={e => { e.preventDefault(); void send() }} style={{ display: 'flex', gap: '0.5rem' }}>
89
- <input className="form-input" value={input}
90
- onChange={e => setInput(e.target.value)} placeholder="Say something…" />
91
- <button type="submit" className="form-submit" style={{ width: 'auto' }}>Send</button>
92
- </form>
93
- </section>
94
- </div>
95
- )
96
- }
97
- `;
98
- }
99
- //# sourceMappingURL=ws.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../../src/templates/demos/ws.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+FR,CAAA;AACD,CAAC"}