@farm.js/cli 0.1.0-beta.22 → 0.1.0-beta.24
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/dist/{add-integration-CdVfiPjG.mjs → add-integration-7hf9WI7e.mjs} +147 -140
- package/dist/add-integration-7hf9WI7e.mjs.map +1 -0
- package/dist/{add-integration-Xc0p-k-m.js → add-integration-D5mff3xX.js} +147 -140
- package/dist/add-integration-D5mff3xX.js.map +1 -0
- package/dist/add-integration.js +1 -1
- package/dist/add-integration.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/dist/add-integration-CdVfiPjG.mjs.map +0 -1
- package/dist/add-integration-Xc0p-k-m.js.map +0 -1
|
@@ -100,7 +100,7 @@ function aiChatUIFeature() {
|
|
|
100
100
|
],
|
|
101
101
|
needsApiClient: false,
|
|
102
102
|
notes: ["Open \"/integrations/ai\" to try the generated chat UI."],
|
|
103
|
-
files: () => [componentFile("ai-chat.tsx", aiChatTemplate()), integrationPageFile("ai", "AIChat")]
|
|
103
|
+
files: () => [componentFile("ai-chat.tsx", aiChatTemplate()), integrationPageFile("ai", "AIChat", "ai-chat")]
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
106
|
function supabaseAuthUIFeature() {
|
|
@@ -132,35 +132,25 @@ function workosAuthUIFeature() {
|
|
|
132
132
|
key: input.key,
|
|
133
133
|
provider: "WorkOS",
|
|
134
134
|
componentName: "WorkOSAuthPanel",
|
|
135
|
-
statusCall: "session
|
|
136
|
-
|
|
135
|
+
statusCall: "session",
|
|
136
|
+
statusMethod: "get",
|
|
137
|
+
logoutCall: "logout",
|
|
138
|
+
logoutMethod: "post",
|
|
137
139
|
loginHref: "/login?returnTo=/dashboard",
|
|
138
140
|
signupHref: "/signup?returnTo=/dashboard",
|
|
139
141
|
statusLabel: "Session"
|
|
140
|
-
})), integrationPageFile("workos", "WorkOSAuthPanel")]
|
|
142
|
+
})), integrationPageFile("workos", "WorkOSAuthPanel", "workos-auth-panel")]
|
|
141
143
|
};
|
|
142
144
|
}
|
|
143
145
|
function auth0AuthUIFeature() {
|
|
144
|
-
return {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
notes: ["Open \"/integrations/auth0\" to try the generated auth UI."],
|
|
153
|
-
files: (input) => [componentFile("auth0-auth-panel.tsx", hostedAuthTemplate({
|
|
154
|
-
key: input.key,
|
|
155
|
-
provider: "Auth0",
|
|
156
|
-
componentName: "Auth0AuthPanel",
|
|
157
|
-
statusCall: "profile.get",
|
|
158
|
-
logoutCall: "logout.get",
|
|
159
|
-
loginHref: "/auth/login?returnTo=/dashboard",
|
|
160
|
-
signupHref: "/auth/signup?returnTo=/dashboard",
|
|
161
|
-
statusLabel: "Profile"
|
|
162
|
-
})), integrationPageFile("auth0", "Auth0AuthPanel")]
|
|
163
|
-
};
|
|
146
|
+
return authRouteShellUIFeature({
|
|
147
|
+
provider: "auth0",
|
|
148
|
+
label: "Auth0",
|
|
149
|
+
componentName: "Auth0AuthPanel",
|
|
150
|
+
signInHref: "/auth/login?returnTo=/dashboard",
|
|
151
|
+
signUpHref: "/auth/signup?returnTo=/dashboard",
|
|
152
|
+
sessionHref: "/auth/profile"
|
|
153
|
+
});
|
|
164
154
|
}
|
|
165
155
|
function clerkAuthUIFeature() {
|
|
166
156
|
return authRouteShellUIFeature({
|
|
@@ -239,16 +229,18 @@ function jobsUIFeature(provider) {
|
|
|
239
229
|
function unkeyApiKeysUIFeature() {
|
|
240
230
|
return {
|
|
241
231
|
name: "unkey-api-keys",
|
|
242
|
-
description: "Unkey
|
|
243
|
-
components: [
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
232
|
+
description: "Unkey protected route UI",
|
|
233
|
+
components: ["badge", "card"],
|
|
234
|
+
needsApiClient: false,
|
|
235
|
+
notes: ["Open \"/integrations/unkey\" to test the generated protected API route."],
|
|
236
|
+
files: () => [
|
|
237
|
+
componentFile("unkey-api-keys-console.tsx", unkeyApiKeysTemplate()),
|
|
238
|
+
integrationPageFile("unkey", "UnkeyApiKeysConsole"),
|
|
239
|
+
{
|
|
240
|
+
path: path.join("src", "app", "api", "protected", "route.ts"),
|
|
241
|
+
source: unkeyProtectedRouteTemplate()
|
|
242
|
+
}
|
|
243
|
+
]
|
|
252
244
|
};
|
|
253
245
|
}
|
|
254
246
|
function billingUIFeature(input) {
|
|
@@ -278,6 +270,7 @@ function authRouteShellUIFeature(input) {
|
|
|
278
270
|
"button",
|
|
279
271
|
"card"
|
|
280
272
|
],
|
|
273
|
+
needsApiClient: false,
|
|
281
274
|
notes: [`Open "/integrations/${input.provider}" to try the generated auth UI.`],
|
|
282
275
|
files: () => [componentFile(`${input.provider}-auth-panel.tsx`, authRouteShellTemplate({
|
|
283
276
|
provider: input.label,
|
|
@@ -285,7 +278,7 @@ function authRouteShellUIFeature(input) {
|
|
|
285
278
|
signInHref: input.signInHref,
|
|
286
279
|
signUpHref: input.signUpHref,
|
|
287
280
|
sessionHref: input.sessionHref
|
|
288
|
-
})), integrationPageFile(input.provider, input.componentName)]
|
|
281
|
+
})), integrationPageFile(input.provider, input.componentName, input.provider === "authjs" ? "authjs-auth-panel" : void 0)]
|
|
289
282
|
};
|
|
290
283
|
}
|
|
291
284
|
function componentFile(fileName, source) {
|
|
@@ -294,11 +287,10 @@ function componentFile(fileName, source) {
|
|
|
294
287
|
source
|
|
295
288
|
};
|
|
296
289
|
}
|
|
297
|
-
function integrationPageFile(provider, componentName) {
|
|
298
|
-
const fileName = kebabCase(componentName);
|
|
290
|
+
function integrationPageFile(provider, componentName, sourceFileName = kebabCase(componentName)) {
|
|
299
291
|
return {
|
|
300
292
|
path: path.join("src", "app", "integrations", provider, "page.tsx"),
|
|
301
|
-
source: `import { ${componentName} } from "@/components/farm/${
|
|
293
|
+
source: `import { ${componentName} } from "@/components/farm/${sourceFileName}";
|
|
302
294
|
|
|
303
295
|
export default function ${componentName}Page() {
|
|
304
296
|
return <${componentName} />;
|
|
@@ -455,7 +447,7 @@ const UI_DEPENDENCIES = {
|
|
|
455
447
|
"tailwind-merge": "^3.3.1",
|
|
456
448
|
tailwindcss: "^4.1.18"
|
|
457
449
|
};
|
|
458
|
-
const SHADCN_THEME_CSS = `@custom-variant dark (&:
|
|
450
|
+
const SHADCN_THEME_CSS = `@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
|
459
451
|
|
|
460
452
|
@theme inline {
|
|
461
453
|
--color-background: var(--background);
|
|
@@ -481,7 +473,8 @@ const SHADCN_THEME_CSS = `@custom-variant dark (&:is(.dark *));
|
|
|
481
473
|
--radius-lg: var(--radius);
|
|
482
474
|
}
|
|
483
475
|
|
|
484
|
-
:root
|
|
476
|
+
:root,
|
|
477
|
+
[data-theme="light"] {
|
|
485
478
|
--radius: 0.5rem;
|
|
486
479
|
--background: oklch(1 0 0);
|
|
487
480
|
--foreground: oklch(0.145 0 0);
|
|
@@ -503,7 +496,7 @@ const SHADCN_THEME_CSS = `@custom-variant dark (&:is(.dark *));
|
|
|
503
496
|
--ring: oklch(0.708 0 0);
|
|
504
497
|
}
|
|
505
498
|
|
|
506
|
-
|
|
499
|
+
[data-theme="dark"] {
|
|
507
500
|
--background: oklch(0.145 0 0);
|
|
508
501
|
--foreground: oklch(0.985 0 0);
|
|
509
502
|
--card: oklch(0.205 0 0);
|
|
@@ -1106,12 +1099,17 @@ export function SupabaseAuthPanel() {
|
|
|
1106
1099
|
}
|
|
1107
1100
|
|
|
1108
1101
|
async function logout() {
|
|
1109
|
-
const response = await
|
|
1110
|
-
|
|
1111
|
-
|
|
1102
|
+
const response = await fetch("/auth/logout", {
|
|
1103
|
+
method: "POST",
|
|
1104
|
+
headers: { "content-type": "application/json" },
|
|
1105
|
+
body: JSON.stringify({ returnTo: "/" }),
|
|
1106
|
+
});
|
|
1107
|
+
const data = (await response.json()) as { redirectTo?: string; error?: string };
|
|
1108
|
+
if (data.redirectTo) {
|
|
1109
|
+
window.location.assign(data.redirectTo);
|
|
1112
1110
|
return;
|
|
1113
1111
|
}
|
|
1114
|
-
setStatus(
|
|
1112
|
+
setStatus(data.error ?? "Signed out");
|
|
1115
1113
|
}
|
|
1116
1114
|
|
|
1117
1115
|
return (
|
|
@@ -1170,7 +1168,7 @@ export function ${input.componentName}() {
|
|
|
1170
1168
|
|
|
1171
1169
|
async function refreshStatus() {
|
|
1172
1170
|
setPending(true);
|
|
1173
|
-
const response = await apiClient.${input.key}.${input.statusCall}();
|
|
1171
|
+
const response = await apiClient.${input.key}.${input.statusCall}.${input.statusMethod}();
|
|
1174
1172
|
if (response.error) {
|
|
1175
1173
|
setStatus(response.error.message);
|
|
1176
1174
|
} else {
|
|
@@ -1181,7 +1179,7 @@ export function ${input.componentName}() {
|
|
|
1181
1179
|
|
|
1182
1180
|
async function logout() {
|
|
1183
1181
|
setPending(true);
|
|
1184
|
-
const response = await apiClient.${input.key}.${input.logoutCall}();
|
|
1182
|
+
const response = await apiClient.${input.key}.${input.logoutCall}.${input.logoutMethod}();
|
|
1185
1183
|
if (response.data?.redirectTo) {
|
|
1186
1184
|
window.location.assign(response.data.redirectTo);
|
|
1187
1185
|
return;
|
|
@@ -1444,17 +1442,20 @@ import { apiClient } from "@/lib/api";
|
|
|
1444
1442
|
export function ResendEmailConsole() {
|
|
1445
1443
|
const [to, setTo] = React.useState("");
|
|
1446
1444
|
const [name, setName] = React.useState("Ada");
|
|
1447
|
-
const
|
|
1445
|
+
const templateId = "welcome" as const;
|
|
1448
1446
|
const [status, setStatus] = React.useState("Idle");
|
|
1449
1447
|
const [previewHtml, setPreviewHtml] = React.useState("");
|
|
1450
1448
|
|
|
1451
1449
|
async function loadTemplates() {
|
|
1452
|
-
const response = await apiClient.${key}.templates
|
|
1453
|
-
|
|
1450
|
+
const response = await apiClient.${key}.templates();
|
|
1451
|
+
const templates = Array.isArray(response.data)
|
|
1452
|
+
? (response.data as Array<{ id: string }>)
|
|
1453
|
+
: [];
|
|
1454
|
+
setStatus(response.error ? response.error.message : "Templates: " + templates.map((item) => item.id).join(", "));
|
|
1454
1455
|
}
|
|
1455
1456
|
|
|
1456
1457
|
async function preview() {
|
|
1457
|
-
const response = await apiClient.${key}.preview
|
|
1458
|
+
const response = await apiClient.${key}.preview({
|
|
1458
1459
|
body: {
|
|
1459
1460
|
templateId,
|
|
1460
1461
|
data: { name },
|
|
@@ -1469,7 +1470,7 @@ export function ResendEmailConsole() {
|
|
|
1469
1470
|
}
|
|
1470
1471
|
|
|
1471
1472
|
async function send() {
|
|
1472
|
-
const response = await apiClient.${key}.send
|
|
1473
|
+
const response = await apiClient.${key}.send({
|
|
1473
1474
|
body: {
|
|
1474
1475
|
templateId,
|
|
1475
1476
|
to,
|
|
@@ -1492,11 +1493,7 @@ export function ResendEmailConsole() {
|
|
|
1492
1493
|
<CardDescription>Template previews and delivery controls.</CardDescription>
|
|
1493
1494
|
</CardHeader>
|
|
1494
1495
|
<CardContent className="space-y-4">
|
|
1495
|
-
<div className="grid gap-4 sm:grid-cols-
|
|
1496
|
-
<div className="space-y-2">
|
|
1497
|
-
<Label htmlFor="templateId">Template</Label>
|
|
1498
|
-
<Input id="templateId" value={templateId} onChange={(event) => setTemplateId(event.target.value)} />
|
|
1499
|
-
</div>
|
|
1496
|
+
<div className="grid gap-4 sm:grid-cols-2">
|
|
1500
1497
|
<div className="space-y-2">
|
|
1501
1498
|
<Label htmlFor="to">To</Label>
|
|
1502
1499
|
<Input id="to" value={to} onChange={(event) => setTo(event.target.value)} />
|
|
@@ -1621,47 +1618,11 @@ export function ${`${pascalCase(provider)}JobsConsole`}() {
|
|
|
1621
1618
|
}
|
|
1622
1619
|
`;
|
|
1623
1620
|
}
|
|
1624
|
-
function unkeyApiKeysTemplate(
|
|
1625
|
-
return `
|
|
1626
|
-
|
|
1627
|
-
import * as React from "react";
|
|
1628
|
-
import { Badge } from "@/components/ui/badge";
|
|
1629
|
-
import { Button } from "@/components/ui/button";
|
|
1621
|
+
function unkeyApiKeysTemplate() {
|
|
1622
|
+
return `import { Badge } from "@/components/ui/badge";
|
|
1630
1623
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
1631
|
-
import { Input } from "@/components/ui/input";
|
|
1632
|
-
import { Label } from "@/components/ui/label";
|
|
1633
|
-
import { apiClient } from "@/lib/api";
|
|
1634
1624
|
|
|
1635
1625
|
export function UnkeyApiKeysConsole() {
|
|
1636
|
-
const [name, setName] = React.useState("Development key");
|
|
1637
|
-
const [prefix, setPrefix] = React.useState("farm");
|
|
1638
|
-
const [apiKey, setApiKey] = React.useState("");
|
|
1639
|
-
const [status, setStatus] = React.useState("Idle");
|
|
1640
|
-
|
|
1641
|
-
async function createKey() {
|
|
1642
|
-
const response = await apiClient.${key}.createKey.post({
|
|
1643
|
-
body: {
|
|
1644
|
-
name,
|
|
1645
|
-
prefix,
|
|
1646
|
-
},
|
|
1647
|
-
});
|
|
1648
|
-
if (response.error) {
|
|
1649
|
-
setStatus(response.error.message);
|
|
1650
|
-
return;
|
|
1651
|
-
}
|
|
1652
|
-
setApiKey(response.data?.key ?? "");
|
|
1653
|
-
setStatus("Created " + (response.data?.keyId ?? "key"));
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
async function verifyKey() {
|
|
1657
|
-
const response = await apiClient.${key}.verifyKey.post({
|
|
1658
|
-
body: {
|
|
1659
|
-
key: apiKey,
|
|
1660
|
-
},
|
|
1661
|
-
});
|
|
1662
|
-
setStatus(response.error ? response.error.message : response.data?.valid ? "Valid key" : "Invalid key");
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
1626
|
return (
|
|
1666
1627
|
<main className="min-h-screen bg-background px-6 py-12 text-foreground">
|
|
1667
1628
|
<section className="mx-auto flex w-full max-w-3xl flex-col gap-6">
|
|
@@ -1671,29 +1632,16 @@ export function UnkeyApiKeysConsole() {
|
|
|
1671
1632
|
</div>
|
|
1672
1633
|
<Card>
|
|
1673
1634
|
<CardHeader>
|
|
1674
|
-
<CardTitle className="text-xl">
|
|
1675
|
-
<CardDescription>
|
|
1635
|
+
<CardTitle className="text-xl">Protected API</CardTitle>
|
|
1636
|
+
<CardDescription>Requests are verified by Unkey before the route runs.</CardDescription>
|
|
1676
1637
|
</CardHeader>
|
|
1677
|
-
<CardContent className="space-y-
|
|
1678
|
-
<
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
<Label htmlFor="prefix">Prefix</Label>
|
|
1685
|
-
<Input id="prefix" value={prefix} onChange={(event) => setPrefix(event.target.value)} />
|
|
1686
|
-
</div>
|
|
1687
|
-
</div>
|
|
1688
|
-
<div className="space-y-2">
|
|
1689
|
-
<Label htmlFor="apiKey">API key</Label>
|
|
1690
|
-
<Input id="apiKey" value={apiKey} onChange={(event) => setApiKey(event.target.value)} />
|
|
1691
|
-
</div>
|
|
1692
|
-
<p className="rounded-md border bg-muted/30 px-3 py-2 text-sm">{status}</p>
|
|
1693
|
-
<div className="flex flex-wrap gap-2">
|
|
1694
|
-
<Button type="button" onClick={() => void createKey()}>Create key</Button>
|
|
1695
|
-
<Button type="button" variant="outline" onClick={() => void verifyKey()}>Verify</Button>
|
|
1696
|
-
</div>
|
|
1638
|
+
<CardContent className="space-y-3">
|
|
1639
|
+
<code className="block overflow-x-auto rounded-md border bg-muted/30 p-3 text-xs">
|
|
1640
|
+
curl http://localhost:3000/api/protected -H "Authorization: Bearer YOUR_KEY"
|
|
1641
|
+
</code>
|
|
1642
|
+
<p className="text-sm text-muted-foreground">
|
|
1643
|
+
Create and rotate keys from trusted server code or the Unkey dashboard.
|
|
1644
|
+
</p>
|
|
1697
1645
|
</CardContent>
|
|
1698
1646
|
</Card>
|
|
1699
1647
|
</section>
|
|
@@ -1702,6 +1650,15 @@ export function UnkeyApiKeysConsole() {
|
|
|
1702
1650
|
}
|
|
1703
1651
|
`;
|
|
1704
1652
|
}
|
|
1653
|
+
function unkeyProtectedRouteTemplate() {
|
|
1654
|
+
return `export function GET() {
|
|
1655
|
+
return Response.json({
|
|
1656
|
+
ok: true,
|
|
1657
|
+
message: "Valid Unkey API key.",
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
`;
|
|
1661
|
+
}
|
|
1705
1662
|
function pascalCase(input) {
|
|
1706
1663
|
return input.split(/[^A-Za-z0-9]+/g).filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
|
|
1707
1664
|
}
|
|
@@ -1729,6 +1686,7 @@ const PROVIDERS = [
|
|
|
1729
1686
|
"chat"
|
|
1730
1687
|
],
|
|
1731
1688
|
defaultKey: "chat",
|
|
1689
|
+
packageName: "@farm.js/ai",
|
|
1732
1690
|
fileName: "chat",
|
|
1733
1691
|
exportName: "POST",
|
|
1734
1692
|
description: "Vercel AI SDK chat route",
|
|
@@ -1739,7 +1697,7 @@ const PROVIDERS = [
|
|
|
1739
1697
|
"No farm.config integration wiring is required for this route."
|
|
1740
1698
|
],
|
|
1741
1699
|
ui: aiChatUIFeature(),
|
|
1742
|
-
template: () => `import { aiChatRoute } from "@farm.js/
|
|
1700
|
+
template: () => `import { aiChatRoute } from "@farm.js/ai";
|
|
1743
1701
|
|
|
1744
1702
|
export const POST = aiChatRoute({
|
|
1745
1703
|
model: "openai/gpt-4o-mini",
|
|
@@ -1755,17 +1713,19 @@ export const POST = aiChatRoute({
|
|
|
1755
1713
|
"stripe-billing"
|
|
1756
1714
|
],
|
|
1757
1715
|
defaultKey: "billing",
|
|
1716
|
+
packageName: "@farm.js/stripe",
|
|
1758
1717
|
fileName: "stripe",
|
|
1759
1718
|
exportName: "stripeIntegration",
|
|
1760
1719
|
description: "Stripe billing and checkout routes",
|
|
1761
1720
|
env: ["STRIPE_SECRET_KEY", "STRIPE_WEBHOOK_SECRET"],
|
|
1762
|
-
template: () => `import {
|
|
1721
|
+
template: () => `import type { FarmIntegrationLogEvent } from "@farm.js/core";
|
|
1722
|
+
import { stripe } from "@farm.js/stripe";
|
|
1763
1723
|
|
|
1764
1724
|
export const stripeIntegration = stripe({
|
|
1765
1725
|
secretKey: process.env.STRIPE_SECRET_KEY,
|
|
1766
1726
|
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
|
|
1767
1727
|
products: [],
|
|
1768
|
-
log(event) {
|
|
1728
|
+
log(event: FarmIntegrationLogEvent) {
|
|
1769
1729
|
console.log("[stripe]", event.phase, event.route?.path || "none");
|
|
1770
1730
|
},
|
|
1771
1731
|
});
|
|
@@ -1776,6 +1736,7 @@ export const stripeIntegration = stripe({
|
|
|
1776
1736
|
provider: "supabase",
|
|
1777
1737
|
aliases: ["auth-supabase", "supabase-auth"],
|
|
1778
1738
|
defaultKey: "auth",
|
|
1739
|
+
packageName: "@farm.js/supabase",
|
|
1779
1740
|
fileName: "supabase",
|
|
1780
1741
|
exportName: "supabaseIntegration",
|
|
1781
1742
|
description: "Supabase auth routes and middleware",
|
|
@@ -1785,7 +1746,7 @@ export const stripeIntegration = stripe({
|
|
|
1785
1746
|
"APP_BASE_URL"
|
|
1786
1747
|
],
|
|
1787
1748
|
ui: supabaseAuthUIFeature(),
|
|
1788
|
-
template: () => `import { supabase } from "@farm.js/
|
|
1749
|
+
template: () => `import { supabase } from "@farm.js/supabase";
|
|
1789
1750
|
|
|
1790
1751
|
export const supabaseIntegration = supabase({
|
|
1791
1752
|
callbackUrl: \`\${process.env.APP_BASE_URL || "http://localhost:3000"}/auth/callback\`,
|
|
@@ -1804,6 +1765,7 @@ export const supabaseIntegration = supabase({
|
|
|
1804
1765
|
provider: "workos",
|
|
1805
1766
|
aliases: ["auth-workos", "workos-auth"],
|
|
1806
1767
|
defaultKey: "auth",
|
|
1768
|
+
packageName: "@farm.js/workos",
|
|
1807
1769
|
fileName: "workos",
|
|
1808
1770
|
exportName: "workosIntegration",
|
|
1809
1771
|
description: "WorkOS auth routes and protected route middleware",
|
|
@@ -1813,7 +1775,7 @@ export const supabaseIntegration = supabase({
|
|
|
1813
1775
|
"WORKOS_COOKIE_PASSWORD"
|
|
1814
1776
|
],
|
|
1815
1777
|
ui: workosAuthUIFeature(),
|
|
1816
|
-
template: () => `import { workos } from "@farm.js/
|
|
1778
|
+
template: () => `import { workos } from "@farm.js/workos";
|
|
1817
1779
|
|
|
1818
1780
|
export const workosIntegration = workos({
|
|
1819
1781
|
protectedRoutes: ["/dashboard(.*)"],
|
|
@@ -1827,6 +1789,7 @@ export const workosIntegration = workos({
|
|
|
1827
1789
|
provider: "auth0",
|
|
1828
1790
|
aliases: ["auth-auth0", "auth0-auth"],
|
|
1829
1791
|
defaultKey: "auth",
|
|
1792
|
+
packageName: "@farm.js/auth0",
|
|
1830
1793
|
fileName: "auth0",
|
|
1831
1794
|
exportName: "auth0Integration",
|
|
1832
1795
|
description: "Auth0 login, callback, logout, and profile routes",
|
|
@@ -1837,7 +1800,7 @@ export const workosIntegration = workos({
|
|
|
1837
1800
|
"AUTH0_SECRET"
|
|
1838
1801
|
],
|
|
1839
1802
|
ui: auth0AuthUIFeature(),
|
|
1840
|
-
template: () => `import { auth0 } from "@farm.js/
|
|
1803
|
+
template: () => `import { auth0 } from "@farm.js/auth0";
|
|
1841
1804
|
|
|
1842
1805
|
export const auth0Integration = auth0({
|
|
1843
1806
|
callbackUrl: \`\${process.env.APP_BASE_URL || "http://localhost:3000"}/auth/callback\`,
|
|
@@ -1852,12 +1815,14 @@ export const auth0Integration = auth0({
|
|
|
1852
1815
|
provider: "clerk",
|
|
1853
1816
|
aliases: ["auth-clerk", "clerk-auth"],
|
|
1854
1817
|
defaultKey: "auth",
|
|
1818
|
+
packageName: "@farm.js/clerk",
|
|
1855
1819
|
fileName: "clerk",
|
|
1856
1820
|
exportName: "clerkIntegration",
|
|
1857
1821
|
description: "Clerk auth provider and protected route middleware",
|
|
1858
1822
|
env: ["NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY", "CLERK_SECRET_KEY"],
|
|
1823
|
+
dependencies: { "@clerk/react": "^6.1.0" },
|
|
1859
1824
|
ui: clerkAuthUIFeature(),
|
|
1860
|
-
template: () => `import { clerk } from "@farm.js/
|
|
1825
|
+
template: () => `import { clerk } from "@farm.js/clerk";
|
|
1861
1826
|
|
|
1862
1827
|
export const clerkIntegration = clerk({
|
|
1863
1828
|
signInUrl: "/sign-in",
|
|
@@ -1873,6 +1838,7 @@ export const clerkIntegration = clerk({
|
|
|
1873
1838
|
provider: "resend",
|
|
1874
1839
|
aliases: ["email", "resend-email"],
|
|
1875
1840
|
defaultKey: "email",
|
|
1841
|
+
packageName: "@farm.js/email",
|
|
1876
1842
|
fileName: "resend",
|
|
1877
1843
|
exportName: "resendIntegration",
|
|
1878
1844
|
description: "Resend email send, preview, schedule, and webhook routes",
|
|
@@ -1883,7 +1849,7 @@ export const clerkIntegration = clerk({
|
|
|
1883
1849
|
],
|
|
1884
1850
|
ui: resendEmailUIFeature(),
|
|
1885
1851
|
template: () => `import { createElement } from "react";
|
|
1886
|
-
import { resend, template } from "@farm.js/
|
|
1852
|
+
import { resend, template } from "@farm.js/email";
|
|
1887
1853
|
|
|
1888
1854
|
function WelcomeEmail(props: { name: string }) {
|
|
1889
1855
|
return createElement("div", null, \`Welcome \${props.name}\`);
|
|
@@ -1922,6 +1888,7 @@ export const resendIntegration = resend({
|
|
|
1922
1888
|
provider: "jobs-inngest",
|
|
1923
1889
|
aliases: ["inngest", "jobs"],
|
|
1924
1890
|
defaultKey: "jobs",
|
|
1891
|
+
packageName: "@farm.js/jobs",
|
|
1925
1892
|
fileName: "jobs-inngest",
|
|
1926
1893
|
exportName: "jobsIntegration",
|
|
1927
1894
|
description: "Jobs integration backed by Inngest",
|
|
@@ -1932,7 +1899,7 @@ export const resendIntegration = resend({
|
|
|
1932
1899
|
],
|
|
1933
1900
|
notes: ["Add tasks to jobTasks before using the generated jobs API."],
|
|
1934
1901
|
ui: jobsUIFeature("inngest"),
|
|
1935
|
-
template: () => `import { defineTasks, inngest, jobs } from "@farm.js/
|
|
1902
|
+
template: () => `import { defineTasks, inngest, jobs } from "@farm.js/jobs";
|
|
1936
1903
|
|
|
1937
1904
|
export const jobTasks = defineTasks({});
|
|
1938
1905
|
|
|
@@ -1957,6 +1924,7 @@ export const jobsIntegration = jobs({
|
|
|
1957
1924
|
"jobs-triggerdev"
|
|
1958
1925
|
],
|
|
1959
1926
|
defaultKey: "jobs",
|
|
1927
|
+
packageName: "@farm.js/jobs",
|
|
1960
1928
|
fileName: "jobs-trigger",
|
|
1961
1929
|
exportName: "jobsIntegration",
|
|
1962
1930
|
description: "Jobs integration backed by Trigger.dev",
|
|
@@ -1967,7 +1935,7 @@ export const jobsIntegration = jobs({
|
|
|
1967
1935
|
],
|
|
1968
1936
|
notes: ["Add tasks to jobTasks before using the generated jobs API."],
|
|
1969
1937
|
ui: jobsUIFeature("trigger"),
|
|
1970
|
-
template: () => `import { defineTasks, jobs, trigger } from "@farm.js/
|
|
1938
|
+
template: () => `import { defineTasks, jobs, trigger } from "@farm.js/jobs";
|
|
1971
1939
|
|
|
1972
1940
|
export const jobTasks = defineTasks({});
|
|
1973
1941
|
|
|
@@ -1988,6 +1956,7 @@ export const jobsIntegration = jobs({
|
|
|
1988
1956
|
provider: "polar",
|
|
1989
1957
|
aliases: ["polar-billing", "billing-polar"],
|
|
1990
1958
|
defaultKey: "billing",
|
|
1959
|
+
packageName: "@farm.js/polar",
|
|
1991
1960
|
fileName: "polar",
|
|
1992
1961
|
exportName: "polarIntegration",
|
|
1993
1962
|
description: "Polar billing and checkout routes",
|
|
@@ -1999,9 +1968,9 @@ export const jobsIntegration = jobs({
|
|
|
1999
1968
|
notes: ["Replace resolveBillingOwner with your app user or organization lookup."],
|
|
2000
1969
|
ui: polarBillingUIFeature(),
|
|
2001
1970
|
template: () => `import type { FarmIntegrationHandlerContext } from "@farm.js/core";
|
|
2002
|
-
import { polar } from "@farm.js/
|
|
1971
|
+
import { polar } from "@farm.js/polar";
|
|
2003
1972
|
|
|
2004
|
-
|
|
1973
|
+
function resolveBillingOwner(_context: FarmIntegrationHandlerContext): never {
|
|
2005
1974
|
throw new Error("Configure Polar billing owner resolution for your app.");
|
|
2006
1975
|
}
|
|
2007
1976
|
|
|
@@ -2029,6 +1998,7 @@ export const polarIntegration = polar({
|
|
|
2029
1998
|
provider: "autumn",
|
|
2030
1999
|
aliases: ["autumn-billing", "billing-autumn"],
|
|
2031
2000
|
defaultKey: "billing",
|
|
2001
|
+
packageName: "@farm.js/autumn",
|
|
2032
2002
|
fileName: "autumn",
|
|
2033
2003
|
exportName: "autumnIntegration",
|
|
2034
2004
|
description: "Autumn billing and checkout routes",
|
|
@@ -2040,9 +2010,9 @@ export const polarIntegration = polar({
|
|
|
2040
2010
|
notes: ["Replace resolveBillingOwner with your app user or organization lookup."],
|
|
2041
2011
|
ui: autumnBillingUIFeature(),
|
|
2042
2012
|
template: () => `import type { FarmIntegrationHandlerContext } from "@farm.js/core";
|
|
2043
|
-
import { autumn } from "@farm.js/
|
|
2013
|
+
import { autumn } from "@farm.js/autumn";
|
|
2044
2014
|
|
|
2045
|
-
|
|
2015
|
+
function resolveBillingOwner(_context: FarmIntegrationHandlerContext): never {
|
|
2046
2016
|
throw new Error("Configure Autumn billing owner resolution for your app.");
|
|
2047
2017
|
}
|
|
2048
2018
|
|
|
@@ -2069,6 +2039,7 @@ export const autumnIntegration = autumn({
|
|
|
2069
2039
|
provider: "better-auth",
|
|
2070
2040
|
aliases: ["betterauth", "auth-better-auth"],
|
|
2071
2041
|
defaultKey: "auth",
|
|
2042
|
+
packageName: "@farm.js/better-auth",
|
|
2072
2043
|
fileName: "better-auth",
|
|
2073
2044
|
exportName: "betterAuthIntegration",
|
|
2074
2045
|
description: "Better Auth route adapter",
|
|
@@ -2123,7 +2094,7 @@ better-auth.sqlite-wal
|
|
|
2123
2094
|
}
|
|
2124
2095
|
],
|
|
2125
2096
|
ui: betterAuthUIFeature(),
|
|
2126
|
-
template: () => `import { betterAuth } from "@farm.js/
|
|
2097
|
+
template: () => `import { betterAuth } from "@farm.js/better-auth";
|
|
2127
2098
|
import { auth } from "../auth.ts";
|
|
2128
2099
|
|
|
2129
2100
|
export const betterAuthIntegration = betterAuth({
|
|
@@ -2142,13 +2113,45 @@ export const betterAuthIntegration = betterAuth({
|
|
|
2142
2113
|
"next-auth"
|
|
2143
2114
|
],
|
|
2144
2115
|
defaultKey: "auth",
|
|
2116
|
+
packageName: "@farm.js/authjs",
|
|
2145
2117
|
fileName: "authjs",
|
|
2146
2118
|
exportName: "authjsIntegration",
|
|
2147
2119
|
description: "Auth.js route adapter",
|
|
2148
|
-
env: [
|
|
2149
|
-
|
|
2120
|
+
env: [
|
|
2121
|
+
"AUTH_SECRET",
|
|
2122
|
+
"AUTH_GITHUB_ID",
|
|
2123
|
+
"AUTH_GITHUB_SECRET"
|
|
2124
|
+
],
|
|
2125
|
+
dependencies: { "@auth/core": "0.34.3" },
|
|
2126
|
+
setupFiles: [{
|
|
2127
|
+
path: "src/lib/auth.ts",
|
|
2128
|
+
source: () => `import { Auth } from "@auth/core";
|
|
2129
|
+
import GitHub from "@auth/core/providers/github";
|
|
2130
|
+
|
|
2131
|
+
const config = {
|
|
2132
|
+
providers: [
|
|
2133
|
+
GitHub({
|
|
2134
|
+
clientId: process.env.AUTH_GITHUB_ID!,
|
|
2135
|
+
clientSecret: process.env.AUTH_GITHUB_SECRET!,
|
|
2136
|
+
}),
|
|
2137
|
+
],
|
|
2138
|
+
secret: process.env.AUTH_SECRET,
|
|
2139
|
+
trustHost: true,
|
|
2140
|
+
};
|
|
2141
|
+
|
|
2142
|
+
const handler = (request: Request) => Auth(request, config);
|
|
2143
|
+
|
|
2144
|
+
export const auth = {
|
|
2145
|
+
handlers: {
|
|
2146
|
+
GET: handler,
|
|
2147
|
+
POST: handler,
|
|
2148
|
+
},
|
|
2149
|
+
};
|
|
2150
|
+
`
|
|
2151
|
+
}],
|
|
2152
|
+
notes: ["The generated Auth.js instance uses GitHub OAuth through @auth/core; add or replace providers in src/lib/auth.ts."],
|
|
2150
2153
|
ui: authjsUIFeature(),
|
|
2151
|
-
template: () => `import { authjs } from "@farm.js/
|
|
2154
|
+
template: () => `import { authjs } from "@farm.js/authjs";
|
|
2152
2155
|
import { auth } from "../auth.ts";
|
|
2153
2156
|
|
|
2154
2157
|
export const authjsIntegration = authjs({
|
|
@@ -2168,6 +2171,7 @@ export const authjsIntegration = authjs({
|
|
|
2168
2171
|
"unkey-api-keys"
|
|
2169
2172
|
],
|
|
2170
2173
|
defaultKey: "apiKeys",
|
|
2174
|
+
packageName: "@farm.js/unkey",
|
|
2171
2175
|
fileName: "unkey",
|
|
2172
2176
|
exportName: "unkeyIntegration",
|
|
2173
2177
|
description: "Unkey API key creation, verification, and route protection",
|
|
@@ -2177,7 +2181,7 @@ export const authjsIntegration = authjs({
|
|
|
2177
2181
|
"UNKEY_BASE_URL"
|
|
2178
2182
|
],
|
|
2179
2183
|
ui: unkeyApiKeysUIFeature(),
|
|
2180
|
-
template: () => `import { unkey } from "@farm.js/
|
|
2184
|
+
template: () => `import { unkey } from "@farm.js/unkey";
|
|
2181
2185
|
|
|
2182
2186
|
export const unkeyIntegration = unkey({
|
|
2183
2187
|
rootKey: process.env.UNKEY_ROOT_KEY,
|
|
@@ -2194,6 +2198,7 @@ export const unkeyIntegration = unkey({
|
|
|
2194
2198
|
function listFarmIntegrationProviders() {
|
|
2195
2199
|
return PROVIDERS.map((provider) => ({
|
|
2196
2200
|
name: provider.provider,
|
|
2201
|
+
packageName: provider.packageName,
|
|
2197
2202
|
aliases: [...provider.aliases],
|
|
2198
2203
|
defaultKey: provider.defaultKey,
|
|
2199
2204
|
description: provider.description,
|
|
@@ -2429,7 +2434,7 @@ async function updatePackageJson(input) {
|
|
|
2429
2434
|
const devDependencies = missingDependencies(manifest, input.definition.devDependencies);
|
|
2430
2435
|
manifest.dependencies = {
|
|
2431
2436
|
...manifest.dependencies,
|
|
2432
|
-
...hasPackageDependency(manifest,
|
|
2437
|
+
...hasPackageDependency(manifest, input.definition.packageName) ? {} : { [input.definition.packageName]: getFarmIntegrationVersion(manifest) },
|
|
2433
2438
|
...dependencies
|
|
2434
2439
|
};
|
|
2435
2440
|
if (Object.keys(devDependencies).length) manifest.devDependencies = {
|
|
@@ -2512,8 +2517,10 @@ function findFarmConfig(root) {
|
|
|
2512
2517
|
function hasPackageDependency(manifest, dependency) {
|
|
2513
2518
|
return dependency in (manifest.dependencies || {}) || dependency in (manifest.devDependencies || {}) || dependency in (manifest.peerDependencies || {}) || dependency in (manifest.optionalDependencies || {});
|
|
2514
2519
|
}
|
|
2515
|
-
function
|
|
2516
|
-
|
|
2520
|
+
function getFarmIntegrationVersion(manifest) {
|
|
2521
|
+
const farmCoreVersion = manifest.dependencies?.["@farm.js/core"] ?? manifest.devDependencies?.["@farm.js/core"] ?? manifest.peerDependencies?.["@farm.js/core"] ?? manifest.optionalDependencies?.["@farm.js/core"];
|
|
2522
|
+
if (!farmCoreVersion) return "latest";
|
|
2523
|
+
return farmCoreVersion.startsWith("workspace:") ? "workspace:*" : farmCoreVersion;
|
|
2517
2524
|
}
|
|
2518
2525
|
function toImportPath(relativePath) {
|
|
2519
2526
|
const normalized = relativePath.split(path.sep).join("/");
|
|
@@ -2525,4 +2532,4 @@ function escapeRegExp(input) {
|
|
|
2525
2532
|
//#endregion
|
|
2526
2533
|
export { listFarmIntegrationProviders as n, addFarmIntegration as t };
|
|
2527
2534
|
|
|
2528
|
-
//# sourceMappingURL=add-integration-
|
|
2535
|
+
//# sourceMappingURL=add-integration-7hf9WI7e.mjs.map
|