@farm.js/create-app 0.1.0-beta.3 → 0.1.0-beta.31

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 (111) hide show
  1. package/README.md +31 -4
  2. package/bin/create-farm-app.js +7 -1
  3. package/dist/index.js +2893 -19
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +2889 -18
  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/_renderers/preact/farm.config.ts +12 -0
  13. package/templates/_renderers/preact/package.json +27 -0
  14. package/templates/_renderers/preact/src/app/api/greeting/route.ts +15 -0
  15. package/templates/_renderers/preact/src/app/layout.tsx +16 -0
  16. package/templates/_renderers/preact/src/app/page.tsx +66 -0
  17. package/templates/_renderers/preact/src/app/preact.css +26 -0
  18. package/templates/_renderers/preact/src/components/resource-links.tsx +71 -0
  19. package/templates/_renderers/preact/src/lib/api-client.ts +4 -0
  20. package/templates/_renderers/preact/src/lib/api.generated.ts +7 -0
  21. package/templates/_renderers/preact/tsconfig.json +25 -0
  22. package/templates/_renderers/solid/farm.config.ts +12 -0
  23. package/templates/_renderers/solid/package.json +26 -0
  24. package/templates/_renderers/solid/src/app/api/greeting/route.ts +15 -0
  25. package/templates/_renderers/solid/src/app/layout.tsx +15 -0
  26. package/templates/_renderers/solid/src/app/page.tsx +56 -0
  27. package/templates/_renderers/solid/src/app/solid.css +22 -0
  28. package/templates/_renderers/solid/src/components/resource-links.tsx +71 -0
  29. package/templates/_renderers/solid/src/lib/api-client.ts +4 -0
  30. package/templates/_renderers/solid/src/lib/api.generated.ts +7 -0
  31. package/templates/_renderers/solid/tsconfig.json +25 -0
  32. package/templates/_renderers/svelte/farm.config.ts +9 -0
  33. package/templates/_renderers/svelte/package.json +28 -0
  34. package/templates/_renderers/svelte/src/app/api/greeting/route.ts +15 -0
  35. package/templates/_renderers/svelte/src/app/layout.svelte +21 -0
  36. package/templates/_renderers/svelte/src/app/page.svelte +64 -0
  37. package/templates/_renderers/svelte/src/app/svelte.css +26 -0
  38. package/templates/_renderers/svelte/src/components/resource-links.svelte +31 -0
  39. package/templates/_renderers/svelte/src/lib/api-client.ts +4 -0
  40. package/templates/_renderers/svelte/src/lib/api.generated.ts +7 -0
  41. package/templates/_renderers/svelte/tsconfig.json +23 -0
  42. package/templates/_renderers/vue/farm.config.ts +12 -0
  43. package/templates/_renderers/vue/package.json +27 -0
  44. package/templates/_renderers/vue/src/app/api/greeting/route.ts +15 -0
  45. package/templates/_renderers/vue/src/app/layout.vue +21 -0
  46. package/templates/_renderers/vue/src/app/page.vue +69 -0
  47. package/templates/_renderers/vue/src/app/vue.css +26 -0
  48. package/templates/_renderers/vue/src/components/resource-links.vue +33 -0
  49. package/templates/_renderers/vue/src/env.d.ts +7 -0
  50. package/templates/_renderers/vue/src/lib/api-client.ts +4 -0
  51. package/templates/_renderers/vue/src/lib/api.generated.ts +7 -0
  52. package/templates/_renderers/vue/tsconfig.json +23 -0
  53. package/templates/auth/.env.example +6 -0
  54. package/templates/auth/README.md +95 -0
  55. package/templates/auth/farm.config.ts +14 -0
  56. package/templates/auth/gitignore +10 -0
  57. package/templates/auth/package.json +32 -0
  58. package/templates/auth/pnpm-workspace.yaml +13 -0
  59. package/templates/auth/src/app/dashboard/middleware.ts +13 -0
  60. package/templates/auth/src/app/dashboard/page.tsx +140 -0
  61. package/templates/auth/src/app/error.tsx +25 -0
  62. package/templates/auth/src/app/globals.css +1064 -0
  63. package/templates/auth/src/app/layout.tsx +11 -0
  64. package/templates/auth/src/app/loading.tsx +15 -0
  65. package/templates/auth/src/app/not-found.tsx +26 -0
  66. package/templates/auth/src/app/page.tsx +46 -0
  67. package/templates/auth/src/app/sign-in/page.tsx +16 -0
  68. package/templates/auth/src/app/sign-up/page.tsx +16 -0
  69. package/templates/auth/src/components/auth-form.tsx +120 -0
  70. package/templates/auth/src/components/auth-shell.tsx +21 -0
  71. package/templates/auth/src/components/resource-links.tsx +78 -0
  72. package/templates/auth/src/components/sign-out-button.tsx +45 -0
  73. package/templates/auth/src/components/site-header.tsx +46 -0
  74. package/templates/auth/tsconfig.json +20 -0
  75. package/templates/basic/farm.config.ts +3 -1
  76. package/templates/basic/gitignore +23 -0
  77. package/templates/basic/package.json +4 -2
  78. package/templates/basic/pnpm-workspace.yaml +8 -0
  79. package/templates/basic/public/favicon.svg +13 -0
  80. package/templates/basic/src/app/globals.css +241 -0
  81. package/templates/basic/src/app/layout.tsx +6 -5
  82. package/templates/basic/src/app/page.tsx +20 -61
  83. package/templates/basic/src/components/resource-links.tsx +78 -0
  84. package/templates/basic/tsconfig.json +4 -0
  85. package/templates/better-auth/.env.example +3 -0
  86. package/templates/better-auth/README.md +87 -0
  87. package/templates/better-auth/farm.config.ts +32 -0
  88. package/templates/better-auth/gitignore +10 -0
  89. package/templates/better-auth/package.json +34 -0
  90. package/templates/better-auth/pnpm-workspace.yaml +13 -0
  91. package/templates/better-auth/src/app/dashboard/middleware.ts +15 -0
  92. package/templates/better-auth/src/app/dashboard/page.tsx +188 -0
  93. package/templates/better-auth/src/app/error.tsx +25 -0
  94. package/templates/better-auth/src/app/globals.css +1064 -0
  95. package/templates/better-auth/src/app/layout.tsx +11 -0
  96. package/templates/better-auth/src/app/loading.tsx +15 -0
  97. package/templates/better-auth/src/app/not-found.tsx +26 -0
  98. package/templates/better-auth/src/app/page.tsx +50 -0
  99. package/templates/better-auth/src/app/sign-in/page.tsx +16 -0
  100. package/templates/better-auth/src/app/sign-up/page.tsx +16 -0
  101. package/templates/better-auth/src/components/auth-form.tsx +120 -0
  102. package/templates/better-auth/src/components/auth-shell.tsx +21 -0
  103. package/templates/better-auth/src/components/resource-links.tsx +78 -0
  104. package/templates/better-auth/src/components/sign-out-button.tsx +45 -0
  105. package/templates/better-auth/src/components/site-header.tsx +46 -0
  106. package/templates/better-auth/src/lib/auth-client.ts +5 -0
  107. package/templates/better-auth/src/lib/auth.ts +50 -0
  108. package/templates/better-auth/src/lib/session.ts +8 -0
  109. package/templates/better-auth/tsconfig.json +20 -0
  110. package/templates/basic/src/app/about/page.tsx +0 -32
  111. 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,4 @@
1
+ import { createAPIClient } from "@farm.js/core/client";
2
+ import type { APIRouter } from "./api.generated";
3
+
4
+ export const api = createAPIClient<APIRouter>();
@@ -0,0 +1,7 @@
1
+ import type { POST as POST_greeting } from "../app/api/greeting/route";
2
+
3
+ export type APIRouter = {
4
+ greeting: {
5
+ post: typeof POST_greeting;
6
+ };
7
+ };
@@ -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,12 @@
1
+ import { defineConfig } from "@farm.js/core/config";
2
+ import { solid } from "@farm.js/solid";
3
+
4
+ export default defineConfig({
5
+ renderer: solid(),
6
+ theme: {
7
+ default: "dark",
8
+ },
9
+ deploy: {
10
+ target: "vercel",
11
+ },
12
+ });
@@ -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.31",
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.31",
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";
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,4 @@
1
+ import { createAPIClient } from "@farm.js/core/client";
2
+ import type { APIRouter } from "./api.generated";
3
+
4
+ export const api = createAPIClient<APIRouter>();
@@ -0,0 +1,7 @@
1
+ import type { POST as POST_greeting } from "../app/api/greeting/route";
2
+
3
+ export type APIRouter = {
4
+ greeting: {
5
+ post: typeof POST_greeting;
6
+ };
7
+ };
@@ -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,9 @@
1
+ import { defineConfig } from "@farm.js/core";
2
+ import { svelte } from "@farm.js/svelte";
3
+
4
+ export default defineConfig({
5
+ renderer: svelte(),
6
+ theme: {
7
+ default: "dark",
8
+ },
9
+ });
@@ -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.31",
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.31",
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";
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>