@flaredev/cli 0.1.2 → 0.2.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 (50) hide show
  1. package/dist/index.js +340 -163
  2. package/package.json +3 -2
  3. package/templates/app/app/api/openapi.json/route.ts +23 -0
  4. package/templates/app/app/api/reference/route.ts +36 -0
  5. package/templates/app/app/dashboard/account/page.tsx +38 -0
  6. package/templates/app/app/dashboard/layout.tsx +39 -0
  7. package/templates/app/app/dashboard/page.tsx +42 -9
  8. package/templates/app/app/forgot-password/page.tsx +22 -0
  9. package/templates/app/app/globals.css +109 -4
  10. package/templates/app/app/layout.tsx +28 -26
  11. package/templates/app/app/page.tsx +126 -13
  12. package/templates/app/app/reset-password/page.tsx +31 -0
  13. package/templates/app/app/sign-in/page.tsx +49 -33
  14. package/templates/app/app/sign-up/page.tsx +42 -23
  15. package/templates/app/app/two-factor/page.tsx +25 -0
  16. package/templates/app/components/account/security-settings.tsx +525 -0
  17. package/templates/app/components/admin/fields/country-field.tsx +152 -0
  18. package/templates/app/components/admin/fields/field-widget.tsx +186 -128
  19. package/templates/app/components/admin/fields/multi-select-field.tsx +46 -0
  20. package/templates/app/components/admin/fields/phone-field.tsx +86 -0
  21. package/templates/app/components/admin/resource-nav.tsx +120 -109
  22. package/templates/app/components/admin/resource-table.tsx +31 -1
  23. package/templates/app/components/auth/auth-shell.tsx +284 -0
  24. package/templates/app/components/auth/password-forms.tsx +79 -0
  25. package/templates/app/components/auth/provider-icons.tsx +39 -0
  26. package/templates/app/components/auth/sign-in-flow.tsx +315 -0
  27. package/templates/app/components/auth/sign-up-form.tsx +101 -0
  28. package/templates/app/components/auth/social-buttons.tsx +56 -0
  29. package/templates/app/components/auth/two-factor-form.tsx +124 -0
  30. package/templates/app/components/auth/ui.tsx +96 -0
  31. package/templates/app/components/dashboard/dashboard-nav.tsx +35 -0
  32. package/templates/app/components/marketing/product-preview.tsx +70 -0
  33. package/templates/app/components/marketing/site-header.tsx +39 -0
  34. package/templates/app/components/sign-out-button.tsx +1 -1
  35. package/templates/app/components/ui/checkbox.tsx +25 -0
  36. package/templates/app/components/ui/radio-group.tsx +29 -0
  37. package/templates/app/db/auth-schema.ts +167 -118
  38. package/templates/app/lib/admin-nav.ts +1 -1
  39. package/templates/app/lib/api-docs.ts +16 -0
  40. package/templates/app/lib/auth-client.ts +16 -1
  41. package/templates/app/lib/auth-config.ts +33 -0
  42. package/templates/app/lib/auth-emails.ts +94 -0
  43. package/templates/app/lib/auth.ts +81 -6
  44. package/templates/app/lib/site.ts +47 -0
  45. package/templates/app/lib/theme.ts +79 -0
  46. package/templates/app/migrations/0000_init.sql +32 -1
  47. package/templates/app/migrations/meta/0000_snapshot.json +215 -1
  48. package/templates/app/migrations/meta/_journal.json +1 -1
  49. package/templates/app/vite.config.ts +5 -3
  50. package/templates/app/components/auth-form.tsx +0 -120
@@ -1,9 +1,11 @@
1
- import { defineConfig } from "vite";
1
+ import { defineConfig, loadEnv } from "vite";
2
2
  import vinext from "vinext";
3
3
  import { cloudflare } from "@cloudflare/vite-plugin";
4
4
  import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";
5
5
 
6
- export default defineConfig({
6
+ export default defineConfig(({ mode }) => ({
7
+ // FLARE_THEME (shell or .env) picks the theme for this build; see lib/theme.ts.
8
+ define: { __FLARE_THEME__: JSON.stringify(loadEnv(mode, process.cwd(), "FLARE_").FLARE_THEME ?? "") },
7
9
  // `flare dev --tunnel` serves the dev server on a https://*.trycloudflare.com URL.
8
10
  server: { allowedHosts: [".trycloudflare.com"] },
9
11
  plugins: [
@@ -26,4 +28,4 @@ export default defineConfig({
26
28
  },
27
29
  }),
28
30
  ],
29
- });
31
+ }));
@@ -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
- }