@flaredev/cli 0.1.2 → 0.3.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 (89) hide show
  1. package/bin/flare.js +9 -1
  2. package/dist/index.js +985 -337
  3. package/package.json +3 -2
  4. package/templates/app/app/admin/page.tsx +9 -61
  5. package/templates/app/app/api/openapi.json/route.ts +23 -0
  6. package/templates/app/app/api/reference/route.ts +36 -0
  7. package/templates/app/app/dashboard/account/page.tsx +40 -0
  8. package/templates/app/app/{admin → dashboard}/actions.ts +109 -11
  9. package/templates/app/app/dashboard/import-actions.ts +91 -0
  10. package/templates/app/app/dashboard/layout.tsx +42 -0
  11. package/templates/app/app/dashboard/observability/page.tsx +174 -0
  12. package/templates/app/app/dashboard/page.tsx +123 -9
  13. package/templates/app/app/forgot-password/page.tsx +22 -0
  14. package/templates/app/app/globals.css +109 -4
  15. package/templates/app/app/layout.tsx +28 -26
  16. package/templates/app/app/page.tsx +126 -13
  17. package/templates/app/app/reset-password/page.tsx +31 -0
  18. package/templates/app/app/sign-in/page.tsx +49 -33
  19. package/templates/app/app/sign-up/page.tsx +42 -23
  20. package/templates/app/app/two-factor/page.tsx +25 -0
  21. package/templates/app/app/verify-email/page.tsx +33 -0
  22. package/templates/app/components/account/security-settings.tsx +522 -0
  23. package/templates/app/components/auth/auth-shell.tsx +284 -0
  24. package/templates/app/components/auth/otp-input.tsx +95 -0
  25. package/templates/app/components/auth/password-field.tsx +116 -0
  26. package/templates/app/components/auth/password-forms.tsx +76 -0
  27. package/templates/app/components/auth/provider-icons.tsx +39 -0
  28. package/templates/app/components/auth/sign-in-flow.tsx +306 -0
  29. package/templates/app/components/auth/sign-up-form.tsx +93 -0
  30. package/templates/app/components/auth/social-buttons.tsx +56 -0
  31. package/templates/app/components/auth/two-factor-form.tsx +139 -0
  32. package/templates/app/components/auth/ui.tsx +96 -0
  33. package/templates/app/components/auth/use-resend.ts +44 -0
  34. package/templates/app/components/auth/verify-email-form.tsx +135 -0
  35. package/templates/app/components/{admin/admin-header.tsx → dashboard/dashboard-header.tsx} +78 -78
  36. package/templates/app/components/{admin/resource-nav.tsx → dashboard/dashboard-sidebar.tsx} +66 -9
  37. package/templates/app/components/dashboard/export-button.tsx +41 -0
  38. package/templates/app/components/dashboard/fields/country-field.tsx +152 -0
  39. package/templates/app/components/{admin → dashboard}/fields/field-widget.tsx +186 -128
  40. package/templates/app/components/{admin → dashboard}/fields/file-field.tsx +302 -302
  41. package/templates/app/components/dashboard/fields/multi-select-field.tsx +46 -0
  42. package/templates/app/components/dashboard/fields/phone-field.tsx +86 -0
  43. package/templates/app/components/dashboard/import-dialog.tsx +487 -0
  44. package/templates/app/components/dashboard/page-header.tsx +57 -0
  45. package/templates/app/components/dashboard/resource-form-dialog.tsx +80 -0
  46. package/templates/app/components/{admin → dashboard}/resource-form-page.tsx +61 -55
  47. package/templates/app/components/{admin → dashboard}/resource-form.tsx +165 -139
  48. package/templates/app/components/dashboard/resource-stats.tsx +53 -0
  49. package/templates/app/components/{admin → dashboard}/resource-table.tsx +331 -251
  50. package/templates/app/components/{admin → dashboard}/row-actions.tsx +144 -111
  51. package/templates/app/components/dashboard/stat-card.tsx +69 -0
  52. package/templates/app/components/dashboard/table-selection.tsx +185 -0
  53. package/templates/app/components/dashboard/traffic-chart.tsx +32 -0
  54. package/templates/app/components/marketing/product-preview.tsx +70 -0
  55. package/templates/app/components/marketing/site-header.tsx +39 -0
  56. package/templates/app/components/sign-out-button.tsx +1 -1
  57. package/templates/app/components/ui/checkbox.tsx +25 -0
  58. package/templates/app/components/ui/radio-group.tsx +29 -0
  59. package/templates/app/db/auth-schema.ts +167 -118
  60. package/templates/app/db/flare-schema.ts +33 -1
  61. package/templates/app/lib/analytics.ts +121 -0
  62. package/templates/app/lib/api-docs.ts +16 -0
  63. package/templates/app/lib/audit.ts +80 -0
  64. package/templates/app/lib/auth-client.ts +16 -1
  65. package/templates/app/lib/auth-config.ts +38 -0
  66. package/templates/app/lib/auth-emails.ts +94 -0
  67. package/templates/app/lib/auth.ts +115 -6
  68. package/templates/app/lib/cache.ts +83 -83
  69. package/templates/app/lib/csv.ts +24 -0
  70. package/templates/app/lib/dashboard-nav.ts +15 -0
  71. package/templates/app/lib/{admin.ts → dashboard.ts} +138 -103
  72. package/templates/app/lib/password-rules.ts +159 -0
  73. package/templates/app/lib/site.ts +56 -0
  74. package/templates/app/lib/theme.ts +79 -0
  75. package/templates/app/migrations/0000_init.sql +47 -4
  76. package/templates/app/migrations/meta/0000_snapshot.json +311 -1
  77. package/templates/app/migrations/meta/_journal.json +1 -1
  78. package/templates/app/vite.config.ts +5 -3
  79. package/templates/app/worker-configuration.d.ts +15764 -0
  80. package/templates/locks/package-lock.json +9189 -0
  81. package/templates/locks/pnpm-lock.yaml +6347 -0
  82. package/templates/app/app/admin/layout.tsx +0 -32
  83. package/templates/app/components/auth-form.tsx +0 -120
  84. package/templates/app/lib/admin-nav.ts +0 -15
  85. /package/templates/app/components/{admin → dashboard}/fields/date-field.tsx +0 -0
  86. /package/templates/app/components/{admin → dashboard}/fields/relation-field.tsx +0 -0
  87. /package/templates/app/components/{admin → dashboard}/query.ts +0 -0
  88. /package/templates/app/components/{admin → dashboard}/resource-icon.tsx +0 -0
  89. /package/templates/app/components/{admin → dashboard}/resource-table-toolbar.tsx +0 -0
@@ -1,32 +0,0 @@
1
- import { cookies } from "next/headers";
2
- import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
3
- import { Toaster } from "@/components/ui/sonner";
4
- import { AdminHeader, type Theme } from "@/components/admin/admin-header";
5
- import { ResourceNav } from "@/components/admin/resource-nav";
6
- import { adminLinks } from "@/lib/admin-nav";
7
- import { requireAdmin, visibleResources } from "@/lib/admin";
8
-
9
- export default async function AdminLayout({ children }: { children: React.ReactNode }) {
10
- const { session } = await requireAdmin();
11
- const jar = await cookies();
12
- const theme = (jar.get("flare-theme")?.value ?? "system") as Theme;
13
- const collapsed = jar.get("sidebar_state")?.value === "false";
14
-
15
- const resources = (await visibleResources()).map((resource) => ({
16
- name: resource.name,
17
- pluralLabel: resource.pluralLabel,
18
- slug: resource.slug,
19
- icon: resource.icon,
20
- }));
21
-
22
- return (
23
- <SidebarProvider defaultOpen={!collapsed}>
24
- <ResourceNav appName="__APP_NAME__" resources={resources} links={adminLinks} />
25
- <SidebarInset>
26
- <AdminHeader user={{ name: session.user.name, email: session.user.email }} initialTheme={theme} />
27
- <main className="flex-1 p-6 md:p-8">{children}</main>
28
- </SidebarInset>
29
- <Toaster theme={theme} />
30
- </SidebarProvider>
31
- );
32
- }
@@ -1,120 +0,0 @@
1
- "use client";
2
-
3
- import { useState, type FormEvent } from "react";
4
- import { authClient } from "@/lib/auth-client";
5
-
6
- const PROVIDER_LABELS: Record<string, string> = { google: "Google", github: "GitHub" };
7
-
8
- const inputClass =
9
- "w-full rounded-md border border-[var(--border)] bg-transparent px-3 py-2 text-sm outline-none focus:border-[var(--foreground)]";
10
-
11
- export function AuthForm({
12
- mode,
13
- next,
14
- socialProviders = [],
15
- initialError = null,
16
- }: {
17
- mode: "sign-in" | "sign-up";
18
- next: string;
19
- socialProviders?: string[];
20
- initialError?: string | null;
21
- }) {
22
- const [error, setError] = useState<string | null>(initialError);
23
- const [pending, setPending] = useState(false);
24
-
25
- async function onSubmit(event: FormEvent<HTMLFormElement>) {
26
- event.preventDefault();
27
- setError(null);
28
- setPending(true);
29
- const form = new FormData(event.currentTarget);
30
- const email = String(form.get("email"));
31
- const password = String(form.get("password"));
32
-
33
- const { error } =
34
- mode === "sign-up"
35
- ? await authClient.signUp.email({ email, password, name: String(form.get("name")) })
36
- : await authClient.signIn.email({ email, password });
37
-
38
- if (error) {
39
- setError(error.message ?? "Something went wrong. Please try again.");
40
- setPending(false);
41
- return;
42
- }
43
- // Full navigation so server components re-render with the new session cookie.
44
- window.location.assign(next);
45
- }
46
-
47
- async function signInWithProvider(provider: string) {
48
- setError(null);
49
- setPending(true);
50
- // Redirects the browser to the provider; failures come back to /sign-in?error=...
51
- const { error } = await authClient.signIn.social({
52
- provider,
53
- callbackURL: next,
54
- errorCallbackURL: `/sign-in?next=${encodeURIComponent(next)}`,
55
- });
56
- if (error) {
57
- setError(error.message ?? "Could not start sign-in. Please try again.");
58
- setPending(false);
59
- }
60
- }
61
-
62
- return (
63
- <div className="flex flex-col gap-4">
64
- {socialProviders.length > 0 && (
65
- <>
66
- <div className="flex flex-col gap-2">
67
- {socialProviders.map((provider) => (
68
- <button
69
- key={provider}
70
- type="button"
71
- disabled={pending}
72
- onClick={() => signInWithProvider(provider)}
73
- className="rounded-md border border-[var(--border)] px-4 py-2 text-sm font-medium hover:bg-[var(--surface-muted)] disabled:opacity-60"
74
- >
75
- Continue with {PROVIDER_LABELS[provider] ?? provider}
76
- </button>
77
- ))}
78
- </div>
79
- <p className="text-center text-xs text-[var(--foreground-muted)]">or use email</p>
80
- </>
81
- )}
82
-
83
- <form onSubmit={onSubmit} className="flex flex-col gap-4">
84
- {mode === "sign-up" && (
85
- <label className="flex flex-col gap-1.5 text-sm font-medium">
86
- Name
87
- <input name="name" required autoComplete="name" className={inputClass} />
88
- </label>
89
- )}
90
- <label className="flex flex-col gap-1.5 text-sm font-medium">
91
- Email
92
- <input name="email" type="email" required autoComplete="email" className={inputClass} />
93
- </label>
94
- <label className="flex flex-col gap-1.5 text-sm font-medium">
95
- Password
96
- <input
97
- name="password"
98
- type="password"
99
- required
100
- minLength={8}
101
- autoComplete={mode === "sign-up" ? "new-password" : "current-password"}
102
- className={inputClass}
103
- />
104
- </label>
105
- {error && (
106
- <p role="alert" className="text-sm text-[var(--danger)]">
107
- {error}
108
- </p>
109
- )}
110
- <button
111
- type="submit"
112
- disabled={pending}
113
- className="rounded-md bg-[var(--foreground)] px-4 py-2 text-sm font-medium text-[var(--background)] disabled:opacity-60"
114
- >
115
- {pending ? "Please wait…" : mode === "sign-up" ? "Create account" : "Sign in"}
116
- </button>
117
- </form>
118
- </div>
119
- );
120
- }
@@ -1,15 +0,0 @@
1
- // Extra admin sidebar links (maintained by flare generators such as `flare gen security`).
2
- // Add your own links outside the generated block.
3
- // generated:start
4
- export interface AdminLink {
5
- label: string;
6
- href: string;
7
- /** A resource icon name, e.g. "shield" (see components/admin/resource-icon.tsx). */
8
- icon: string;
9
- }
10
-
11
- export const generatedAdminLinks: AdminLink[] = [];
12
- // generated:end
13
-
14
- /** Links shown under "Platform" in the admin sidebar. */
15
- export const adminLinks: AdminLink[] = [...generatedAdminLinks];