@idealyst/cli 1.2.32 → 1.2.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +5 -1
- package/dist/constants.js.map +1 -1
- package/dist/generators/core/shared.js +382 -3
- package/dist/generators/core/shared.js.map +1 -1
- package/dist/generators/extensions/graphql.js +112 -26
- package/dist/generators/extensions/graphql.js.map +1 -1
- package/dist/generators/extensions/prisma.js +105 -16
- package/dist/generators/extensions/prisma.js.map +1 -1
- package/dist/generators/extensions/trpc.js +137 -41
- package/dist/generators/extensions/trpc.js.map +1 -1
- package/dist/templates/core/api/src-graphql/builder.ts +25 -0
- package/dist/templates/core/api/src-graphql/schema.ts +217 -0
- package/dist/templates/core/api/src-trpc/context.ts +15 -0
- package/dist/templates/core/api/src-trpc/index.ts +6 -0
- package/dist/templates/core/api/src-trpc/lib/database.ts +4 -0
- package/dist/templates/core/api/src-trpc/router/index.ts +187 -0
- package/dist/templates/core/api/src-trpc/server.ts +63 -0
- package/dist/templates/core/api/src-trpc/trpc.ts +20 -0
- package/dist/templates/core/database/schema.prisma +22 -0
- package/dist/templates/core/shared/src-components/App.tsx +51 -0
- package/dist/templates/core/shared/src-graphql/client.ts +70 -0
- package/dist/templates/core/shared/{src/navigation → src-navigation}/AppRouter.tsx +34 -0
- package/dist/templates/core/shared/src-screens-graphql/GraphQLDemoScreen.tsx +354 -0
- package/dist/templates/core/shared/src-screens-trpc/TRPCDemoScreen.tsx +432 -0
- package/dist/templates/core/shared/src-trpc/client.ts +44 -0
- package/dist/types/constants.d.ts +9 -5
- package/package.json +1 -1
- package/dist/templates/core/shared/src/components/App.tsx +0 -13
- package/dist/templates/core/shared/src/screens/index.ts +0 -4
- /package/dist/templates/core/shared/{src/components → src-components}/index.ts +0 -0
- /package/dist/templates/core/shared/{src/layouts → src-layouts}/AppLayout.tsx +0 -0
- /package/dist/templates/core/shared/{src/navigation → src-navigation}/index.ts +0 -0
- /package/dist/templates/core/shared/{src/screens → src-screens}/ExploreScreen.tsx +0 -0
- /package/dist/templates/core/shared/{src/screens → src-screens}/HomeScreen.tsx +0 -0
- /package/dist/templates/core/shared/{src/screens → src-screens}/ProfileScreen.tsx +0 -0
- /package/dist/templates/core/shared/{src/screens → src-screens}/SettingsScreen.tsx +0 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Screen,
|
|
4
|
+
View,
|
|
5
|
+
Text,
|
|
6
|
+
Card,
|
|
7
|
+
Button,
|
|
8
|
+
Icon,
|
|
9
|
+
Badge,
|
|
10
|
+
ActivityIndicator,
|
|
11
|
+
Alert,
|
|
12
|
+
TextInput,
|
|
13
|
+
Divider,
|
|
14
|
+
} from '@idealyst/components';
|
|
15
|
+
import { trpc } from '../trpc/client';
|
|
16
|
+
|
|
17
|
+
// Set this to true if database/Prisma is available
|
|
18
|
+
// This will be replaced by the CLI generator based on user selection
|
|
19
|
+
const HAS_DATABASE = true;
|
|
20
|
+
|
|
21
|
+
export const TRPCDemoScreen: React.FC = () => {
|
|
22
|
+
const [echoInput, setEchoInput] = useState('');
|
|
23
|
+
const [newItemTitle, setNewItemTitle] = useState('');
|
|
24
|
+
|
|
25
|
+
// ==========================================================================
|
|
26
|
+
// Base tRPC queries (no database required)
|
|
27
|
+
// ==========================================================================
|
|
28
|
+
const healthQuery = trpc.health.useQuery();
|
|
29
|
+
const counterQuery = trpc.counter.get.useQuery();
|
|
30
|
+
|
|
31
|
+
const echoQuery = trpc.echo.useQuery(
|
|
32
|
+
{ message: echoInput },
|
|
33
|
+
{ enabled: echoInput.length > 0 }
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const incrementMutation = trpc.counter.increment.useMutation({
|
|
37
|
+
onSuccess: () => counterQuery.refetch(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const decrementMutation = trpc.counter.decrement.useMutation({
|
|
41
|
+
onSuccess: () => counterQuery.refetch(),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const resetMutation = trpc.counter.reset.useMutation({
|
|
45
|
+
onSuccess: () => counterQuery.refetch(),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// ==========================================================================
|
|
49
|
+
// Database tRPC queries (requires Prisma)
|
|
50
|
+
// ==========================================================================
|
|
51
|
+
const itemsQuery = HAS_DATABASE ? trpc.items.list.useQuery() : null;
|
|
52
|
+
const statsQuery = HAS_DATABASE ? trpc.items.stats.useQuery() : null;
|
|
53
|
+
|
|
54
|
+
const createMutation = trpc.items.create.useMutation({
|
|
55
|
+
onSuccess: () => {
|
|
56
|
+
itemsQuery?.refetch();
|
|
57
|
+
statsQuery?.refetch();
|
|
58
|
+
setNewItemTitle('');
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const toggleMutation = trpc.items.toggle.useMutation({
|
|
63
|
+
onSuccess: () => {
|
|
64
|
+
itemsQuery?.refetch();
|
|
65
|
+
statsQuery?.refetch();
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const deleteMutation = trpc.items.delete.useMutation({
|
|
70
|
+
onSuccess: () => {
|
|
71
|
+
itemsQuery?.refetch();
|
|
72
|
+
statsQuery?.refetch();
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const isLoading = healthQuery.isLoading;
|
|
77
|
+
const hasError = healthQuery.isError;
|
|
78
|
+
|
|
79
|
+
const handleCreateItem = () => {
|
|
80
|
+
if (newItemTitle.trim()) {
|
|
81
|
+
createMutation.mutate({ title: newItemTitle.trim() });
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Screen background="primary" padding="lg" scrollable>
|
|
87
|
+
<View gap="lg">
|
|
88
|
+
{/* Header */}
|
|
89
|
+
<View gap="sm">
|
|
90
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
91
|
+
<Icon name="api" size={28} intent="primary" />
|
|
92
|
+
<Text typography="h3">tRPC Demo</Text>
|
|
93
|
+
</View>
|
|
94
|
+
<Text color="secondary">
|
|
95
|
+
Type-safe API calls with full end-to-end type safety
|
|
96
|
+
</Text>
|
|
97
|
+
</View>
|
|
98
|
+
|
|
99
|
+
{/* Loading State */}
|
|
100
|
+
{isLoading && (
|
|
101
|
+
<Card type="outlined" padding="lg">
|
|
102
|
+
<View style={{ alignItems: 'center', gap: 12 }}>
|
|
103
|
+
<ActivityIndicator size="lg" intent="primary" />
|
|
104
|
+
<Text color="secondary">Connecting to API...</Text>
|
|
105
|
+
</View>
|
|
106
|
+
</Card>
|
|
107
|
+
)}
|
|
108
|
+
|
|
109
|
+
{/* Error State */}
|
|
110
|
+
{hasError && (
|
|
111
|
+
<Alert intent="danger" title="Connection Error">
|
|
112
|
+
Could not connect to the API. Make sure the server is running.
|
|
113
|
+
</Alert>
|
|
114
|
+
)}
|
|
115
|
+
|
|
116
|
+
{/* ================================================================== */}
|
|
117
|
+
{/* SECTION 1: Base Routes (No Database Required) */}
|
|
118
|
+
{/* ================================================================== */}
|
|
119
|
+
|
|
120
|
+
<View gap="sm">
|
|
121
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
122
|
+
<Icon name="lightning-bolt" size={20} intent="warning" />
|
|
123
|
+
<Text typography="h5" weight="semibold">Base API Routes</Text>
|
|
124
|
+
<Badge intent="warning" size="sm">No Database</Badge>
|
|
125
|
+
</View>
|
|
126
|
+
<Text typography="caption" color="secondary">
|
|
127
|
+
These routes work without any database setup
|
|
128
|
+
</Text>
|
|
129
|
+
</View>
|
|
130
|
+
|
|
131
|
+
{/* Health Check */}
|
|
132
|
+
{healthQuery.data && (
|
|
133
|
+
<Card type="elevated" padding="md" gap="sm">
|
|
134
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
135
|
+
<Icon name="heart-pulse" size={20} intent="success" />
|
|
136
|
+
<Text weight="semibold">Health Check</Text>
|
|
137
|
+
<Badge intent="success" size="sm">
|
|
138
|
+
{healthQuery.data.status}
|
|
139
|
+
</Badge>
|
|
140
|
+
</View>
|
|
141
|
+
<Text typography="caption" color="secondary">
|
|
142
|
+
Version: {healthQuery.data.version} | {healthQuery.data.timestamp}
|
|
143
|
+
</Text>
|
|
144
|
+
</Card>
|
|
145
|
+
)}
|
|
146
|
+
|
|
147
|
+
{/* Echo Demo */}
|
|
148
|
+
<Card type="outlined" padding="md" gap="md" style={{ minHeight: 180 }}>
|
|
149
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
150
|
+
<Icon name="message-reply-text" size={20} intent="primary" />
|
|
151
|
+
<Text weight="semibold">Echo Endpoint</Text>
|
|
152
|
+
</View>
|
|
153
|
+
|
|
154
|
+
<TextInput
|
|
155
|
+
placeholder="Type a message to echo..."
|
|
156
|
+
value={echoInput}
|
|
157
|
+
onChangeText={setEchoInput}
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
<View
|
|
161
|
+
background="secondary"
|
|
162
|
+
padding="md"
|
|
163
|
+
radius="md"
|
|
164
|
+
gap="xs"
|
|
165
|
+
style={{ height: 80 }}
|
|
166
|
+
>
|
|
167
|
+
{echoQuery.data ? (
|
|
168
|
+
<>
|
|
169
|
+
<Text typography="caption" color="secondary" numberOfLines={1}>Original: {echoQuery.data.original}</Text>
|
|
170
|
+
<Text typography="caption" color="secondary" numberOfLines={1}>Reversed: {echoQuery.data.reversed}</Text>
|
|
171
|
+
<Text typography="caption" color="secondary">Length: {echoQuery.data.length}</Text>
|
|
172
|
+
</>
|
|
173
|
+
) : (
|
|
174
|
+
<Text typography="caption" color="secondary" style={{ opacity: 0.5 }}>
|
|
175
|
+
Type a message above to see the echo response...
|
|
176
|
+
</Text>
|
|
177
|
+
)}
|
|
178
|
+
</View>
|
|
179
|
+
</Card>
|
|
180
|
+
|
|
181
|
+
{/* Counter Demo */}
|
|
182
|
+
<Card type="outlined" padding="md" gap="md">
|
|
183
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
184
|
+
<Icon name="counter" size={20} intent="primary" />
|
|
185
|
+
<Text weight="semibold">In-Memory Counter</Text>
|
|
186
|
+
</View>
|
|
187
|
+
|
|
188
|
+
<View style={{ alignItems: 'center', gap: 12 }}>
|
|
189
|
+
<Text typography="h2" color="primary">
|
|
190
|
+
{counterQuery.data?.value ?? 0}
|
|
191
|
+
</Text>
|
|
192
|
+
|
|
193
|
+
<View style={{ flexDirection: 'row', gap: 8 }}>
|
|
194
|
+
<Button
|
|
195
|
+
size="sm"
|
|
196
|
+
intent="danger"
|
|
197
|
+
leftIcon="minus"
|
|
198
|
+
onPress={() => decrementMutation.mutate()}
|
|
199
|
+
disabled={decrementMutation.isPending}
|
|
200
|
+
>
|
|
201
|
+
-1
|
|
202
|
+
</Button>
|
|
203
|
+
<Button
|
|
204
|
+
size="sm"
|
|
205
|
+
intent="neutral"
|
|
206
|
+
leftIcon="refresh"
|
|
207
|
+
onPress={() => resetMutation.mutate()}
|
|
208
|
+
disabled={resetMutation.isPending}
|
|
209
|
+
>
|
|
210
|
+
Reset
|
|
211
|
+
</Button>
|
|
212
|
+
<Button
|
|
213
|
+
size="sm"
|
|
214
|
+
intent="success"
|
|
215
|
+
leftIcon="plus"
|
|
216
|
+
onPress={() => incrementMutation.mutate()}
|
|
217
|
+
disabled={incrementMutation.isPending}
|
|
218
|
+
>
|
|
219
|
+
+1
|
|
220
|
+
</Button>
|
|
221
|
+
</View>
|
|
222
|
+
</View>
|
|
223
|
+
|
|
224
|
+
<Text typography="caption" color="secondary" style={{ textAlign: 'center' }}>
|
|
225
|
+
Server-side state - persists across page refreshes but resets on server restart
|
|
226
|
+
</Text>
|
|
227
|
+
</Card>
|
|
228
|
+
|
|
229
|
+
{/* ================================================================== */}
|
|
230
|
+
{/* SECTION 2: Database Routes (Requires Prisma) */}
|
|
231
|
+
{/* ================================================================== */}
|
|
232
|
+
|
|
233
|
+
{HAS_DATABASE && (
|
|
234
|
+
<>
|
|
235
|
+
<Divider />
|
|
236
|
+
|
|
237
|
+
<View gap="sm">
|
|
238
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
239
|
+
<Icon name="database" size={20} intent="success" />
|
|
240
|
+
<Text typography="h5" weight="semibold">Database Routes</Text>
|
|
241
|
+
<Badge intent="success" size="sm">Prisma</Badge>
|
|
242
|
+
</View>
|
|
243
|
+
<Text typography="caption" color="secondary">
|
|
244
|
+
Full CRUD operations with persistent database storage
|
|
245
|
+
</Text>
|
|
246
|
+
</View>
|
|
247
|
+
|
|
248
|
+
{/* Stats */}
|
|
249
|
+
{statsQuery?.data && (
|
|
250
|
+
<Card type="outlined" padding="md" gap="md">
|
|
251
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
252
|
+
<Icon name="chart-bar" size={20} intent="primary" />
|
|
253
|
+
<Text weight="semibold">Item Statistics</Text>
|
|
254
|
+
</View>
|
|
255
|
+
|
|
256
|
+
<View style={{ flexDirection: 'row', gap: 12 }}>
|
|
257
|
+
<View
|
|
258
|
+
background="secondary"
|
|
259
|
+
padding="md"
|
|
260
|
+
radius="md"
|
|
261
|
+
style={{ flex: 1, alignItems: 'center' }}
|
|
262
|
+
>
|
|
263
|
+
<Text typography="h4">{statsQuery.data.total}</Text>
|
|
264
|
+
<Text typography="caption" color="secondary">
|
|
265
|
+
Total
|
|
266
|
+
</Text>
|
|
267
|
+
</View>
|
|
268
|
+
<View
|
|
269
|
+
background="secondary"
|
|
270
|
+
padding="md"
|
|
271
|
+
radius="md"
|
|
272
|
+
style={{ flex: 1, alignItems: 'center' }}
|
|
273
|
+
>
|
|
274
|
+
<Text typography="h4" color="success">
|
|
275
|
+
{statsQuery.data.completed}
|
|
276
|
+
</Text>
|
|
277
|
+
<Text typography="caption" color="secondary">
|
|
278
|
+
Completed
|
|
279
|
+
</Text>
|
|
280
|
+
</View>
|
|
281
|
+
<View
|
|
282
|
+
background="secondary"
|
|
283
|
+
padding="md"
|
|
284
|
+
radius="md"
|
|
285
|
+
style={{ flex: 1, alignItems: 'center' }}
|
|
286
|
+
>
|
|
287
|
+
<Text typography="h4" color="warning">
|
|
288
|
+
{statsQuery.data.pending}
|
|
289
|
+
</Text>
|
|
290
|
+
<Text typography="caption" color="secondary">
|
|
291
|
+
Pending
|
|
292
|
+
</Text>
|
|
293
|
+
</View>
|
|
294
|
+
</View>
|
|
295
|
+
</Card>
|
|
296
|
+
)}
|
|
297
|
+
|
|
298
|
+
{/* Create Item */}
|
|
299
|
+
<Card type="elevated" padding="md" gap="md">
|
|
300
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
301
|
+
<Icon name="plus-circle" size={20} intent="success" />
|
|
302
|
+
<Text weight="semibold">Create Item</Text>
|
|
303
|
+
</View>
|
|
304
|
+
|
|
305
|
+
<TextInput
|
|
306
|
+
placeholder="Enter item title..."
|
|
307
|
+
value={newItemTitle}
|
|
308
|
+
onChangeText={setNewItemTitle}
|
|
309
|
+
/>
|
|
310
|
+
|
|
311
|
+
<Button
|
|
312
|
+
intent="primary"
|
|
313
|
+
leftIcon="plus"
|
|
314
|
+
onPress={handleCreateItem}
|
|
315
|
+
disabled={!newItemTitle.trim() || createMutation.isPending}
|
|
316
|
+
>
|
|
317
|
+
{createMutation.isPending ? 'Creating...' : 'Add Item'}
|
|
318
|
+
</Button>
|
|
319
|
+
</Card>
|
|
320
|
+
|
|
321
|
+
{/* Items List */}
|
|
322
|
+
{itemsQuery?.data && itemsQuery.data.length > 0 && (
|
|
323
|
+
<Card type="outlined" padding="md" gap="md">
|
|
324
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
|
|
325
|
+
<Icon name="format-list-checks" size={20} intent="primary" />
|
|
326
|
+
<Text weight="semibold">Items</Text>
|
|
327
|
+
<Badge intent="primary" size="sm">
|
|
328
|
+
{itemsQuery.data.length}
|
|
329
|
+
</Badge>
|
|
330
|
+
</View>
|
|
331
|
+
|
|
332
|
+
<View gap="sm">
|
|
333
|
+
{itemsQuery.data.map((item: { id: string; title: string; description?: string | null; completed: boolean }) => (
|
|
334
|
+
<View
|
|
335
|
+
key={item.id}
|
|
336
|
+
background="secondary"
|
|
337
|
+
padding="sm"
|
|
338
|
+
radius="sm"
|
|
339
|
+
style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
|
|
340
|
+
>
|
|
341
|
+
<Button
|
|
342
|
+
size="sm"
|
|
343
|
+
intent={item.completed ? 'success' : 'neutral'}
|
|
344
|
+
leftIcon={item.completed ? 'check-circle' : 'circle-outline'}
|
|
345
|
+
onPress={() => toggleMutation.mutate({ id: item.id })}
|
|
346
|
+
/>
|
|
347
|
+
<View style={{ flex: 1 }}>
|
|
348
|
+
<Text
|
|
349
|
+
weight="medium"
|
|
350
|
+
style={{
|
|
351
|
+
textDecorationLine: item.completed ? 'line-through' : 'none',
|
|
352
|
+
opacity: item.completed ? 0.6 : 1,
|
|
353
|
+
}}
|
|
354
|
+
>
|
|
355
|
+
{item.title}
|
|
356
|
+
</Text>
|
|
357
|
+
{item.description && (
|
|
358
|
+
<Text typography="caption" color="secondary">
|
|
359
|
+
{item.description}
|
|
360
|
+
</Text>
|
|
361
|
+
)}
|
|
362
|
+
</View>
|
|
363
|
+
<Button
|
|
364
|
+
size="sm"
|
|
365
|
+
intent="danger"
|
|
366
|
+
leftIcon="delete"
|
|
367
|
+
onPress={() => deleteMutation.mutate({ id: item.id })}
|
|
368
|
+
/>
|
|
369
|
+
</View>
|
|
370
|
+
))}
|
|
371
|
+
</View>
|
|
372
|
+
</Card>
|
|
373
|
+
)}
|
|
374
|
+
|
|
375
|
+
{/* Empty State */}
|
|
376
|
+
{itemsQuery?.data && itemsQuery.data.length === 0 && (
|
|
377
|
+
<Card type="outlined" padding="lg">
|
|
378
|
+
<View style={{ alignItems: 'center', gap: 8 }}>
|
|
379
|
+
<Icon name="inbox-outline" size={48} textColor="secondary" />
|
|
380
|
+
<Text color="secondary">No items yet. Create one above!</Text>
|
|
381
|
+
</View>
|
|
382
|
+
</Card>
|
|
383
|
+
)}
|
|
384
|
+
</>
|
|
385
|
+
)}
|
|
386
|
+
|
|
387
|
+
{/* Refetch Button */}
|
|
388
|
+
<Button
|
|
389
|
+
intent="primary"
|
|
390
|
+
leftIcon="refresh"
|
|
391
|
+
onPress={() => {
|
|
392
|
+
healthQuery.refetch();
|
|
393
|
+
counterQuery.refetch();
|
|
394
|
+
if (echoInput) echoQuery.refetch();
|
|
395
|
+
if (HAS_DATABASE) {
|
|
396
|
+
itemsQuery?.refetch();
|
|
397
|
+
statsQuery?.refetch();
|
|
398
|
+
}
|
|
399
|
+
}}
|
|
400
|
+
>
|
|
401
|
+
Refetch All Data
|
|
402
|
+
</Button>
|
|
403
|
+
|
|
404
|
+
{/* Code Example */}
|
|
405
|
+
<Card type="outlined" padding="md" gap="sm">
|
|
406
|
+
<Text weight="semibold">tRPC Usage Examples</Text>
|
|
407
|
+
<View background="secondary" padding="md" radius="sm">
|
|
408
|
+
<Text
|
|
409
|
+
typography="caption"
|
|
410
|
+
style={{ fontFamily: 'monospace', lineHeight: 20 }}
|
|
411
|
+
>
|
|
412
|
+
{`// Query with full type inference
|
|
413
|
+
const { data } = trpc.health.useQuery();
|
|
414
|
+
const counter = trpc.counter.get.useQuery();
|
|
415
|
+
|
|
416
|
+
// Mutations
|
|
417
|
+
trpc.counter.increment.useMutation();
|
|
418
|
+
trpc.echo.useQuery({ message: 'hello' });${HAS_DATABASE ? `
|
|
419
|
+
|
|
420
|
+
// Database operations (with Prisma)
|
|
421
|
+
const items = trpc.items.list.useQuery();
|
|
422
|
+
trpc.items.create.useMutation();
|
|
423
|
+
trpc.items.toggle.useMutation();` : ''}`}
|
|
424
|
+
</Text>
|
|
425
|
+
</View>
|
|
426
|
+
</Card>
|
|
427
|
+
</View>
|
|
428
|
+
</Screen>
|
|
429
|
+
);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
export default TRPCDemoScreen;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
|
2
|
+
import { createTRPCReact } from '@trpc/react-query';
|
|
3
|
+
import type { AppRouter } from '@{{workspaceScope}}/api';
|
|
4
|
+
|
|
5
|
+
// Create the tRPC React hooks with full type safety
|
|
6
|
+
export const trpc: ReturnType<typeof createTRPCReact<AppRouter>> =
|
|
7
|
+
createTRPCReact<AppRouter>();
|
|
8
|
+
|
|
9
|
+
// Configuration for tRPC client
|
|
10
|
+
export interface TRPCClientConfig {
|
|
11
|
+
apiUrl: string;
|
|
12
|
+
headers?: () => Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Create tRPC client factory
|
|
16
|
+
export function createTRPCClient(
|
|
17
|
+
config: TRPCClientConfig
|
|
18
|
+
): ReturnType<typeof trpc.createClient> {
|
|
19
|
+
return trpc.createClient({
|
|
20
|
+
links: [
|
|
21
|
+
httpBatchLink({
|
|
22
|
+
url: config.apiUrl,
|
|
23
|
+
headers: config.headers,
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Create a vanilla client (for use outside of React components)
|
|
30
|
+
export function createVanillaTRPCClient(
|
|
31
|
+
config: TRPCClientConfig
|
|
32
|
+
): ReturnType<typeof createTRPCProxyClient<AppRouter>> {
|
|
33
|
+
return createTRPCProxyClient<AppRouter>({
|
|
34
|
+
links: [
|
|
35
|
+
httpBatchLink({
|
|
36
|
+
url: config.apiUrl,
|
|
37
|
+
headers: config.headers,
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Export types
|
|
44
|
+
export type { AppRouter } from '@{{workspaceScope}}/api';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Constants and default values for the CLI
|
|
3
3
|
*/
|
|
4
4
|
export declare const VERSION = "0.1.0";
|
|
5
|
-
export declare const IDEALYST_VERSION = "1.2.
|
|
5
|
+
export declare const IDEALYST_VERSION = "1.2.33";
|
|
6
6
|
export declare const REACT_NATIVE_VERSION = "0.83.0";
|
|
7
7
|
export declare const REACT_VERSION = "19.1.0";
|
|
8
8
|
export declare const DEFAULT_TIMEOUT = 300000;
|
|
@@ -18,9 +18,9 @@ export declare const TEMPLATE_EXTENSIONS: readonly [".ts", ".tsx", ".js", ".jsx"
|
|
|
18
18
|
export declare const IGNORE_PATTERNS: readonly ["node_modules", ".git", "dist", "build", ".cache", ".DS_Store", "Thumbs.db", "*.log", "*.tmp", "*.bak", "~*"];
|
|
19
19
|
export declare const DEPENDENCIES: {
|
|
20
20
|
readonly core: {
|
|
21
|
-
readonly '@idealyst/components': "^1.2.
|
|
22
|
-
readonly '@idealyst/theme': "^1.2.
|
|
23
|
-
readonly '@idealyst/navigation': "^1.2.
|
|
21
|
+
readonly '@idealyst/components': "^1.2.33";
|
|
22
|
+
readonly '@idealyst/theme': "^1.2.33";
|
|
23
|
+
readonly '@idealyst/navigation': "^1.2.33";
|
|
24
24
|
};
|
|
25
25
|
readonly web: {
|
|
26
26
|
readonly '@mdi/js': "^7.4.47";
|
|
@@ -60,12 +60,16 @@ export declare const DEPENDENCIES: {
|
|
|
60
60
|
};
|
|
61
61
|
readonly graphql: {
|
|
62
62
|
readonly '@apollo/client': "^3.11.0";
|
|
63
|
+
readonly '@tanstack/react-query': "^5.62.0";
|
|
63
64
|
readonly graphql: "^16.9.0";
|
|
64
65
|
};
|
|
65
66
|
readonly graphqlServer: {
|
|
66
67
|
readonly '@pothos/core': "^4.3.0";
|
|
67
68
|
readonly 'graphql-yoga': "^5.10.0";
|
|
68
69
|
};
|
|
70
|
+
readonly graphqlServerPrisma: {
|
|
71
|
+
readonly '@pothos/plugin-prisma': "^4.3.0";
|
|
72
|
+
};
|
|
69
73
|
readonly prisma: {
|
|
70
74
|
readonly '@prisma/client': "^5.19.0";
|
|
71
75
|
};
|
|
@@ -73,7 +77,7 @@ export declare const DEPENDENCIES: {
|
|
|
73
77
|
readonly prisma: "^5.19.0";
|
|
74
78
|
};
|
|
75
79
|
readonly tooling: {
|
|
76
|
-
readonly '@idealyst/tooling': "^1.2.
|
|
80
|
+
readonly '@idealyst/tooling': "^1.2.33";
|
|
77
81
|
};
|
|
78
82
|
readonly api: {
|
|
79
83
|
readonly express: "^4.21.0";
|
package/package.json
CHANGED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { NavigatorProvider } from '@idealyst/navigation';
|
|
3
|
-
import { AppRouter } from '../navigation/AppRouter';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Main App component for the {{appDisplayName}}
|
|
7
|
-
* Sets up navigation with the AppRouter
|
|
8
|
-
*/
|
|
9
|
-
export const App: React.FC = () => {
|
|
10
|
-
return <NavigatorProvider route={AppRouter} />;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default App;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|