create-better-t-stack 2.2.4 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/index.js +21 -29
  2. package/package.json +1 -1
  3. package/templates/addons/turborepo/{turbo.json → turbo.json.hbs} +7 -1
  4. package/templates/api/orpc/server/base/src/lib/context.ts.hbs +0 -2
  5. package/templates/auth/web/nuxt/app/components/SignInForm.vue +0 -1
  6. package/templates/auth/web/nuxt/app/components/SignUpForm.vue +0 -1
  7. package/templates/auth/web/nuxt/app/components/UserMenu.vue +0 -1
  8. package/templates/backend/convex/packages/backend/_gitignore +2 -0
  9. package/templates/backend/convex/packages/backend/convex/README.md +90 -0
  10. package/templates/backend/convex/packages/backend/convex/healthCheck.ts +7 -0
  11. package/templates/backend/convex/packages/backend/convex/schema.ts +9 -0
  12. package/templates/backend/convex/packages/backend/convex/todos.ts +42 -0
  13. package/templates/backend/convex/packages/backend/convex/tsconfig.json +25 -0
  14. package/templates/backend/convex/packages/backend/package.json.hbs +21 -0
  15. package/templates/base/package.json +2 -1
  16. package/templates/examples/todo/web/react/react-router/src/routes/todos.tsx.hbs +178 -93
  17. package/templates/examples/todo/web/react/tanstack-router/src/routes/todos.tsx.hbs +178 -92
  18. package/templates/examples/todo/web/react/tanstack-start/src/routes/todos.tsx.hbs +119 -18
  19. package/templates/examples/todo/web/svelte/src/routes/todos/+page.svelte.hbs +357 -0
  20. package/templates/extras/pnpm-workspace.yaml +1 -0
  21. package/templates/frontend/native/app/(drawer)/index.tsx.hbs +35 -7
  22. package/templates/frontend/native/app/_layout.tsx.hbs +27 -0
  23. package/templates/frontend/react/next/package.json +0 -2
  24. package/templates/frontend/react/next/src/app/page.tsx.hbs +26 -44
  25. package/templates/frontend/react/next/src/components/providers.tsx.hbs +15 -3
  26. package/templates/frontend/react/react-router/package.json +0 -2
  27. package/templates/frontend/react/react-router/src/root.tsx.hbs +31 -11
  28. package/templates/frontend/react/react-router/src/routes/_index.tsx.hbs +28 -47
  29. package/templates/frontend/react/tanstack-router/package.json +0 -2
  30. package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +18 -2
  31. package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +24 -1
  32. package/templates/frontend/react/tanstack-router/src/routes/index.tsx.hbs +24 -39
  33. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +57 -13
  34. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +12 -10
  35. package/templates/frontend/react/tanstack-start/src/routes/index.tsx.hbs +31 -45
  36. package/templates/frontend/svelte/src/routes/+layout.svelte.hbs +24 -0
  37. package/templates/frontend/svelte/src/routes/+page.svelte.hbs +59 -1
  38. package/templates/examples/todo/web/svelte/src/routes/todos/+page.svelte +0 -150
  39. /package/templates/backend/{elysia → server/elysia}/src/index.ts.hbs +0 -0
  40. /package/templates/backend/{express → server/express}/src/index.ts.hbs +0 -0
  41. /package/templates/backend/{hono → server/hono}/src/index.ts.hbs +0 -0
  42. /package/templates/backend/{next → server/next}/next-env.d.ts +0 -0
  43. /package/templates/backend/{next → server/next}/next.config.ts +0 -0
  44. /package/templates/backend/{next → server/next}/package.json +0 -0
  45. /package/templates/backend/{next → server/next}/src/app/route.ts +0 -0
  46. /package/templates/backend/{next → server/next}/src/middleware.ts +0 -0
  47. /package/templates/backend/{next → server/next}/tsconfig.json +0 -0
  48. /package/templates/backend/{server-base → server/server-base}/_gitignore +0 -0
  49. /package/templates/backend/{server-base → server/server-base}/package.json +0 -0
  50. /package/templates/backend/{server-base → server/server-base}/src/routers/index.ts.hbs +0 -0
  51. /package/templates/backend/{server-base → server/server-base}/tsconfig.json.hbs +0 -0
@@ -1,8 +1,65 @@
1
+ {{#if (eq backend "convex")}}
1
2
  <script lang="ts">
3
+ import { useQuery } from 'convex-svelte';
4
+ import { api } from "@{{projectName}}/backend/convex/_generated/api.js";
5
+
6
+
7
+ const healthCheck = useQuery(api.healthCheck.get, {});
8
+
9
+
10
+ const TITLE_TEXT = `
11
+ ██████╗ ███████╗████████╗████████╗███████╗██████╗
12
+ ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗
13
+ ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝
14
+ ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗
15
+ ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║
16
+ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
17
+
18
+ ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗
19
+ ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝
20
+ ██║ ███████╗ ██║ ███████║██║ █████╔╝
21
+ ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗
22
+ ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗
23
+ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
24
+ `;
25
+ </script>
26
+
27
+ <div class="container mx-auto max-w-3xl px-4 py-2">
28
+ <pre class="overflow-x-auto font-mono text-sm">{TITLE_TEXT}</pre>
29
+ <div class="grid gap-6">
30
+ <section class="rounded-lg border p-4">
31
+ <h2 class="mb-2 font-medium">API Status (Convex)</h2>
32
+ <div class="flex items-center gap-2">
33
+ <div
34
+ class={`h-2 w-2 rounded-full ${healthCheck.data ? "bg-green-500" : "bg-red-500"}`}
35
+ ></div>
36
+ <span class="text-muted-foreground text-sm">
37
+ {healthCheck.isLoading
38
+ ? "Checking..."
39
+ : healthCheck.data
40
+ ? "Connected"
41
+ : "Disconnected"}
42
+ </span>
43
+ </div>
44
+ </section>
45
+ </div>
46
+ </div>
47
+ {{else}}
48
+ <script lang="ts">
49
+ {{#if (eq api "orpc")}}
2
50
  import { orpc } from "$lib/orpc";
51
+ {{/if}}
52
+ {{#if (eq api "trpc")}}
53
+ import { trpc } from "$lib/trpc";
54
+ {{/if}}
3
55
  import { createQuery } from "@tanstack/svelte-query";
4
56
 
57
+ {{#if (eq api "orpc")}}
5
58
  const healthCheck = createQuery(orpc.healthCheck.queryOptions());
59
+ {{/if}}
60
+ {{#if (eq api "trpc")}}
61
+ const healthCheck = createQuery(trpc.healthCheck.queryOptions());
62
+ {{/if}}
6
63
 
7
64
 
8
65
  const TITLE_TEXT = `
@@ -26,7 +83,7 @@ const TITLE_TEXT = `
26
83
  <pre class="overflow-x-auto font-mono text-sm">{TITLE_TEXT}</pre>
27
84
  <div class="grid gap-6">
28
85
  <section class="rounded-lg border p-4">
29
- <h2 class="mb-2 font-medium">API Status</h2>
86
+ <h2 class="mb-2 font-medium">API Status{{#if (eq api "trpc")}} (tRPC){{/if}}{{#if (eq api "orpc")}} (oRPC){{/if}}</h2>
30
87
  <div class="flex items-center gap-2">
31
88
  <div
32
89
  class={`h-2 w-2 rounded-full ${$healthCheck.data ? "bg-green-500" : "bg-red-500"}`}
@@ -42,3 +99,4 @@ const TITLE_TEXT = `
42
99
  </section>
43
100
  </div>
44
101
  </div>
102
+ {{/if}}
@@ -1,150 +0,0 @@
1
- <script lang="ts">
2
- import { orpc } from '$lib/orpc';
3
- import { createQuery, createMutation } from '@tanstack/svelte-query';
4
-
5
- let newTodoText = $state('');
6
-
7
- const todosQuery = createQuery(orpc.todo.getAll.queryOptions());
8
-
9
- const addMutation = createMutation(
10
- orpc.todo.create.mutationOptions({
11
- onSuccess: () => {
12
- $todosQuery.refetch();
13
- newTodoText = '';
14
- },
15
- onError: (error) => {
16
- console.error('Failed to create todo:', error?.message ?? error);
17
- },
18
- })
19
- );
20
-
21
- const toggleMutation = createMutation(
22
- orpc.todo.toggle.mutationOptions({
23
- onSuccess: () => {
24
- $todosQuery.refetch();
25
- },
26
- onError: (error) => {
27
- console.error('Failed to toggle todo:', error?.message ?? error);
28
- },
29
- })
30
- );
31
-
32
- const deleteMutation = createMutation(
33
- orpc.todo.delete.mutationOptions({
34
- onSuccess: () => {
35
- $todosQuery.refetch();
36
- },
37
- onError: (error) => {
38
- console.error('Failed to delete todo:', error?.message ?? error);
39
- },
40
- })
41
- );
42
-
43
- function handleAddTodo(event: SubmitEvent) {
44
- event.preventDefault();
45
- const text = newTodoText.trim();
46
- if (text) {
47
- $addMutation.mutate({ text });
48
- }
49
- }
50
-
51
- function handleToggleTodo(id: number, completed: boolean) {
52
- $toggleMutation.mutate({ id, completed: !completed });
53
- }
54
-
55
- function handleDeleteTodo(id: number) {
56
- $deleteMutation.mutate({ id });
57
- }
58
-
59
- const isAdding = $derived($addMutation.isPending);
60
- const canAdd = $derived(!isAdding && newTodoText.trim().length > 0);
61
- const isLoadingTodos = $derived($todosQuery.isLoading);
62
- const todos = $derived($todosQuery.data ?? []);
63
- const hasTodos = $derived(todos.length > 0);
64
-
65
- </script>
66
-
67
- <div class="p-4">
68
- <h1 class="text-xl mb-4">Todos</h1>
69
-
70
- <form onsubmit={handleAddTodo} class="flex gap-2 mb-4">
71
- <input
72
- type="text"
73
- bind:value={newTodoText}
74
- placeholder="New task..."
75
- disabled={isAdding}
76
- class=" p-1 flex-grow"
77
- />
78
- <button
79
- type="submit"
80
- disabled={!canAdd}
81
- class="bg-blue-500 text-white px-3 py-1 rounded disabled:opacity-50"
82
- >
83
- {#if isAdding}Adding...{:else}Add{/if}
84
- </button>
85
- </form>
86
-
87
- {#if isLoadingTodos}
88
- <p>Loading...</p>
89
- {:else if !hasTodos}
90
- <p>No todos yet.</p>
91
- {:else}
92
- <ul class="space-y-1">
93
- {#each todos as todo (todo.id)}
94
- {@const isToggling = $toggleMutation.isPending && $toggleMutation.variables?.id === todo.id}
95
- {@const isDeleting = $deleteMutation.isPending && $deleteMutation.variables?.id === todo.id}
96
- {@const isDisabled = isToggling || isDeleting}
97
- <li
98
- class="flex items-center justify-between p-2 "
99
- class:opacity-50={isDisabled}
100
- >
101
- <div class="flex items-center gap-2">
102
- <input
103
- type="checkbox"
104
- id={`todo-${todo.id}`}
105
- checked={todo.completed}
106
- onchange={() => handleToggleTodo(todo.id, todo.completed)}
107
- disabled={isDisabled}
108
- />
109
- <label
110
- for={`todo-${todo.id}`}
111
- class:line-through={todo.completed}
112
- >
113
- {todo.text}
114
- </label>
115
- </div>
116
- <button
117
- type="button"
118
- onclick={() => handleDeleteTodo(todo.id)}
119
- disabled={isDisabled}
120
- aria-label="Delete todo"
121
- class="text-red-500 px-1 disabled:opacity-50"
122
- >
123
- {#if isDeleting}Deleting...{:else}X{/if}
124
- </button>
125
- </li>
126
- {/each}
127
- </ul>
128
- {/if}
129
-
130
- {#if $todosQuery.isError}
131
- <p class="mt-4 text-red-500">
132
- Error loading: {$todosQuery.error?.message ?? 'Unknown error'}
133
- </p>
134
- {/if}
135
- {#if $addMutation.isError}
136
- <p class="mt-4 text-red-500">
137
- Error adding: {$addMutation.error?.message ?? 'Unknown error'}
138
- </p>
139
- {/if}
140
- {#if $toggleMutation.isError}
141
- <p class="mt-4 text-red-500">
142
- Error updating: {$toggleMutation.error?.message ?? 'Unknown error'}
143
- </p>
144
- {/if}
145
- {#if $deleteMutation.isError}
146
- <p class="mt-4 text-red-500">
147
- Error deleting: {$deleteMutation.error?.message ?? 'Unknown error'}
148
- </p>
149
- {/if}
150
- </div>