@farm.js/create-app 0.1.0-beta.7 → 0.1.0-beta.71

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 (173) hide show
  1. package/README.md +38 -6
  2. package/bin/create-farm-app.js +7 -2
  3. package/dist/index.js +3298 -16
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +3294 -14
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/utils.js +9 -6
  8. package/dist/utils.js.map +1 -1
  9. package/dist/utils.mjs +9 -6
  10. package/dist/utils.mjs.map +1 -1
  11. package/package.json +2 -2
  12. package/templates/_integrations/better-auth/preact/farm.config.ts +17 -0
  13. package/templates/_integrations/better-auth/preact/src/app/dashboard/page.tsx +73 -0
  14. package/templates/_integrations/better-auth/preact/src/app/layout.tsx +14 -0
  15. package/templates/_integrations/better-auth/preact/src/app/page.tsx +36 -0
  16. package/templates/_integrations/better-auth/preact/src/app/sign-in/page.tsx +10 -0
  17. package/templates/_integrations/better-auth/preact/src/app/sign-up/page.tsx +10 -0
  18. package/templates/_integrations/better-auth/preact/src/components/auth-form.tsx +92 -0
  19. package/templates/_integrations/better-auth/preact/src/components/auth-shell.tsx +16 -0
  20. package/templates/_integrations/better-auth/preact/src/lib/auth-client.ts +5 -0
  21. package/templates/_integrations/better-auth/solid/farm.config.ts +17 -0
  22. package/templates/_integrations/better-auth/solid/src/app/dashboard/page.tsx +67 -0
  23. package/templates/_integrations/better-auth/solid/src/app/layout.tsx +14 -0
  24. package/templates/_integrations/better-auth/solid/src/app/page.tsx +36 -0
  25. package/templates/_integrations/better-auth/solid/src/app/sign-in/page.tsx +10 -0
  26. package/templates/_integrations/better-auth/solid/src/app/sign-up/page.tsx +10 -0
  27. package/templates/_integrations/better-auth/solid/src/components/auth-form.tsx +91 -0
  28. package/templates/_integrations/better-auth/solid/src/components/auth-shell.tsx +16 -0
  29. package/templates/_integrations/better-auth/solid/src/lib/auth-client.ts +5 -0
  30. package/templates/_integrations/better-auth/svelte/farm.config.ts +17 -0
  31. package/templates/_integrations/better-auth/svelte/src/app/dashboard/page.svelte +62 -0
  32. package/templates/_integrations/better-auth/svelte/src/app/layout.svelte +20 -0
  33. package/templates/_integrations/better-auth/svelte/src/app/page.svelte +32 -0
  34. package/templates/_integrations/better-auth/svelte/src/app/sign-in/page.svelte +10 -0
  35. package/templates/_integrations/better-auth/svelte/src/app/sign-up/page.svelte +10 -0
  36. package/templates/_integrations/better-auth/svelte/src/components/auth-form.svelte +83 -0
  37. package/templates/_integrations/better-auth/svelte/src/components/auth-shell.svelte +16 -0
  38. package/templates/_integrations/better-auth/svelte/src/components/resource-links.svelte +47 -0
  39. package/templates/_integrations/better-auth/svelte/src/lib/auth-client.ts +5 -0
  40. package/templates/_integrations/better-auth/vue/farm.config.ts +17 -0
  41. package/templates/_integrations/better-auth/vue/src/app/dashboard/page.vue +62 -0
  42. package/templates/_integrations/better-auth/vue/src/app/layout.vue +20 -0
  43. package/templates/_integrations/better-auth/vue/src/app/page.vue +34 -0
  44. package/templates/_integrations/better-auth/vue/src/app/sign-in/page.vue +12 -0
  45. package/templates/_integrations/better-auth/vue/src/app/sign-up/page.vue +12 -0
  46. package/templates/_integrations/better-auth/vue/src/components/auth-form.vue +86 -0
  47. package/templates/_integrations/better-auth/vue/src/components/auth-shell.vue +15 -0
  48. package/templates/_integrations/better-auth/vue/src/components/resource-links.vue +43 -0
  49. package/templates/_integrations/better-auth/vue/src/lib/auth-client.ts +5 -0
  50. package/templates/_renderers/preact/farm.config.ts +12 -0
  51. package/templates/_renderers/preact/package.json +26 -0
  52. package/templates/_renderers/preact/src/app/api/greeting/route.ts +15 -0
  53. package/templates/_renderers/preact/src/app/layout.tsx +16 -0
  54. package/templates/_renderers/preact/src/app/page.tsx +66 -0
  55. package/templates/_renderers/preact/src/app/preact.css +26 -0
  56. package/templates/_renderers/preact/src/components/resource-links.tsx +71 -0
  57. package/templates/_renderers/preact/src/lib/api-client.ts +4 -0
  58. package/templates/_renderers/preact/src/lib/api.generated.ts +7 -0
  59. package/templates/_renderers/preact/tsconfig.json +25 -0
  60. package/templates/_renderers/solid/farm.config.ts +12 -0
  61. package/templates/_renderers/solid/package.json +25 -0
  62. package/templates/_renderers/solid/src/app/api/greeting/route.ts +15 -0
  63. package/templates/_renderers/solid/src/app/layout.tsx +15 -0
  64. package/templates/_renderers/solid/src/app/page.tsx +56 -0
  65. package/templates/_renderers/solid/src/app/solid.css +22 -0
  66. package/templates/_renderers/solid/src/components/resource-links.tsx +71 -0
  67. package/templates/_renderers/solid/src/lib/api-client.ts +4 -0
  68. package/templates/_renderers/solid/src/lib/api.generated.ts +7 -0
  69. package/templates/_renderers/solid/tsconfig.json +25 -0
  70. package/templates/_renderers/svelte/farm.config.ts +9 -0
  71. package/templates/_renderers/svelte/package.json +28 -0
  72. package/templates/_renderers/svelte/src/app/api/greeting/route.ts +15 -0
  73. package/templates/_renderers/svelte/src/app/layout.svelte +21 -0
  74. package/templates/_renderers/svelte/src/app/page.svelte +64 -0
  75. package/templates/_renderers/svelte/src/app/svelte.css +26 -0
  76. package/templates/_renderers/svelte/src/components/resource-links.svelte +31 -0
  77. package/templates/_renderers/svelte/src/lib/api-client.ts +4 -0
  78. package/templates/_renderers/svelte/src/lib/api.generated.ts +7 -0
  79. package/templates/_renderers/svelte/tsconfig.json +23 -0
  80. package/templates/_renderers/vue/farm.config.ts +12 -0
  81. package/templates/_renderers/vue/package.json +26 -0
  82. package/templates/_renderers/vue/src/app/api/greeting/route.ts +15 -0
  83. package/templates/_renderers/vue/src/app/layout.vue +21 -0
  84. package/templates/_renderers/vue/src/app/page.vue +69 -0
  85. package/templates/_renderers/vue/src/app/vue.css +26 -0
  86. package/templates/_renderers/vue/src/components/resource-links.vue +33 -0
  87. package/templates/_renderers/vue/src/env.d.ts +7 -0
  88. package/templates/_renderers/vue/src/lib/api-client.ts +4 -0
  89. package/templates/_renderers/vue/src/lib/api.generated.ts +7 -0
  90. package/templates/_renderers/vue/tsconfig.json +23 -0
  91. package/templates/auth/.env.example +6 -0
  92. package/templates/auth/README.md +95 -0
  93. package/templates/auth/docs.config.ts +33 -0
  94. package/templates/auth/docs.json +36 -0
  95. package/templates/auth/farm.config.ts +20 -0
  96. package/templates/auth/gitignore +10 -0
  97. package/templates/auth/package.json +34 -0
  98. package/templates/auth/pnpm-workspace.yaml +13 -0
  99. package/templates/auth/src/app/dashboard/middleware.ts +13 -0
  100. package/templates/auth/src/app/dashboard/page.tsx +140 -0
  101. package/templates/auth/src/app/docs/page.md +29 -0
  102. package/templates/auth/src/app/error.tsx +25 -0
  103. package/templates/auth/src/app/globals.css +1064 -0
  104. package/templates/auth/src/app/layout.tsx +11 -0
  105. package/templates/auth/src/app/loading.tsx +15 -0
  106. package/templates/auth/src/app/not-found.tsx +26 -0
  107. package/templates/auth/src/app/page.tsx +46 -0
  108. package/templates/auth/src/app/sign-in/page.tsx +16 -0
  109. package/templates/auth/src/app/sign-up/page.tsx +16 -0
  110. package/templates/auth/src/components/auth-form.tsx +120 -0
  111. package/templates/auth/src/components/auth-shell.tsx +21 -0
  112. package/templates/auth/src/components/resource-links.tsx +78 -0
  113. package/templates/auth/src/components/sign-out-button.tsx +45 -0
  114. package/templates/auth/src/components/site-header.tsx +46 -0
  115. package/templates/auth/tsconfig.json +20 -0
  116. package/templates/basic/docs.config.ts +33 -0
  117. package/templates/basic/docs.json +36 -0
  118. package/templates/basic/farm.config.ts +9 -0
  119. package/templates/basic/package.json +7 -3
  120. package/templates/basic/pnpm-workspace.yaml +8 -0
  121. package/templates/basic/src/app/docs/page.md +29 -0
  122. package/templates/basic/src/app/globals.css +241 -0
  123. package/templates/basic/src/app/layout.tsx +3 -5
  124. package/templates/basic/src/app/page.tsx +20 -61
  125. package/templates/basic/src/components/resource-links.tsx +78 -0
  126. package/templates/basic/tsconfig.json +4 -0
  127. package/templates/better-auth/.env.example +3 -0
  128. package/templates/better-auth/README.md +89 -0
  129. package/templates/better-auth/docs.config.ts +33 -0
  130. package/templates/better-auth/docs.json +36 -0
  131. package/templates/better-auth/farm.config.ts +38 -0
  132. package/templates/better-auth/gitignore +10 -0
  133. package/templates/better-auth/package.json +36 -0
  134. package/templates/better-auth/pnpm-workspace.yaml +13 -0
  135. package/templates/better-auth/src/app/dashboard/middleware.ts +15 -0
  136. package/templates/better-auth/src/app/dashboard/page.tsx +188 -0
  137. package/templates/better-auth/src/app/docs/page.md +29 -0
  138. package/templates/better-auth/src/app/error.tsx +25 -0
  139. package/templates/better-auth/src/app/globals.css +1064 -0
  140. package/templates/better-auth/src/app/layout.tsx +11 -0
  141. package/templates/better-auth/src/app/loading.tsx +15 -0
  142. package/templates/better-auth/src/app/not-found.tsx +26 -0
  143. package/templates/better-auth/src/app/page.tsx +50 -0
  144. package/templates/better-auth/src/app/sign-in/page.tsx +16 -0
  145. package/templates/better-auth/src/app/sign-up/page.tsx +16 -0
  146. package/templates/better-auth/src/components/auth-form.tsx +120 -0
  147. package/templates/better-auth/src/components/auth-shell.tsx +21 -0
  148. package/templates/better-auth/src/components/resource-links.tsx +78 -0
  149. package/templates/better-auth/src/components/sign-out-button.tsx +45 -0
  150. package/templates/better-auth/src/components/site-header.tsx +46 -0
  151. package/templates/better-auth/src/lib/auth-client.ts +5 -0
  152. package/templates/better-auth/src/lib/auth.ts +50 -0
  153. package/templates/better-auth/src/lib/session.ts +8 -0
  154. package/templates/better-auth/tsconfig.json +20 -0
  155. package/templates/react-compiler/README.md +62 -0
  156. package/templates/react-compiler/docs.config.ts +33 -0
  157. package/templates/react-compiler/docs.json +36 -0
  158. package/templates/react-compiler/farm.config.ts +29 -0
  159. package/templates/react-compiler/gitignore +23 -0
  160. package/templates/react-compiler/package.json +34 -0
  161. package/templates/react-compiler/pnpm-workspace.yaml +8 -0
  162. package/templates/react-compiler/public/favicon.svg +5 -0
  163. package/templates/react-compiler/scripts/verify-experiment.mjs +113 -0
  164. package/templates/react-compiler/src/app/docs/page.md +29 -0
  165. package/templates/react-compiler/src/app/globals.css +470 -0
  166. package/templates/react-compiler/src/app/layout.tsx +22 -0
  167. package/templates/react-compiler/src/app/page.tsx +47 -0
  168. package/templates/react-compiler/src/components/compiler-comparison.tsx +93 -0
  169. package/templates/react-compiler/src/components/resource-links.tsx +78 -0
  170. package/templates/react-compiler/src/farm.d.ts +74 -0
  171. package/templates/react-compiler/src/lib/api.generated.ts +10 -0
  172. package/templates/react-compiler/tsconfig.json +24 -0
  173. package/templates/basic/src/app/about/page.tsx +0 -32
@@ -0,0 +1,11 @@
1
+ import type { LayoutProps, Metadata } from "@farm.js/core";
2
+ import "./globals.css";
3
+
4
+ export const metadata: Metadata = {
5
+ title: "FARMJS Auth Starter",
6
+ description: "A production-shaped starter powered by FARMJS built-in authentication.",
7
+ };
8
+
9
+ export default function RootLayout({ children }: LayoutProps) {
10
+ return <>{children}</>;
11
+ }
@@ -0,0 +1,15 @@
1
+ export default function Loading() {
2
+ return (
3
+ <main className="loading-shell" aria-label="Loading page" aria-live="polite">
4
+ <div className="loading-block">
5
+ <span className="loading-label">Loading account</span>
6
+ <div className="loading-line wide" />
7
+ <div className="loading-line" />
8
+ <div className="loading-grid">
9
+ <div />
10
+ <div />
11
+ </div>
12
+ </div>
13
+ </main>
14
+ );
15
+ }
@@ -0,0 +1,26 @@
1
+ interface NotFoundProps {
2
+ pathname?: string;
3
+ }
4
+
5
+ export default function NotFound({ pathname }: NotFoundProps) {
6
+ return (
7
+ <main className="error-shell">
8
+ <section className="error-panel">
9
+ <span className="section-index">404 / NOT FOUND</span>
10
+ <h1>This route is outside the starter.</h1>
11
+ <p>
12
+ {pathname ? (
13
+ <>
14
+ Nothing is registered at <code>{pathname}</code>.
15
+ </>
16
+ ) : (
17
+ "The page you requested does not exist."
18
+ )}
19
+ </p>
20
+ <a className="button button-primary" href="/">
21
+ Return home
22
+ </a>
23
+ </section>
24
+ </main>
25
+ );
26
+ }
@@ -0,0 +1,46 @@
1
+ import { auth } from "@farm.js/auth/server";
2
+ import { ResourceLinks } from "../components/resource-links";
3
+
4
+ export default async function HomePage() {
5
+ const session = await auth.session();
6
+
7
+ return (
8
+ <main className="landing-main">
9
+ <section className="hero-section">
10
+ <div className="hero-copy">
11
+ <div className="eyebrow-row">
12
+ <span>00</span>
13
+ <span>FARMJS / Auth starter</span>
14
+ </div>
15
+
16
+ <h1>
17
+ {session ? (
18
+ <>
19
+ Open your <code>/dashboard</code>.
20
+ </>
21
+ ) : (
22
+ <>
23
+ Start at <code>/sign-up</code>.
24
+ </>
25
+ )}
26
+ </h1>
27
+
28
+ <div className="command-list" aria-label="Development command">
29
+ <div className="command-row">
30
+ <span>01</span>
31
+ <code>pnpm dev</code>
32
+ </div>
33
+ </div>
34
+
35
+ <ResourceLinks
36
+ className="resource-links"
37
+ primary={{
38
+ href: session ? "/dashboard" : "/sign-up",
39
+ label: session ? "Dashboard" : "Get started",
40
+ }}
41
+ />
42
+ </div>
43
+ </section>
44
+ </main>
45
+ );
46
+ }
@@ -0,0 +1,16 @@
1
+ import type { Metadata } from "@farm.js/core";
2
+ import { AuthForm } from "../../components/auth-form";
3
+ import { AuthShell } from "../../components/auth-shell";
4
+
5
+ export const metadata: Metadata = {
6
+ title: "Sign in | FARMJS Auth Starter",
7
+ description: "Sign in with FARMJS Auth.",
8
+ };
9
+
10
+ export default function SignInPage() {
11
+ return (
12
+ <AuthShell>
13
+ <AuthForm mode="sign-in" />
14
+ </AuthShell>
15
+ );
16
+ }
@@ -0,0 +1,16 @@
1
+ import type { Metadata } from "@farm.js/core";
2
+ import { AuthForm } from "../../components/auth-form";
3
+ import { AuthShell } from "../../components/auth-shell";
4
+
5
+ export const metadata: Metadata = {
6
+ title: "Create account | FARMJS Auth Starter",
7
+ description: "Create an account with FARMJS Auth.",
8
+ };
9
+
10
+ export default function SignUpPage() {
11
+ return (
12
+ <AuthShell>
13
+ <AuthForm mode="sign-up" />
14
+ </AuthShell>
15
+ );
16
+ }
@@ -0,0 +1,120 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { signIn, signUp } from "@farm.js/auth/client";
5
+
6
+ interface AuthFormProps {
7
+ mode: "sign-in" | "sign-up";
8
+ }
9
+
10
+ export function AuthForm({ mode }: AuthFormProps) {
11
+ const isSignUp = mode === "sign-up";
12
+ const [pending, setPending] = useState(false);
13
+ const [error, setError] = useState<string | null>(null);
14
+
15
+ async function submit(event: React.FormEvent<HTMLFormElement>) {
16
+ event.preventDefault();
17
+ setError(null);
18
+ setPending(true);
19
+
20
+ const formData = new FormData(event.currentTarget);
21
+ const email = String(formData.get("email") ?? "").trim();
22
+ const password = String(formData.get("password") ?? "");
23
+ const name = String(formData.get("name") ?? "").trim();
24
+
25
+ try {
26
+ const response = isSignUp
27
+ ? await signUp({
28
+ email,
29
+ name,
30
+ password,
31
+ })
32
+ : await signIn({
33
+ email,
34
+ password,
35
+ });
36
+
37
+ if (response.error) {
38
+ setError(response.error.message ?? "We could not complete that request.");
39
+ setPending(false);
40
+ return;
41
+ }
42
+
43
+ window.location.assign("/dashboard");
44
+ } catch {
45
+ setError("The authentication service could not be reached. Please try again.");
46
+ setPending(false);
47
+ }
48
+ }
49
+
50
+ return (
51
+ <div className="auth-form-panel">
52
+ <div className="auth-form-heading">
53
+ <span className="section-index">{isSignUp ? "01 / SIGN UP" : "01 / SIGN IN"}</span>
54
+ <h1>{isSignUp ? "Create account." : "Welcome back."}</h1>
55
+ </div>
56
+
57
+ <form className="auth-form" onSubmit={submit}>
58
+ {isSignUp ? (
59
+ <label className="field">
60
+ <span>
61
+ <small>01</small> Name
62
+ </span>
63
+ <input
64
+ autoComplete="name"
65
+ minLength={2}
66
+ name="name"
67
+ placeholder="Ada Lovelace"
68
+ required
69
+ type="text"
70
+ />
71
+ </label>
72
+ ) : null}
73
+
74
+ <label className="field">
75
+ <span>
76
+ <small>{isSignUp ? "02" : "01"}</small> Email
77
+ </span>
78
+ <input
79
+ autoComplete="email"
80
+ name="email"
81
+ placeholder="you@example.com"
82
+ required
83
+ type="email"
84
+ />
85
+ </label>
86
+
87
+ <label className="field">
88
+ <span>
89
+ <small>{isSignUp ? "03" : "02"}</small> Password
90
+ </span>
91
+ <input
92
+ autoComplete={isSignUp ? "new-password" : "current-password"}
93
+ minLength={8}
94
+ name="password"
95
+ placeholder="At least 8 characters"
96
+ required
97
+ type="password"
98
+ />
99
+ </label>
100
+
101
+ {error ? (
102
+ <div className="form-error" role="alert">
103
+ <strong>Authentication failed</strong>
104
+ <span>{error}</span>
105
+ </div>
106
+ ) : null}
107
+
108
+ <button className="button button-primary auth-submit" disabled={pending} type="submit">
109
+ <span>{pending ? "Please wait…" : isSignUp ? "Create account" : "Sign in"}</span>
110
+ <span aria-hidden="true">{pending ? "···" : "→"}</span>
111
+ </button>
112
+ </form>
113
+
114
+ <p className="auth-switch">
115
+ {isSignUp ? "Have an account?" : "Need an account?"}{" "}
116
+ <a href={isSignUp ? "/sign-in" : "/sign-up"}>{isSignUp ? "Sign in →" : "Sign up →"}</a>
117
+ </p>
118
+ </div>
119
+ );
120
+ }
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from "react";
2
+ import { ResourceLinks } from "./resource-links";
3
+
4
+ interface AuthShellProps {
5
+ children: ReactNode;
6
+ }
7
+
8
+ export function AuthShell({ children }: AuthShellProps) {
9
+ return (
10
+ <main className="auth-shell">
11
+ <a className="auth-home-link" href="/" aria-label="Back to starter home">
12
+ <span>00</span>
13
+ <span>FARMJS / Auth starter</span>
14
+ </a>
15
+
16
+ <section className="auth-form-side">{children}</section>
17
+
18
+ <ResourceLinks className="auth-resource-links" />
19
+ </main>
20
+ );
21
+ }
@@ -0,0 +1,78 @@
1
+ interface ResourceLinkAction {
2
+ href: string;
3
+ label: string;
4
+ }
5
+
6
+ interface ResourceLinksProps {
7
+ className: string;
8
+ primary?: ResourceLinkAction;
9
+ }
10
+
11
+ function DocsIcon() {
12
+ return (
13
+ <svg
14
+ className="resource-icon"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ stroke="currentColor"
18
+ strokeWidth="1.8"
19
+ strokeLinecap="round"
20
+ strokeLinejoin="round"
21
+ aria-hidden="true"
22
+ focusable="false"
23
+ >
24
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
25
+ <path d="M14 2v6h6M8 13h8M8 17h6" />
26
+ </svg>
27
+ );
28
+ }
29
+
30
+ function GitHubIcon() {
31
+ return (
32
+ <svg
33
+ className="resource-icon"
34
+ viewBox="0 0 24 24"
35
+ fill="currentColor"
36
+ aria-hidden="true"
37
+ focusable="false"
38
+ >
39
+ <path d="M12 .7a11.5 11.5 0 0 0-3.64 22.41c.58.1.79-.25.79-.56v-2.23c-3.22.7-3.9-1.37-3.9-1.37-.52-1.34-1.28-1.69-1.28-1.69-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.57-.29-5.27-1.29-5.27-5.68 0-1.26.45-2.28 1.18-3.09-.12-.29-.51-1.47.11-3.05 0 0 .96-.31 3.16 1.18A10.95 10.95 0 0 1 12 6.1c.98 0 1.95.13 2.87.39 2.2-1.49 3.16-1.18 3.16-1.18.62 1.58.23 2.76.11 3.05.74.81 1.18 1.83 1.18 3.09 0 4.4-2.71 5.38-5.29 5.67.42.36.79 1.07.79 2.16v3.27c0 .31.21.67.8.56A11.5 11.5 0 0 0 12 .7Z" />
40
+ </svg>
41
+ );
42
+ }
43
+
44
+ function ResourceSeparator() {
45
+ return (
46
+ <span className="resource-separator" aria-hidden="true">
47
+ /
48
+ </span>
49
+ );
50
+ }
51
+
52
+ export function ResourceLinks({ className, primary }: ResourceLinksProps) {
53
+ return (
54
+ <nav className={className} aria-label="Starter resources">
55
+ {primary ? (
56
+ <span className="resource-link-item">
57
+ <a className="resource-link-primary" href={primary.href}>
58
+ {primary.label}
59
+ </a>
60
+ </span>
61
+ ) : null}
62
+ <span className="resource-link-item">
63
+ {primary ? <ResourceSeparator /> : null}
64
+ <a href="https://farm.js.dev">
65
+ <DocsIcon />
66
+ <span>Docs</span>
67
+ </a>
68
+ </span>
69
+ <span className="resource-link-item">
70
+ <ResourceSeparator />
71
+ <a href="https://github.com/farming-labs/farm.js">
72
+ <GitHubIcon />
73
+ <span>GitHub</span>
74
+ </a>
75
+ </span>
76
+ </nav>
77
+ );
78
+ }
@@ -0,0 +1,45 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { signOut as endSession } from "@farm.js/auth/client";
5
+
6
+ export function SignOutButton() {
7
+ const [pending, setPending] = useState(false);
8
+ const [error, setError] = useState<string | null>(null);
9
+
10
+ async function signOut() {
11
+ setPending(true);
12
+ setError(null);
13
+
14
+ try {
15
+ const response = await endSession();
16
+ if (response.error) {
17
+ setError(response.error.message ?? "Could not sign out.");
18
+ setPending(false);
19
+ return;
20
+ }
21
+ window.location.assign("/");
22
+ } catch {
23
+ setError("Could not reach the authentication service.");
24
+ setPending(false);
25
+ }
26
+ }
27
+
28
+ return (
29
+ <div className="sign-out-control">
30
+ <button
31
+ className="button button-secondary"
32
+ disabled={pending}
33
+ onClick={signOut}
34
+ type="button"
35
+ >
36
+ {pending ? "Signing out…" : "Sign out"}
37
+ </button>
38
+ {error ? (
39
+ <span className="inline-error" role="alert">
40
+ {error}
41
+ </span>
42
+ ) : null}
43
+ </div>
44
+ );
45
+ }
@@ -0,0 +1,46 @@
1
+ interface HeaderUser {
2
+ email: string;
3
+ name: string;
4
+ }
5
+
6
+ interface SiteHeaderProps {
7
+ user: HeaderUser | null;
8
+ }
9
+
10
+ export function SiteHeader({ user }: SiteHeaderProps) {
11
+ return (
12
+ <header className="site-header">
13
+ <a className="brand" href="/" aria-label="FARMJS Auth Starter home">
14
+ <span className="brand-mark" aria-hidden="true">
15
+ F
16
+ </span>
17
+ <span>
18
+ <strong>FARMJS</strong>
19
+ <small>Auth Starter</small>
20
+ </span>
21
+ </a>
22
+
23
+ <nav className="header-nav" aria-label="Primary navigation">
24
+ <a href="https://farm.js.dev">Docs</a>
25
+ {user ? (
26
+ <a className="header-account" href="/dashboard">
27
+ <span className="avatar" aria-hidden="true">
28
+ {(user.name || user.email).slice(0, 1).toUpperCase()}
29
+ </span>
30
+ <span className="account-copy">
31
+ <small>Signed in</small>
32
+ <strong>{user.name || user.email}</strong>
33
+ </span>
34
+ </a>
35
+ ) : (
36
+ <>
37
+ <a href="/sign-in">Sign in</a>
38
+ <a className="button button-small button-primary" href="/sign-up">
39
+ Get started
40
+ </a>
41
+ </>
42
+ )}
43
+ </nav>
44
+ </header>
45
+ );
46
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true
18
+ },
19
+ "include": ["src", "farm.config.ts"]
20
+ }
@@ -0,0 +1,33 @@
1
+ import { defineDocs } from "@farming-labs/docs";
2
+
3
+ // Site-wide docs configuration, powered by the @farming-labs/farmjs framework.
4
+ // Farm auto-detects the installed adapter (because farm.config.ts sets
5
+ // `docs: { enabled: true }`), loads this file, and serves Markdown from
6
+ // src/app/docs.
7
+ //
8
+ // This typed config takes priority over docs.json. Keep docs.json in sync as
9
+ // the language-agnostic manifest: it is the fallback for frameworkless / non
10
+ // JS-TS setups and the source the docs cloud reads.
11
+ export default defineDocs({
12
+ entry: "docs",
13
+ docsPath: "/docs",
14
+ metadata: {
15
+ description: "Documentation for your Farm.js app.",
16
+ },
17
+ nav: {
18
+ title: "Farm App",
19
+ url: "/",
20
+ },
21
+ search: {
22
+ provider: "simple",
23
+ enabled: true,
24
+ maxResults: 12,
25
+ },
26
+ llmsTxt: {
27
+ enabled: true,
28
+ siteTitle: "Farm App Docs",
29
+ siteDescription: "Documentation for your Farm.js app.",
30
+ },
31
+ sitemap: true,
32
+ robots: true,
33
+ });
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://docs.farming-labs.dev/schema/docs.json",
3
+ "version": 1,
4
+ "entry": "docs",
5
+ "docsPath": "/docs",
6
+ "docs": {
7
+ "mode": "framework",
8
+ "runtime": "farm",
9
+ "root": "."
10
+ },
11
+ "content": {
12
+ "docsRoot": "src/app/docs"
13
+ },
14
+ "site": {
15
+ "name": "Farm App Docs"
16
+ },
17
+ "metadata": {
18
+ "description": "Documentation for your Farm.js app."
19
+ },
20
+ "nav": {
21
+ "title": "Farm App",
22
+ "url": "/"
23
+ },
24
+ "search": {
25
+ "provider": "simple",
26
+ "enabled": true,
27
+ "maxResults": 12
28
+ },
29
+ "llmsTxt": {
30
+ "enabled": true,
31
+ "siteTitle": "Farm App Docs",
32
+ "siteDescription": "Documentation for your Farm.js app."
33
+ },
34
+ "sitemap": true,
35
+ "robots": true
36
+ }
@@ -1,6 +1,15 @@
1
1
  import { defineConfig } from "@farm.js/core";
2
2
 
3
3
  export default defineConfig({
4
+ theme: {
5
+ default: "dark",
6
+ },
7
+ // Docs are powered by the @farming-labs/farmjs framework. Farm auto-detects
8
+ // the installed adapter and reads docs.config.ts (docs.json is kept as a
9
+ // language-agnostic fallback/manifest); content lives in src/app/docs.
10
+ docs: {
11
+ enabled: true,
12
+ },
4
13
  deploy: {
5
14
  target: "vercel",
6
15
  },
@@ -6,16 +6,20 @@
6
6
  "dev": "farm dev",
7
7
  "build": "farm build",
8
8
  "deploy": "farm deploy",
9
- "start": "farm start",
10
9
  "type-check": "tsc --noEmit"
11
10
  },
12
11
  "dependencies": {
13
- "@farm.js/core": "0.1.0-beta.7",
12
+ "@farm.js/core": "0.1.0-beta.71",
13
+ "@farming-labs/docs": "0.2.111",
14
+ "@farming-labs/farmjs": "0.2.111",
15
+ "@farming-labs/theme": "0.2.111",
16
+ "@fontsource-variable/geist": "5.3.0",
17
+ "@fontsource-variable/geist-mono": "5.3.0",
14
18
  "react": "^19.0.0",
15
19
  "react-dom": "^19.0.0"
16
20
  },
17
21
  "devDependencies": {
18
- "@farm.js/cli": "0.1.0-beta.7",
22
+ "@farm.js/cli": "0.1.0-beta.71",
19
23
  "@types/react": "^19.0.0",
20
24
  "@types/react-dom": "^19.0.0",
21
25
  "tailwindcss": "^4.0.0",
@@ -0,0 +1,8 @@
1
+ packages:
2
+ - "."
3
+
4
+ allowBuilds:
5
+ "@prisma/client": true
6
+ esbuild: true
7
+ sharp: true
8
+ vue-demi: true
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: "Getting Started"
3
+ description: "Your Farm.js documentation, powered by the @farming-labs/farmjs docs framework."
4
+ ---
5
+
6
+ # Getting Started
7
+
8
+ These docs are served by the Farm docs runtime, powered by the
9
+ [@farming-labs/farmjs](https://www.npmjs.com/package/@farming-labs/farmjs) docs
10
+ framework. The same Markdown files power human pages, Markdown routes,
11
+ `llms.txt`, the sitemap, search, and agent discovery through `/api/docs`.
12
+
13
+ ## Edit this page
14
+
15
+ This page lives at `src/app/docs/page.md`. Add more pages as folders with their
16
+ own `page.md` — for example `src/app/docs/configuration/page.md` is served at
17
+ `/docs/configuration`.
18
+
19
+ ## Configure
20
+
21
+ Site-wide docs settings live in `docs.config.ts` at the project root (title,
22
+ navigation, search, `llms.txt`, sitemap, and robots). Farm auto-detects the
23
+ installed adapter because `farm.config.ts` sets `docs: { enabled: true }` — no
24
+ manual wiring required.
25
+
26
+ ## Learn more
27
+
28
+ - [Farm.js documentation](https://farm.js.dev/docs)
29
+ - [Configuration guide](https://farm.js.dev/docs/configuration)