@farm.js/create-app 0.1.0-beta.4 → 0.1.0-beta.41
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 +41 -4
- package/bin/create-farm-app.js +8 -2
- package/dist/index.js +3244 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3239 -18
- 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 +27 -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 +26 -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 +27 -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/farm.config.ts +14 -0
- package/templates/auth/gitignore +10 -0
- package/templates/auth/package.json +32 -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/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/farm.config.ts +3 -0
- package/templates/basic/gitignore +23 -0
- package/templates/basic/package.json +4 -2
- package/templates/basic/pnpm-workspace.yaml +8 -0
- package/templates/basic/public/favicon.svg +13 -0
- package/templates/basic/src/app/globals.css +241 -0
- package/templates/basic/src/app/layout.tsx +6 -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/farm.config.ts +32 -0
- package/templates/better-auth/gitignore +10 -0
- package/templates/better-auth/package.json +34 -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/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/farm.config.ts +23 -0
- package/templates/react-compiler/gitignore +23 -0
- package/templates/react-compiler/package.json +31 -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/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 +73 -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
- package/templates/basic/src/farm-images.d.ts +0 -59
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "preact/hooks";
|
|
4
|
+
import { ResourceLinks } from "../components/resource-links";
|
|
5
|
+
import { api } from "../lib/api-client";
|
|
6
|
+
|
|
7
|
+
export default function HomePage() {
|
|
8
|
+
const [message, setMessage] = useState("Call a typed server function");
|
|
9
|
+
const [pending, setPending] = useState(false);
|
|
10
|
+
const [failed, setFailed] = useState(false);
|
|
11
|
+
|
|
12
|
+
const callServer = async () => {
|
|
13
|
+
setPending(true);
|
|
14
|
+
setFailed(false);
|
|
15
|
+
try {
|
|
16
|
+
const result = await api.greeting.post({
|
|
17
|
+
body: { name: "Preact" },
|
|
18
|
+
});
|
|
19
|
+
if (result.error) throw result.error;
|
|
20
|
+
if (!result.data) throw new Error("The server returned no greeting");
|
|
21
|
+
setMessage(result.data.message);
|
|
22
|
+
} catch {
|
|
23
|
+
setFailed(true);
|
|
24
|
+
setMessage("Try the server call again");
|
|
25
|
+
} finally {
|
|
26
|
+
setPending(false);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<main className="landing-main">
|
|
32
|
+
<section className="hero-section">
|
|
33
|
+
<div className="hero-copy">
|
|
34
|
+
<div className="eyebrow-row">
|
|
35
|
+
<span>00</span>
|
|
36
|
+
<span>FARMJS / Preact starter</span>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<h1>
|
|
40
|
+
Edit <code>page.tsx</code> to begin.
|
|
41
|
+
</h1>
|
|
42
|
+
|
|
43
|
+
<div className="command-list" aria-label="Getting started">
|
|
44
|
+
<div className="command-row">
|
|
45
|
+
<span>01</span>
|
|
46
|
+
<code>pnpm dev</code>
|
|
47
|
+
</div>
|
|
48
|
+
<div className="command-row">
|
|
49
|
+
<span>02</span>
|
|
50
|
+
<button
|
|
51
|
+
type="button"
|
|
52
|
+
className={`server-call${failed ? " server-call-error" : ""}`}
|
|
53
|
+
onClick={callServer}
|
|
54
|
+
disabled={pending}
|
|
55
|
+
>
|
|
56
|
+
{pending ? "Calling…" : message}
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<ResourceLinks className="resource-links" />
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
</main>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -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,71 @@
|
|
|
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
|
+
>
|
|
23
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
|
|
24
|
+
<path d="M14 2v6h6M8 13h8M8 17h6" />
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function GitHubIcon() {
|
|
30
|
+
return (
|
|
31
|
+
<svg className="resource-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
32
|
+
<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" />
|
|
33
|
+
</svg>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ResourceSeparator() {
|
|
38
|
+
return (
|
|
39
|
+
<span className="resource-separator" aria-hidden="true">
|
|
40
|
+
/
|
|
41
|
+
</span>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function ResourceLinks({ className, primary }: ResourceLinksProps) {
|
|
46
|
+
return (
|
|
47
|
+
<nav className={className} aria-label="Starter resources">
|
|
48
|
+
{primary ? (
|
|
49
|
+
<span className="resource-link-item">
|
|
50
|
+
<a className="resource-link-primary" href={primary.href}>
|
|
51
|
+
{primary.label}
|
|
52
|
+
</a>
|
|
53
|
+
</span>
|
|
54
|
+
) : null}
|
|
55
|
+
<span className="resource-link-item">
|
|
56
|
+
{primary ? <ResourceSeparator /> : null}
|
|
57
|
+
<a href="https://farm.js.dev">
|
|
58
|
+
<DocsIcon />
|
|
59
|
+
<span>Docs</span>
|
|
60
|
+
</a>
|
|
61
|
+
</span>
|
|
62
|
+
<span className="resource-link-item">
|
|
63
|
+
<ResourceSeparator />
|
|
64
|
+
<a href="https://github.com/farming-labs/farm.js">
|
|
65
|
+
<GitHubIcon />
|
|
66
|
+
<span>GitHub</span>
|
|
67
|
+
</a>
|
|
68
|
+
</span>
|
|
69
|
+
</nav>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
"jsx": "react-jsx",
|
|
18
|
+
"jsxImportSource": "preact",
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["src", "farm.config.ts"]
|
|
25
|
+
}
|
|
@@ -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
|
+
"start": "farm start",
|
|
10
|
+
"type-check": "tsc --noEmit"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@farm.js/core": "0.1.0-beta.41",
|
|
14
|
+
"@farm.js/solid": "0.1.0-beta.26",
|
|
15
|
+
"@fontsource-variable/geist": "5.3.0",
|
|
16
|
+
"@fontsource-variable/geist-mono": "5.3.0",
|
|
17
|
+
"solid-js": "1.9.14",
|
|
18
|
+
"zod": "4.1.12"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@farm.js/cli": "0.1.0-beta.41",
|
|
22
|
+
"tailwindcss": "^4.0.0",
|
|
23
|
+
"typescript": "^5.3.3"
|
|
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,15 @@
|
|
|
1
|
+
import type { LayoutProps, Metadata } from "@farm.js/core";
|
|
2
|
+
import "./globals.css";
|
|
3
|
+
import "./solid.css";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: "FARMJS Solid App",
|
|
7
|
+
description: "A framework for product-integrated apps",
|
|
8
|
+
icons: {
|
|
9
|
+
icon: [{ url: "/favicon.svg", type: "image/svg+xml", sizes: "any" }],
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function RootLayout(props: LayoutProps) {
|
|
14
|
+
return <>{props.children}</>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createSignal } from "solid-js";
|
|
4
|
+
import { ResourceLinks } from "../components/resource-links";
|
|
5
|
+
import { api } from "../lib/api-client";
|
|
6
|
+
|
|
7
|
+
export default function HomePage() {
|
|
8
|
+
const [message, setMessage] = createSignal("Call a typed server function");
|
|
9
|
+
const [pending, setPending] = createSignal(false);
|
|
10
|
+
|
|
11
|
+
const callServer = async () => {
|
|
12
|
+
setPending(true);
|
|
13
|
+
try {
|
|
14
|
+
const result = await api.greeting.post({
|
|
15
|
+
body: { name: "Solid" },
|
|
16
|
+
});
|
|
17
|
+
if (result.error) throw result.error;
|
|
18
|
+
if (!result.data) throw new Error("The server returned no greeting");
|
|
19
|
+
setMessage(result.data.message);
|
|
20
|
+
} finally {
|
|
21
|
+
setPending(false);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<main class="landing-main">
|
|
27
|
+
<section class="hero-section">
|
|
28
|
+
<div class="hero-copy">
|
|
29
|
+
<div class="eyebrow-row">
|
|
30
|
+
<span>00</span>
|
|
31
|
+
<span>FARMJS / Solid starter</span>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<h1>
|
|
35
|
+
Edit <code>page.tsx</code> to begin.
|
|
36
|
+
</h1>
|
|
37
|
+
|
|
38
|
+
<div class="command-list" aria-label="Getting started">
|
|
39
|
+
<div class="command-row">
|
|
40
|
+
<span>01</span>
|
|
41
|
+
<code>pnpm dev</code>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="command-row">
|
|
44
|
+
<span>02</span>
|
|
45
|
+
<button type="button" class="server-call" onClick={callServer} disabled={pending()}>
|
|
46
|
+
{pending() ? "Calling…" : message()}
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<ResourceLinks className="resource-links" />
|
|
52
|
+
</div>
|
|
53
|
+
</section>
|
|
54
|
+
</main>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
class="resource-icon"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
fill="none"
|
|
17
|
+
stroke="currentColor"
|
|
18
|
+
stroke-width="1.8"
|
|
19
|
+
stroke-linecap="round"
|
|
20
|
+
stroke-linejoin="round"
|
|
21
|
+
aria-hidden="true"
|
|
22
|
+
>
|
|
23
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
|
|
24
|
+
<path d="M14 2v6h6M8 13h8M8 17h6" />
|
|
25
|
+
</svg>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function GitHubIcon() {
|
|
30
|
+
return (
|
|
31
|
+
<svg class="resource-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
32
|
+
<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" />
|
|
33
|
+
</svg>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ResourceSeparator() {
|
|
38
|
+
return (
|
|
39
|
+
<span class="resource-separator" aria-hidden="true">
|
|
40
|
+
/
|
|
41
|
+
</span>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function ResourceLinks(props: ResourceLinksProps) {
|
|
46
|
+
return (
|
|
47
|
+
<nav class={props.className} aria-label="Starter resources">
|
|
48
|
+
{props.primary ? (
|
|
49
|
+
<span class="resource-link-item">
|
|
50
|
+
<a class="resource-link-primary" href={props.primary.href}>
|
|
51
|
+
{props.primary.label}
|
|
52
|
+
</a>
|
|
53
|
+
</span>
|
|
54
|
+
) : null}
|
|
55
|
+
<span class="resource-link-item">
|
|
56
|
+
{props.primary ? <ResourceSeparator /> : null}
|
|
57
|
+
<a href="https://farm.js.dev">
|
|
58
|
+
<DocsIcon />
|
|
59
|
+
<span>Docs</span>
|
|
60
|
+
</a>
|
|
61
|
+
</span>
|
|
62
|
+
<span class="resource-link-item">
|
|
63
|
+
<ResourceSeparator />
|
|
64
|
+
<a href="https://github.com/farming-labs/farm.js">
|
|
65
|
+
<GitHubIcon />
|
|
66
|
+
<span>GitHub</span>
|
|
67
|
+
</a>
|
|
68
|
+
</span>
|
|
69
|
+
</nav>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
"jsx": "preserve",
|
|
18
|
+
"jsxImportSource": "solid-js",
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["src", "farm.config.ts"]
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "farm-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "farm dev",
|
|
8
|
+
"build": "farm build",
|
|
9
|
+
"deploy": "farm deploy",
|
|
10
|
+
"start": "farm start",
|
|
11
|
+
"type-check": "svelte-check --tsconfig ./tsconfig.json"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@farm.js/core": "0.1.0-beta.41",
|
|
15
|
+
"@farm.js/svelte": "0.1.0-beta.29",
|
|
16
|
+
"@fontsource-variable/geist": "5.3.0",
|
|
17
|
+
"@fontsource-variable/geist-mono": "5.3.0",
|
|
18
|
+
"svelte": "5.56.8",
|
|
19
|
+
"zod": "4.1.12"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@farm.js/cli": "0.1.0-beta.41",
|
|
23
|
+
"svelte-check": "4.7.5",
|
|
24
|
+
"tailwindcss": "^4.0.0",
|
|
25
|
+
"typescript": "^5.3.3"
|
|
26
|
+
},
|
|
27
|
+
"packageManager": "pnpm@8.12.1"
|
|
28
|
+
}
|
|
@@ -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 module lang="ts">
|
|
2
|
+
import type { Metadata } from "@farm.js/core";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
import "./svelte.css";
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: "FARMJS Svelte 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 lang="ts">
|
|
16
|
+
import type { Snippet } from "svelte";
|
|
17
|
+
|
|
18
|
+
let { children }: { children?: Snippet } = $props();
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
{@render children?.()}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export const hydrate = true;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import ResourceLinks from "../components/resource-links.svelte";
|
|
7
|
+
import { api } from "../lib/api-client";
|
|
8
|
+
|
|
9
|
+
let message = $state("Call a typed server function");
|
|
10
|
+
let pending = $state(false);
|
|
11
|
+
let failed = $state(false);
|
|
12
|
+
|
|
13
|
+
async function callServer() {
|
|
14
|
+
pending = true;
|
|
15
|
+
failed = false;
|
|
16
|
+
try {
|
|
17
|
+
const result = await api.greeting.post({
|
|
18
|
+
body: { name: "Svelte" },
|
|
19
|
+
});
|
|
20
|
+
if (result.error) throw result.error;
|
|
21
|
+
if (!result.data) throw new Error("The server returned no greeting");
|
|
22
|
+
message = result.data.message;
|
|
23
|
+
} catch {
|
|
24
|
+
failed = true;
|
|
25
|
+
message = "Try the server call again";
|
|
26
|
+
} finally {
|
|
27
|
+
pending = false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<main class="landing-main">
|
|
33
|
+
<section class="hero-section">
|
|
34
|
+
<div class="hero-copy">
|
|
35
|
+
<div class="eyebrow-row">
|
|
36
|
+
<span>00</span>
|
|
37
|
+
<span>FARMJS / Svelte starter</span>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<h1>Edit <code>page.svelte</code> to begin.</h1>
|
|
41
|
+
|
|
42
|
+
<div class="command-list" aria-label="Getting started">
|
|
43
|
+
<div class="command-row">
|
|
44
|
+
<span>01</span>
|
|
45
|
+
<code>pnpm dev</code>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="command-row">
|
|
48
|
+
<span>02</span>
|
|
49
|
+
<button
|
|
50
|
+
type="button"
|
|
51
|
+
class:server-call-error={failed}
|
|
52
|
+
class="server-call"
|
|
53
|
+
disabled={pending}
|
|
54
|
+
onclick={callServer}
|
|
55
|
+
>
|
|
56
|
+
{pending ? "Calling…" : message}
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<ResourceLinks class="resource-links" />
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
</main>
|
|
@@ -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,31 @@
|
|
|
1
|
+
<nav aria-label="Starter resources">
|
|
2
|
+
<span class="resource-link-item">
|
|
3
|
+
<a href="https://farm.js.dev">
|
|
4
|
+
<svg
|
|
5
|
+
class="resource-icon"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
fill="none"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
stroke-width="1.8"
|
|
10
|
+
stroke-linecap="round"
|
|
11
|
+
stroke-linejoin="round"
|
|
12
|
+
aria-hidden="true"
|
|
13
|
+
>
|
|
14
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" />
|
|
15
|
+
<path d="M14 2v6h6M8 13h8M8 17h6" />
|
|
16
|
+
</svg>
|
|
17
|
+
<span>Docs</span>
|
|
18
|
+
</a>
|
|
19
|
+
</span>
|
|
20
|
+
<span class="resource-link-item">
|
|
21
|
+
<span class="resource-separator" aria-hidden="true">/</span>
|
|
22
|
+
<a href="https://github.com/farming-labs/farm.js">
|
|
23
|
+
<svg class="resource-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
24
|
+
<path
|
|
25
|
+
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"
|
|
26
|
+
/>
|
|
27
|
+
</svg>
|
|
28
|
+
<span>GitHub</span>
|
|
29
|
+
</a>
|
|
30
|
+
</span>
|
|
31
|
+
</nav>
|