@farm.js/create-app 0.1.0-beta.7 → 0.1.0-beta.70
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/README.md +38 -6
- package/bin/create-farm-app.js +7 -2
- package/dist/index.js +3298 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3294 -14
- package/dist/index.mjs.map +1 -1
- package/dist/utils.js +9 -6
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +9 -6
- package/dist/utils.mjs.map +1 -1
- package/package.json +2 -2
- package/templates/_integrations/better-auth/preact/farm.config.ts +17 -0
- package/templates/_integrations/better-auth/preact/src/app/dashboard/page.tsx +73 -0
- package/templates/_integrations/better-auth/preact/src/app/layout.tsx +14 -0
- package/templates/_integrations/better-auth/preact/src/app/page.tsx +36 -0
- package/templates/_integrations/better-auth/preact/src/app/sign-in/page.tsx +10 -0
- package/templates/_integrations/better-auth/preact/src/app/sign-up/page.tsx +10 -0
- package/templates/_integrations/better-auth/preact/src/components/auth-form.tsx +92 -0
- package/templates/_integrations/better-auth/preact/src/components/auth-shell.tsx +16 -0
- package/templates/_integrations/better-auth/preact/src/lib/auth-client.ts +5 -0
- package/templates/_integrations/better-auth/solid/farm.config.ts +17 -0
- package/templates/_integrations/better-auth/solid/src/app/dashboard/page.tsx +67 -0
- package/templates/_integrations/better-auth/solid/src/app/layout.tsx +14 -0
- package/templates/_integrations/better-auth/solid/src/app/page.tsx +36 -0
- package/templates/_integrations/better-auth/solid/src/app/sign-in/page.tsx +10 -0
- package/templates/_integrations/better-auth/solid/src/app/sign-up/page.tsx +10 -0
- package/templates/_integrations/better-auth/solid/src/components/auth-form.tsx +91 -0
- package/templates/_integrations/better-auth/solid/src/components/auth-shell.tsx +16 -0
- package/templates/_integrations/better-auth/solid/src/lib/auth-client.ts +5 -0
- package/templates/_integrations/better-auth/svelte/farm.config.ts +17 -0
- package/templates/_integrations/better-auth/svelte/src/app/dashboard/page.svelte +62 -0
- package/templates/_integrations/better-auth/svelte/src/app/layout.svelte +20 -0
- package/templates/_integrations/better-auth/svelte/src/app/page.svelte +32 -0
- package/templates/_integrations/better-auth/svelte/src/app/sign-in/page.svelte +10 -0
- package/templates/_integrations/better-auth/svelte/src/app/sign-up/page.svelte +10 -0
- package/templates/_integrations/better-auth/svelte/src/components/auth-form.svelte +83 -0
- package/templates/_integrations/better-auth/svelte/src/components/auth-shell.svelte +16 -0
- package/templates/_integrations/better-auth/svelte/src/components/resource-links.svelte +47 -0
- package/templates/_integrations/better-auth/svelte/src/lib/auth-client.ts +5 -0
- package/templates/_integrations/better-auth/vue/farm.config.ts +17 -0
- package/templates/_integrations/better-auth/vue/src/app/dashboard/page.vue +62 -0
- package/templates/_integrations/better-auth/vue/src/app/layout.vue +20 -0
- package/templates/_integrations/better-auth/vue/src/app/page.vue +34 -0
- package/templates/_integrations/better-auth/vue/src/app/sign-in/page.vue +12 -0
- package/templates/_integrations/better-auth/vue/src/app/sign-up/page.vue +12 -0
- package/templates/_integrations/better-auth/vue/src/components/auth-form.vue +86 -0
- package/templates/_integrations/better-auth/vue/src/components/auth-shell.vue +15 -0
- package/templates/_integrations/better-auth/vue/src/components/resource-links.vue +43 -0
- package/templates/_integrations/better-auth/vue/src/lib/auth-client.ts +5 -0
- package/templates/_renderers/preact/farm.config.ts +12 -0
- package/templates/_renderers/preact/package.json +26 -0
- package/templates/_renderers/preact/src/app/api/greeting/route.ts +15 -0
- package/templates/_renderers/preact/src/app/layout.tsx +16 -0
- package/templates/_renderers/preact/src/app/page.tsx +66 -0
- package/templates/_renderers/preact/src/app/preact.css +26 -0
- package/templates/_renderers/preact/src/components/resource-links.tsx +71 -0
- package/templates/_renderers/preact/src/lib/api-client.ts +4 -0
- package/templates/_renderers/preact/src/lib/api.generated.ts +7 -0
- package/templates/_renderers/preact/tsconfig.json +25 -0
- package/templates/_renderers/solid/farm.config.ts +12 -0
- package/templates/_renderers/solid/package.json +25 -0
- package/templates/_renderers/solid/src/app/api/greeting/route.ts +15 -0
- package/templates/_renderers/solid/src/app/layout.tsx +15 -0
- package/templates/_renderers/solid/src/app/page.tsx +56 -0
- package/templates/_renderers/solid/src/app/solid.css +22 -0
- package/templates/_renderers/solid/src/components/resource-links.tsx +71 -0
- package/templates/_renderers/solid/src/lib/api-client.ts +4 -0
- package/templates/_renderers/solid/src/lib/api.generated.ts +7 -0
- package/templates/_renderers/solid/tsconfig.json +25 -0
- package/templates/_renderers/svelte/farm.config.ts +9 -0
- package/templates/_renderers/svelte/package.json +28 -0
- package/templates/_renderers/svelte/src/app/api/greeting/route.ts +15 -0
- package/templates/_renderers/svelte/src/app/layout.svelte +21 -0
- package/templates/_renderers/svelte/src/app/page.svelte +64 -0
- package/templates/_renderers/svelte/src/app/svelte.css +26 -0
- package/templates/_renderers/svelte/src/components/resource-links.svelte +31 -0
- package/templates/_renderers/svelte/src/lib/api-client.ts +4 -0
- package/templates/_renderers/svelte/src/lib/api.generated.ts +7 -0
- package/templates/_renderers/svelte/tsconfig.json +23 -0
- package/templates/_renderers/vue/farm.config.ts +12 -0
- package/templates/_renderers/vue/package.json +26 -0
- package/templates/_renderers/vue/src/app/api/greeting/route.ts +15 -0
- package/templates/_renderers/vue/src/app/layout.vue +21 -0
- package/templates/_renderers/vue/src/app/page.vue +69 -0
- package/templates/_renderers/vue/src/app/vue.css +26 -0
- package/templates/_renderers/vue/src/components/resource-links.vue +33 -0
- package/templates/_renderers/vue/src/env.d.ts +7 -0
- package/templates/_renderers/vue/src/lib/api-client.ts +4 -0
- package/templates/_renderers/vue/src/lib/api.generated.ts +7 -0
- package/templates/_renderers/vue/tsconfig.json +23 -0
- package/templates/auth/.env.example +6 -0
- package/templates/auth/README.md +95 -0
- package/templates/auth/docs.config.ts +33 -0
- package/templates/auth/docs.json +36 -0
- package/templates/auth/farm.config.ts +20 -0
- package/templates/auth/gitignore +10 -0
- package/templates/auth/package.json +34 -0
- package/templates/auth/pnpm-workspace.yaml +13 -0
- package/templates/auth/src/app/dashboard/middleware.ts +13 -0
- package/templates/auth/src/app/dashboard/page.tsx +140 -0
- package/templates/auth/src/app/docs/page.md +29 -0
- package/templates/auth/src/app/error.tsx +25 -0
- package/templates/auth/src/app/globals.css +1064 -0
- package/templates/auth/src/app/layout.tsx +11 -0
- package/templates/auth/src/app/loading.tsx +15 -0
- package/templates/auth/src/app/not-found.tsx +26 -0
- package/templates/auth/src/app/page.tsx +46 -0
- package/templates/auth/src/app/sign-in/page.tsx +16 -0
- package/templates/auth/src/app/sign-up/page.tsx +16 -0
- package/templates/auth/src/components/auth-form.tsx +120 -0
- package/templates/auth/src/components/auth-shell.tsx +21 -0
- package/templates/auth/src/components/resource-links.tsx +78 -0
- package/templates/auth/src/components/sign-out-button.tsx +45 -0
- package/templates/auth/src/components/site-header.tsx +46 -0
- package/templates/auth/tsconfig.json +20 -0
- package/templates/basic/docs.config.ts +33 -0
- package/templates/basic/docs.json +36 -0
- package/templates/basic/farm.config.ts +9 -0
- package/templates/basic/package.json +7 -3
- package/templates/basic/pnpm-workspace.yaml +8 -0
- package/templates/basic/src/app/docs/page.md +29 -0
- package/templates/basic/src/app/globals.css +241 -0
- package/templates/basic/src/app/layout.tsx +3 -5
- package/templates/basic/src/app/page.tsx +20 -61
- package/templates/basic/src/components/resource-links.tsx +78 -0
- package/templates/basic/tsconfig.json +4 -0
- package/templates/better-auth/.env.example +3 -0
- package/templates/better-auth/README.md +89 -0
- package/templates/better-auth/docs.config.ts +33 -0
- package/templates/better-auth/docs.json +36 -0
- package/templates/better-auth/farm.config.ts +38 -0
- package/templates/better-auth/gitignore +10 -0
- package/templates/better-auth/package.json +36 -0
- package/templates/better-auth/pnpm-workspace.yaml +13 -0
- package/templates/better-auth/src/app/dashboard/middleware.ts +15 -0
- package/templates/better-auth/src/app/dashboard/page.tsx +188 -0
- package/templates/better-auth/src/app/docs/page.md +29 -0
- package/templates/better-auth/src/app/error.tsx +25 -0
- package/templates/better-auth/src/app/globals.css +1064 -0
- package/templates/better-auth/src/app/layout.tsx +11 -0
- package/templates/better-auth/src/app/loading.tsx +15 -0
- package/templates/better-auth/src/app/not-found.tsx +26 -0
- package/templates/better-auth/src/app/page.tsx +50 -0
- package/templates/better-auth/src/app/sign-in/page.tsx +16 -0
- package/templates/better-auth/src/app/sign-up/page.tsx +16 -0
- package/templates/better-auth/src/components/auth-form.tsx +120 -0
- package/templates/better-auth/src/components/auth-shell.tsx +21 -0
- package/templates/better-auth/src/components/resource-links.tsx +78 -0
- package/templates/better-auth/src/components/sign-out-button.tsx +45 -0
- package/templates/better-auth/src/components/site-header.tsx +46 -0
- package/templates/better-auth/src/lib/auth-client.ts +5 -0
- package/templates/better-auth/src/lib/auth.ts +50 -0
- package/templates/better-auth/src/lib/session.ts +8 -0
- package/templates/better-auth/tsconfig.json +20 -0
- package/templates/react-compiler/README.md +62 -0
- package/templates/react-compiler/docs.config.ts +33 -0
- package/templates/react-compiler/docs.json +36 -0
- package/templates/react-compiler/farm.config.ts +29 -0
- package/templates/react-compiler/gitignore +23 -0
- package/templates/react-compiler/package.json +34 -0
- package/templates/react-compiler/pnpm-workspace.yaml +8 -0
- package/templates/react-compiler/public/favicon.svg +5 -0
- package/templates/react-compiler/scripts/verify-experiment.mjs +113 -0
- package/templates/react-compiler/src/app/docs/page.md +29 -0
- package/templates/react-compiler/src/app/globals.css +470 -0
- package/templates/react-compiler/src/app/layout.tsx +22 -0
- package/templates/react-compiler/src/app/page.tsx +47 -0
- package/templates/react-compiler/src/components/compiler-comparison.tsx +93 -0
- package/templates/react-compiler/src/components/resource-links.tsx +78 -0
- package/templates/react-compiler/src/farm.d.ts +74 -0
- package/templates/react-compiler/src/lib/api.generated.ts +10 -0
- package/templates/react-compiler/tsconfig.json +24 -0
- package/templates/basic/src/app/about/page.tsx +0 -32
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
"baseUrl": ".",
|
|
10
|
+
"paths": {
|
|
11
|
+
"@/*": ["./src/*"]
|
|
12
|
+
},
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*.ts", "src/**/*.svelte", "farm.config.ts"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "farm-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "farm dev",
|
|
7
|
+
"build": "farm build",
|
|
8
|
+
"deploy": "farm deploy",
|
|
9
|
+
"type-check": "vue-tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@farm.js/core": "0.1.0-beta.70",
|
|
13
|
+
"@farm.js/vue": "0.1.0-beta.27",
|
|
14
|
+
"@fontsource-variable/geist": "5.3.0",
|
|
15
|
+
"@fontsource-variable/geist-mono": "5.3.0",
|
|
16
|
+
"vue": "3.5.41",
|
|
17
|
+
"zod": "4.1.12"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@farm.js/cli": "0.1.0-beta.70",
|
|
21
|
+
"tailwindcss": "^4.0.0",
|
|
22
|
+
"typescript": "^5.3.3",
|
|
23
|
+
"vue-tsc": "3.3.9"
|
|
24
|
+
},
|
|
25
|
+
"packageManager": "pnpm@8.12.1"
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createEndpoint } from "@farm.js/core/api";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const POST = createEndpoint(
|
|
5
|
+
"/api/greeting",
|
|
6
|
+
{
|
|
7
|
+
method: "POST",
|
|
8
|
+
body: z.object({
|
|
9
|
+
name: z.string().trim().min(1).max(40),
|
|
10
|
+
}),
|
|
11
|
+
},
|
|
12
|
+
async ({ body }) => ({
|
|
13
|
+
message: `Hello, ${body.name}, from the FARMJS server.`,
|
|
14
|
+
}),
|
|
15
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Metadata } from "@farm.js/core";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
import "./vue.css";
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: "FARMJS Vue App",
|
|
8
|
+
description: "A framework for product-integrated apps",
|
|
9
|
+
icons: {
|
|
10
|
+
icon: [{ url: "/favicon.svg", type: "image/svg+xml", sizes: "any" }],
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
defineOptions({ inheritAttrs: false });
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<slot />
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export const hydrate = true;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { ref } from "vue";
|
|
7
|
+
import ResourceLinks from "../components/resource-links.vue";
|
|
8
|
+
import { api } from "../lib/api-client";
|
|
9
|
+
|
|
10
|
+
defineOptions({ inheritAttrs: false });
|
|
11
|
+
|
|
12
|
+
const message = ref("Call a typed server function");
|
|
13
|
+
const pending = ref(false);
|
|
14
|
+
const failed = ref(false);
|
|
15
|
+
|
|
16
|
+
async function callServer() {
|
|
17
|
+
pending.value = true;
|
|
18
|
+
failed.value = false;
|
|
19
|
+
try {
|
|
20
|
+
const result = await api.greeting.post({
|
|
21
|
+
body: { name: "Vue" },
|
|
22
|
+
});
|
|
23
|
+
if (result.error) throw result.error;
|
|
24
|
+
if (!result.data) throw new Error("The server returned no greeting");
|
|
25
|
+
message.value = result.data.message;
|
|
26
|
+
} catch {
|
|
27
|
+
failed.value = true;
|
|
28
|
+
message.value = "Try the server call again";
|
|
29
|
+
} finally {
|
|
30
|
+
pending.value = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<main class="landing-main">
|
|
37
|
+
<section class="hero-section">
|
|
38
|
+
<div class="hero-copy">
|
|
39
|
+
<div class="eyebrow-row">
|
|
40
|
+
<span>00</span>
|
|
41
|
+
<span>FARMJS / Vue starter</span>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<h1>Edit <code>page.vue</code> to begin.</h1>
|
|
45
|
+
|
|
46
|
+
<div class="command-list" aria-label="Getting started">
|
|
47
|
+
<div class="command-row">
|
|
48
|
+
<span>01</span>
|
|
49
|
+
<code>pnpm dev</code>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="command-row">
|
|
52
|
+
<span>02</span>
|
|
53
|
+
<button
|
|
54
|
+
type="button"
|
|
55
|
+
class="server-call"
|
|
56
|
+
:class="{ 'server-call-error': failed }"
|
|
57
|
+
:disabled="pending"
|
|
58
|
+
@click="callServer"
|
|
59
|
+
>
|
|
60
|
+
{{ pending ? "Calling…" : message }}
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<ResourceLinks class="resource-links" />
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
</main>
|
|
69
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.server-call {
|
|
2
|
+
appearance: none;
|
|
3
|
+
width: fit-content;
|
|
4
|
+
border: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
color: var(--ink);
|
|
7
|
+
background: transparent;
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
font-family: var(--font-mono);
|
|
10
|
+
font-size: 0.75rem;
|
|
11
|
+
text-align: left;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.server-call:hover:not(:disabled) {
|
|
15
|
+
text-decoration: underline;
|
|
16
|
+
text-underline-offset: 0.25rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.server-call:disabled {
|
|
20
|
+
color: var(--ink-soft);
|
|
21
|
+
cursor: wait;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.server-call-error {
|
|
25
|
+
color: #fca5a5;
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav aria-label="Starter resources">
|
|
3
|
+
<span class="resource-link-item">
|
|
4
|
+
<a href="https://farm.js.dev">
|
|
5
|
+
<svg
|
|
6
|
+
class="resource-icon"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="1.8"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
>
|
|
15
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
|
|
16
|
+
<path d="M14 2v6h6M8 13h8M8 17h6" />
|
|
17
|
+
</svg>
|
|
18
|
+
<span>Docs</span>
|
|
19
|
+
</a>
|
|
20
|
+
</span>
|
|
21
|
+
<span class="resource-link-item">
|
|
22
|
+
<span class="resource-separator" aria-hidden="true">/</span>
|
|
23
|
+
<a href="https://github.com/farming-labs/farm.js">
|
|
24
|
+
<svg class="resource-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
25
|
+
<path
|
|
26
|
+
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"
|
|
27
|
+
/>
|
|
28
|
+
</svg>
|
|
29
|
+
<span>GitHub</span>
|
|
30
|
+
</a>
|
|
31
|
+
</span>
|
|
32
|
+
</nav>
|
|
33
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
"baseUrl": ".",
|
|
10
|
+
"paths": {
|
|
11
|
+
"@/*": ["./src/*"]
|
|
12
|
+
},
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*.ts", "src/**/*.vue", "farm.config.ts"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# FARMJS Auth needs no environment variables in local development.
|
|
2
|
+
# Configure these values in the production deployment environment.
|
|
3
|
+
|
|
4
|
+
# FARM_AUTH_URL=https://your-app.example.com
|
|
5
|
+
# FARM_AUTH_SECRET=replace-with-a-random-secret-at-least-32-characters
|
|
6
|
+
# DATABASE_URL=postgresql://user:password@your-postgres-host/database?sslmode=require
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# FARMJS Auth Starter
|
|
2
|
+
|
|
3
|
+
A standalone email/password authentication starter using FARMJS built-in authentication and
|
|
4
|
+
React.
|
|
5
|
+
|
|
6
|
+
This project was generated from the FARMJS Auth template included with `@farm.js/create-app`.
|
|
7
|
+
|
|
8
|
+
## Included
|
|
9
|
+
|
|
10
|
+
- email/password sign-up and sign-in enabled by `auth: true`
|
|
11
|
+
- database-backed, HTTP-only session cookies
|
|
12
|
+
- a server-middleware-protected `/dashboard`
|
|
13
|
+
- `@farm.js/auth/server` request helpers and the `@farm.js/auth/client` React hook
|
|
14
|
+
- automatic local SQLite storage in `.farm/auth.sqlite`
|
|
15
|
+
- production Postgres support through `DATABASE_URL`
|
|
16
|
+
- a dark-first, one-page welcome screen set in Geist Sans and Geist Mono
|
|
17
|
+
- pending, error, unauthorized, loading, and not-found states
|
|
18
|
+
- exact FARMJS beta dependencies for reproducible installs
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm create @farm.js/app@beta my-app --template auth --typescript
|
|
24
|
+
cd my-app
|
|
25
|
+
pnpm dev
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Open [http://localhost:3000](http://localhost:3000), create an account, and continue to the
|
|
29
|
+
protected dashboard. Local development needs no database or auth environment variables; FARMJS Auth
|
|
30
|
+
creates and migrates `.farm/auth.sqlite` when auth is first used.
|
|
31
|
+
|
|
32
|
+
## How it is wired
|
|
33
|
+
|
|
34
|
+
- [`farm.config.ts`](./farm.config.ts) enables email/password authentication with `auth: true`.
|
|
35
|
+
- [`src/app/page.tsx`](./src/app/page.tsx) reads the current session with
|
|
36
|
+
`auth.session()` from `@farm.js/auth/server`.
|
|
37
|
+
- [`src/components/auth-form.tsx`](./src/components/auth-form.tsx) uses the built-in `signIn` and
|
|
38
|
+
`signUp` client functions.
|
|
39
|
+
- [`src/app/dashboard/middleware.ts`](./src/app/dashboard/middleware.ts) redirects anonymous
|
|
40
|
+
requests before the dashboard route runs.
|
|
41
|
+
- [`src/app/dashboard/page.tsx`](./src/app/dashboard/page.tsx) uses the built-in `useAuth` React
|
|
42
|
+
hook to render the current account and session.
|
|
43
|
+
|
|
44
|
+
FARMJS owns the auth action routes, so the starter does not need an app-local Better Auth instance,
|
|
45
|
+
client factory, database pool, or catch-all API route:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
/api/auth/*
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Production environment
|
|
52
|
+
|
|
53
|
+
Local development uses safe defaults. Production requires these deployment environment variables:
|
|
54
|
+
|
|
55
|
+
| Variable | Purpose |
|
|
56
|
+
| ------------------ | ----------------------------------------------------------- |
|
|
57
|
+
| `FARM_AUTH_URL` | Public application origin; inferred automatically on Vercel |
|
|
58
|
+
| `FARM_AUTH_SECRET` | Random secret used to sign and encrypt auth data |
|
|
59
|
+
| `DATABASE_URL` | Postgres connection string |
|
|
60
|
+
|
|
61
|
+
Generate a production secret with:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
openssl rand -base64 32
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Loading `farm.config.ts` and running `farm build` do not connect to the database. Apply the
|
|
68
|
+
production auth schema before serving traffic:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pnpm auth:migrate
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The FARMJS deployment target is configured in [`farm.config.ts`](./farm.config.ts) for Vercel.
|
|
75
|
+
|
|
76
|
+
## Advanced authentication
|
|
77
|
+
|
|
78
|
+
`auth: true` intentionally owns the common email/password path. If an application needs Better Auth
|
|
79
|
+
plugins, adapters, social providers, or callbacks, replace the top-level auth option with an
|
|
80
|
+
app-owned `integrations.auth` configuration using `@farm.js/better-auth`.
|
|
81
|
+
|
|
82
|
+
## Commands
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pnpm dev # start the development server
|
|
86
|
+
pnpm type-check # run TypeScript checks
|
|
87
|
+
pnpm build # create the production build without connecting to the database
|
|
88
|
+
pnpm check # type-check and build
|
|
89
|
+
pnpm auth:migrate # apply the production auth schema
|
|
90
|
+
pnpm run deploy -- --prod
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
MIT
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from "@farm.js/core";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
auth: true,
|
|
5
|
+
theme: {
|
|
6
|
+
default: "dark",
|
|
7
|
+
},
|
|
8
|
+
// Docs are powered by the @farming-labs/farmjs framework. Farm auto-detects
|
|
9
|
+
// the installed adapter and reads docs.config.ts (docs.json is kept as a
|
|
10
|
+
// language-agnostic fallback/manifest); content lives in src/app/docs.
|
|
11
|
+
docs: {
|
|
12
|
+
enabled: true,
|
|
13
|
+
},
|
|
14
|
+
experimental: {
|
|
15
|
+
serverComponents: true,
|
|
16
|
+
},
|
|
17
|
+
deploy: {
|
|
18
|
+
target: "vercel",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "farmjs-auth-starter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "farm dev",
|
|
7
|
+
"build": "farm build",
|
|
8
|
+
"auth:migrate": "farm auth migrate",
|
|
9
|
+
"check": "pnpm type-check && pnpm build",
|
|
10
|
+
"deploy": "farm deploy",
|
|
11
|
+
"type-check": "tsc --noEmit"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@farm.js/auth": "0.1.0-beta.70",
|
|
15
|
+
"@farm.js/core": "0.1.0-beta.70",
|
|
16
|
+
"@farming-labs/docs": "0.2.111",
|
|
17
|
+
"@farming-labs/farmjs": "0.2.111",
|
|
18
|
+
"@farming-labs/theme": "0.2.111",
|
|
19
|
+
"@fontsource-variable/geist": "5.3.0",
|
|
20
|
+
"@fontsource-variable/geist-mono": "5.3.0",
|
|
21
|
+
"better-call": "1.3.2",
|
|
22
|
+
"react": "^19.0.0",
|
|
23
|
+
"react-dom": "^19.0.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@farm.js/cli": "0.1.0-beta.70",
|
|
27
|
+
"@types/node": "20.19.9",
|
|
28
|
+
"@types/react": "^19.0.0",
|
|
29
|
+
"@types/react-dom": "^19.0.0",
|
|
30
|
+
"tailwindcss": "^4.0.0",
|
|
31
|
+
"typescript": "^5.3.3"
|
|
32
|
+
},
|
|
33
|
+
"packageManager": "pnpm@11.18.0"
|
|
34
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { auth } from "@farm.js/auth/server";
|
|
2
|
+
|
|
3
|
+
export const config = {
|
|
4
|
+
runtime: "nodejs" as const,
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export async function middleware(request: Request) {
|
|
8
|
+
const user = await auth.user({ request });
|
|
9
|
+
|
|
10
|
+
if (!user) {
|
|
11
|
+
return Response.redirect(new URL("/sign-in", request.url), 307);
|
|
12
|
+
}
|
|
13
|
+
}
|