@farm.js/create-app 0.1.1-beta.1 → 0.1.1-beta.4

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 CHANGED
@@ -5,7 +5,7 @@ Create a new FARMJS application
5
5
  See [Stability and Support](https://farmjs.dev/docs/stability) for what this package guarantees.
6
6
 
7
7
  ```bash
8
- PNPM_CONFIG_DLX_CACHE_MAX_AGE=0 PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE='["@farm.js/*"]' pnpm create @farm.js/app my-app --template basic
8
+ pnpm create @farm.js/app my-app --template basic
9
9
  cd my-app
10
10
  pnpm dev
11
11
  ```
@@ -15,13 +15,19 @@ automatically. Every starter also registers the official
15
15
  [`@farm.js/devtools`](https://farmjs.dev/docs/plugins/devtools) workspace, available at
16
16
  `/__farm/devtools` (or `Command/Ctrl + Shift + .`) during `pnpm dev`. The command explicitly selects the minimal Basic starter. Use `pnpm create`, not
17
17
  `pnpm add`; pnpm resolves this initializer command to the published `@farm.js/create-app` package.
18
- `PNPM_CONFIG_DLX_CACHE_MAX_AGE=0` refreshes pnpm's one-day `create`/`dlx` cache so the `beta`
19
- dist-tag is resolved on every run. `PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE` keeps pnpm's default
20
- release-age protection enabled for third-party packages while allowing newly published
21
- `@farm.js/*` betas. Generated pnpm projects preserve that scoped exclusion. Pass `--skip-install`
22
- when you only want to generate the project files.
18
+ Pass `--skip-install` when you only want to generate the project files.
19
+
20
+ Right after a release, pnpm can still start the previous initializer: its `create` cache lasts a
21
+ day, and pnpm 11's default release-age policy holds back packages published in the last day. Set
22
+ both for the shell, then run the command again:
23
+
24
+ ```bash
25
+ export PNPM_CONFIG_DLX_CACHE_MAX_AGE=0
26
+ export PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE='["@farm.js/*"]'
27
+ pnpm create @farm.js/app my-app --template basic
28
+ ```
23
29
 
24
- In PowerShell, set the same variables before running the command:
30
+ In PowerShell:
25
31
 
26
32
  ```powershell
27
33
  $env:PNPM_CONFIG_DLX_CACHE_MAX_AGE = "0"
@@ -32,7 +38,7 @@ pnpm create @farm.js/app my-app --template basic
32
38
  Choose React, Preact, Solid, Vue, or Svelte for the Basic and Better Auth starters:
33
39
 
34
40
  ```bash
35
- PNPM_CONFIG_DLX_CACHE_MAX_AGE=0 PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE='["@farm.js/*"]' pnpm create @farm.js/app my-app --template better-auth --renderer solid
41
+ pnpm create @farm.js/app my-app --template better-auth --renderer solid
36
42
  ```
37
43
 
38
44
  React remains the default when `--renderer` is omitted. The interactive Basic and Better Auth
@@ -41,7 +47,7 @@ flows also offer a renderer chooser.
41
47
  List every starter:
42
48
 
43
49
  ```bash
44
- PNPM_CONFIG_DLX_CACHE_MAX_AGE=0 PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE='["@farm.js/*"]' pnpm create @farm.js/app --list-templates
50
+ pnpm create @farm.js/app --list-templates
45
51
  ```
46
52
 
47
53
  Available templates:
@@ -56,7 +62,7 @@ home page, and setup documentation. Better Auth has renderer-native UI for all f
56
62
  other integration templates currently use React. For example:
57
63
 
58
64
  ```bash
59
- PNPM_CONFIG_DLX_CACHE_MAX_AGE=0 PNPM_CONFIG_MINIMUM_RELEASE_AGE_EXCLUDE='["@farm.js/*"]' pnpm create @farm.js/app stripe-app --template stripe
65
+ pnpm create @farm.js/app stripe-app --template stripe
60
66
  ```
61
67
 
62
68
  See the [FARMJS repository](https://github.com/farming-labs/farm.js) for documentation, examples, and support.
package/dist/index.js CHANGED
@@ -437,6 +437,16 @@ function sanityContentUIFeature() {
437
437
  files: () => [componentFile("sanity-content-console.tsx", sanityContentTemplate()), integrationPageFile("sanity", "SanityContentConsole")]
438
438
  };
439
439
  }
440
+ function strapiContentUIFeature() {
441
+ return {
442
+ name: "strapi-content",
443
+ description: "Strapi content list UI",
444
+ components: ["badge", "card"],
445
+ needsApiClient: false,
446
+ notes: ["Open \"/integrations/strapi\" to check the Strapi connection."],
447
+ files: () => [componentFile("strapi-content-console.tsx", strapiContentTemplate()), integrationPageFile("strapi", "StrapiContentConsole")]
448
+ };
449
+ }
440
450
  function billingUIFeature(input) {
441
451
  return {
442
452
  name: `${input.provider}-billing`,
@@ -1682,30 +1692,48 @@ export function UnkeyApiKeysConsole() {
1682
1692
  `;
1683
1693
  }
1684
1694
  function sanityContentTemplate() {
1695
+ return contentConsoleTemplate({
1696
+ componentName: "SanityContentConsole",
1697
+ label: "Sanity",
1698
+ description: "Query documents with createServerQuery and invalidate them from the Sanity webhook.",
1699
+ example: "cms.fetch('*[_type == "post"]{\"{\"} title {\"}\"}')",
1700
+ webhook: "Point a Sanity webhook at /api/sanity/webhook to keep cached pages fresh."
1701
+ });
1702
+ }
1703
+ function strapiContentTemplate() {
1704
+ return contentConsoleTemplate({
1705
+ componentName: "StrapiContentConsole",
1706
+ label: "Strapi",
1707
+ description: "Query typed documents from server queries and invalidate them from the Strapi webhook.",
1708
+ example: "createStrapiCollection(cms, "articles").find()",
1709
+ webhook: "Send the configured secret header to /api/strapi/webhook when content changes."
1710
+ });
1711
+ }
1712
+ function contentConsoleTemplate(input) {
1685
1713
  return `import { Badge } from "@/components/ui/badge";
1686
1714
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
1687
1715
 
1688
- export function SanityContentConsole() {
1716
+ export function ${input.componentName}() {
1689
1717
  return (
1690
1718
  <main className="min-h-screen bg-background px-6 py-12 text-foreground">
1691
1719
  <section className="mx-auto flex w-full max-w-3xl flex-col gap-6">
1692
1720
  <div className="space-y-3">
1693
- <Badge variant="secondary">Sanity</Badge>
1721
+ <Badge variant="secondary">${input.label}</Badge>
1694
1722
  <h1 className="text-3xl font-semibold tracking-normal">Content</h1>
1695
1723
  </div>
1696
1724
  <Card>
1697
1725
  <CardHeader>
1698
- <CardTitle className="text-xl">Connected to Sanity</CardTitle>
1726
+ <CardTitle className="text-xl">Connected to ${input.label}</CardTitle>
1699
1727
  <CardDescription>
1700
- Query documents with createServerQuery and invalidate them from the Sanity webhook.
1728
+ ${input.description}
1701
1729
  </CardDescription>
1702
1730
  </CardHeader>
1703
1731
  <CardContent className="space-y-3">
1704
1732
  <code className="block overflow-x-auto rounded-md border bg-muted/30 p-3 text-xs">
1705
- cms.fetch(&apos;*[_type == &quot;post&quot;]{"{"} title {"}"}&apos;)
1733
+ ${input.example}
1706
1734
  </code>
1707
1735
  <p className="text-sm text-muted-foreground">
1708
- Point a Sanity webhook at /api/sanity/webhook to keep cached pages fresh.
1736
+ ${input.webhook}
1709
1737
  </p>
1710
1738
  </CardContent>
1711
1739
  </Card>
@@ -2294,6 +2322,41 @@ export const sanityIntegration = sanity({
2294
2322
  console.log("[sanity]", event.phase, event.route?.path || "none");
2295
2323
  },
2296
2324
  });
2325
+ `
2326
+ },
2327
+ {
2328
+ provider: "strapi",
2329
+ aliases: ["strapi-cms"],
2330
+ defaultKey: "cms",
2331
+ packageName: "@farm.js/strapi",
2332
+ fileName: "strapi",
2333
+ exportName: "strapiIntegration",
2334
+ description: "Strapi content with typed reads, responsive media, and webhook invalidation",
2335
+ env: [
2336
+ "STRAPI_API_URL",
2337
+ "STRAPI_API_TOKEN",
2338
+ "STRAPI_MEDIA_URL",
2339
+ "STRAPI_WEBHOOK_SECRET"
2340
+ ],
2341
+ dependencies: { "@strapi/client": "^1.6.2" },
2342
+ ui: strapiContentUIFeature(),
2343
+ template: () => `import { strapi } from "@farm.js/strapi";
2344
+
2345
+ export const strapiIntegration = strapi({
2346
+ apiUrl: process.env.STRAPI_API_URL,
2347
+ token: process.env.STRAPI_API_TOKEN,
2348
+ mediaUrl: process.env.STRAPI_MEDIA_URL,
2349
+ webhook: {
2350
+ secret: process.env.STRAPI_WEBHOOK_SECRET,
2351
+ onChange(payload) {
2352
+ console.log("[strapi]", payload.event, payload.model);
2353
+ return undefined;
2354
+ },
2355
+ },
2356
+ log(event) {
2357
+ console.log("[strapi]", event.phase, event.route?.path || "none");
2358
+ },
2359
+ });
2297
2360
  `
2298
2361
  }
2299
2362
  ];
@@ -2634,6 +2697,7 @@ const FARM_TELEMETRY_TEMPLATES = [
2634
2697
  "polar",
2635
2698
  "resend",
2636
2699
  "sanity",
2700
+ "strapi",
2637
2701
  "stripe",
2638
2702
  "supabase",
2639
2703
  "unkey",