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

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/index.mjs CHANGED
@@ -10,6 +10,174 @@ import { randomUUID } from "node:crypto";
10
10
  import { request } from "node:http";
11
11
  import { request as request$1 } from "node:https";
12
12
  import os from "node:os";
13
+ function shadcnComponentTemplate(component) {
14
+ switch (component) {
15
+ case "badge": return `import * as React from "react";
16
+ import { cva, type VariantProps } from "class-variance-authority";
17
+ import { cn } from "@/lib/utils";
18
+
19
+ const badgeVariants = cva(
20
+ "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
21
+ {
22
+ variants: {
23
+ variant: {
24
+ default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
25
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
26
+ outline: "text-foreground",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ },
32
+ },
33
+ );
34
+
35
+ export interface BadgeProps
36
+ extends React.HTMLAttributes<HTMLDivElement>,
37
+ VariantProps<typeof badgeVariants> {}
38
+
39
+ export function Badge({ className, variant, ...props }: BadgeProps) {
40
+ return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
41
+ }
42
+
43
+ export { badgeVariants };
44
+ `;
45
+ case "button": return `import * as React from "react";
46
+ import { cva, type VariantProps } from "class-variance-authority";
47
+ import { cn } from "@/lib/utils";
48
+
49
+ const buttonVariants = cva(
50
+ "inline-flex h-9 items-center justify-center whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
51
+ {
52
+ variants: {
53
+ variant: {
54
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
55
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
56
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
57
+ ghost: "hover:bg-accent hover:text-accent-foreground",
58
+ },
59
+ size: {
60
+ default: "h-9 px-4 py-2",
61
+ sm: "h-8 rounded-md px-3 text-xs",
62
+ lg: "h-10 rounded-md px-8",
63
+ },
64
+ },
65
+ defaultVariants: {
66
+ variant: "default",
67
+ size: "default",
68
+ },
69
+ },
70
+ );
71
+
72
+ export interface ButtonProps
73
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
74
+ VariantProps<typeof buttonVariants> {}
75
+
76
+ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
77
+ ({ className, variant, size, ...props }, ref) => {
78
+ return (
79
+ <button
80
+ className={cn(buttonVariants({ variant, size, className }))}
81
+ ref={ref}
82
+ {...props}
83
+ />
84
+ );
85
+ },
86
+ );
87
+ Button.displayName = "Button";
88
+
89
+ export { buttonVariants };
90
+ `;
91
+ case "card": return `import * as React from "react";
92
+ import { cn } from "@/lib/utils";
93
+
94
+ export const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
95
+ ({ className, ...props }, ref) => (
96
+ <div
97
+ ref={ref}
98
+ className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
99
+ {...props}
100
+ />
101
+ ),
102
+ );
103
+ Card.displayName = "Card";
104
+
105
+ export const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
106
+ ({ className, ...props }, ref) => (
107
+ <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
108
+ ),
109
+ );
110
+ CardHeader.displayName = "CardHeader";
111
+
112
+ export const CardTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(
113
+ ({ className, ...props }, ref) => (
114
+ <h3 ref={ref} className={cn("text-2xl font-semibold leading-none tracking-normal", className)} {...props} />
115
+ ),
116
+ );
117
+ CardTitle.displayName = "CardTitle";
118
+
119
+ export const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
120
+ ({ className, ...props }, ref) => (
121
+ <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
122
+ ),
123
+ );
124
+ CardDescription.displayName = "CardDescription";
125
+
126
+ export const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
127
+ ({ className, ...props }, ref) => (
128
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
129
+ ),
130
+ );
131
+ CardContent.displayName = "CardContent";
132
+
133
+ export const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
134
+ ({ className, ...props }, ref) => (
135
+ <div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
136
+ ),
137
+ );
138
+ CardFooter.displayName = "CardFooter";
139
+ `;
140
+ case "input": return `import * as React from "react";
141
+ import { cn } from "@/lib/utils";
142
+
143
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
144
+
145
+ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
146
+ ({ className, type, ...props }, ref) => (
147
+ <input
148
+ type={type}
149
+ className={cn(
150
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
151
+ className,
152
+ )}
153
+ ref={ref}
154
+ {...props}
155
+ />
156
+ ),
157
+ );
158
+ Input.displayName = "Input";
159
+ `;
160
+ case "label": return `import * as React from "react";
161
+ import { cn } from "@/lib/utils";
162
+
163
+ export const Label = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(
164
+ ({ className, ...props }, ref) => (
165
+ <label
166
+ ref={ref}
167
+ className={cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", className)}
168
+ {...props}
169
+ />
170
+ ),
171
+ );
172
+ Label.displayName = "Label";
173
+ `;
174
+ }
175
+ }
176
+ //#endregion
177
+ //#region ../farm-cli/src/ui-registry.ts
178
+ /** Value written into a generated `components.json` as `registries.farm.url`. */
179
+ const UI_REGISTRY_URL_TEMPLATE = "https://farmjs.dev/r/{name}.json";
180
+ //#endregion
13
181
  //#region ../farm-cli/src/ui-feature-registry.ts
14
182
  async function installUIFeature(input) {
15
183
  const feature = input.definition.ui;
@@ -252,6 +420,16 @@ function unkeyApiKeysUIFeature() {
252
420
  ]
253
421
  };
254
422
  }
423
+ function sanityContentUIFeature() {
424
+ return {
425
+ name: "sanity-content",
426
+ description: "Sanity content list UI",
427
+ components: ["badge", "card"],
428
+ needsApiClient: false,
429
+ notes: ["Open \"/integrations/sanity\" to check the Sanity connection."],
430
+ files: () => [componentFile("sanity-content-console.tsx", sanityContentTemplate()), integrationPageFile("sanity", "SanityContentConsole")]
431
+ };
432
+ }
255
433
  function billingUIFeature(input) {
256
434
  return {
257
435
  name: `${input.provider}-billing`,
@@ -554,7 +732,7 @@ function createComponentsJson() {
554
732
  lib: "@/lib",
555
733
  hooks: "@/hooks"
556
734
  },
557
- registries: { farm: { url: "https://farmjs.dev/r/{name}.json" } }
735
+ registries: { farm: { url: UI_REGISTRY_URL_TEMPLATE } }
558
736
  };
559
737
  }
560
738
  function mergeComponentsJson(current, defaults) {
@@ -597,169 +775,6 @@ import type { AppIntegrations } from "./integrations";
597
775
  export const { api, apiClient } = createIntegrations<AppIntegrations>();
598
776
  `;
599
777
  }
600
- function shadcnComponentTemplate(component) {
601
- switch (component) {
602
- case "badge": return `import * as React from "react";
603
- import { cva, type VariantProps } from "class-variance-authority";
604
- import { cn } from "@/lib/utils";
605
-
606
- const badgeVariants = cva(
607
- "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
608
- {
609
- variants: {
610
- variant: {
611
- default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
612
- secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
613
- outline: "text-foreground",
614
- },
615
- },
616
- defaultVariants: {
617
- variant: "default",
618
- },
619
- },
620
- );
621
-
622
- export interface BadgeProps
623
- extends React.HTMLAttributes<HTMLDivElement>,
624
- VariantProps<typeof badgeVariants> {}
625
-
626
- export function Badge({ className, variant, ...props }: BadgeProps) {
627
- return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
628
- }
629
-
630
- export { badgeVariants };
631
- `;
632
- case "button": return `import * as React from "react";
633
- import { cva, type VariantProps } from "class-variance-authority";
634
- import { cn } from "@/lib/utils";
635
-
636
- const buttonVariants = cva(
637
- "inline-flex h-9 items-center justify-center whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
638
- {
639
- variants: {
640
- variant: {
641
- default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
642
- secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
643
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
644
- ghost: "hover:bg-accent hover:text-accent-foreground",
645
- },
646
- size: {
647
- default: "h-9 px-4 py-2",
648
- sm: "h-8 rounded-md px-3 text-xs",
649
- lg: "h-10 rounded-md px-8",
650
- },
651
- },
652
- defaultVariants: {
653
- variant: "default",
654
- size: "default",
655
- },
656
- },
657
- );
658
-
659
- export interface ButtonProps
660
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
661
- VariantProps<typeof buttonVariants> {}
662
-
663
- export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
664
- ({ className, variant, size, ...props }, ref) => {
665
- return (
666
- <button
667
- className={cn(buttonVariants({ variant, size, className }))}
668
- ref={ref}
669
- {...props}
670
- />
671
- );
672
- },
673
- );
674
- Button.displayName = "Button";
675
-
676
- export { buttonVariants };
677
- `;
678
- case "card": return `import * as React from "react";
679
- import { cn } from "@/lib/utils";
680
-
681
- export const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
682
- ({ className, ...props }, ref) => (
683
- <div
684
- ref={ref}
685
- className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
686
- {...props}
687
- />
688
- ),
689
- );
690
- Card.displayName = "Card";
691
-
692
- export const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
693
- ({ className, ...props }, ref) => (
694
- <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
695
- ),
696
- );
697
- CardHeader.displayName = "CardHeader";
698
-
699
- export const CardTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(
700
- ({ className, ...props }, ref) => (
701
- <h3 ref={ref} className={cn("text-2xl font-semibold leading-none tracking-normal", className)} {...props} />
702
- ),
703
- );
704
- CardTitle.displayName = "CardTitle";
705
-
706
- export const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
707
- ({ className, ...props }, ref) => (
708
- <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
709
- ),
710
- );
711
- CardDescription.displayName = "CardDescription";
712
-
713
- export const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
714
- ({ className, ...props }, ref) => (
715
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
716
- ),
717
- );
718
- CardContent.displayName = "CardContent";
719
-
720
- export const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
721
- ({ className, ...props }, ref) => (
722
- <div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
723
- ),
724
- );
725
- CardFooter.displayName = "CardFooter";
726
- `;
727
- case "input": return `import * as React from "react";
728
- import { cn } from "@/lib/utils";
729
-
730
- export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
731
-
732
- export const Input = React.forwardRef<HTMLInputElement, InputProps>(
733
- ({ className, type, ...props }, ref) => (
734
- <input
735
- type={type}
736
- className={cn(
737
- "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
738
- className,
739
- )}
740
- ref={ref}
741
- {...props}
742
- />
743
- ),
744
- );
745
- Input.displayName = "Input";
746
- `;
747
- case "label": return `import * as React from "react";
748
- import { cn } from "@/lib/utils";
749
-
750
- export const Label = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(
751
- ({ className, ...props }, ref) => (
752
- <label
753
- ref={ref}
754
- className={cn("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", className)}
755
- {...props}
756
- />
757
- ),
758
- );
759
- Label.displayName = "Label";
760
- `;
761
- }
762
- }
763
778
  function billingPricingTemplate(input) {
764
779
  return `"use client";
765
780
 
@@ -1659,6 +1674,40 @@ export function UnkeyApiKeysConsole() {
1659
1674
  }
1660
1675
  `;
1661
1676
  }
1677
+ function sanityContentTemplate() {
1678
+ return `import { Badge } from "@/components/ui/badge";
1679
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
1680
+
1681
+ export function SanityContentConsole() {
1682
+ return (
1683
+ <main className="min-h-screen bg-background px-6 py-12 text-foreground">
1684
+ <section className="mx-auto flex w-full max-w-3xl flex-col gap-6">
1685
+ <div className="space-y-3">
1686
+ <Badge variant="secondary">Sanity</Badge>
1687
+ <h1 className="text-3xl font-semibold tracking-normal">Content</h1>
1688
+ </div>
1689
+ <Card>
1690
+ <CardHeader>
1691
+ <CardTitle className="text-xl">Connected to Sanity</CardTitle>
1692
+ <CardDescription>
1693
+ Query documents with createServerQuery and invalidate them from the Sanity webhook.
1694
+ </CardDescription>
1695
+ </CardHeader>
1696
+ <CardContent className="space-y-3">
1697
+ <code className="block overflow-x-auto rounded-md border bg-muted/30 p-3 text-xs">
1698
+ cms.fetch(&apos;*[_type == &quot;post&quot;]{"{"} title {"}"}&apos;)
1699
+ </code>
1700
+ <p className="text-sm text-muted-foreground">
1701
+ Point a Sanity webhook at /api/sanity/webhook to keep cached pages fresh.
1702
+ </p>
1703
+ </CardContent>
1704
+ </Card>
1705
+ </section>
1706
+ </main>
1707
+ );
1708
+ }
1709
+ `;
1710
+ }
1662
1711
  function unkeyProtectedRouteTemplate() {
1663
1712
  return `export function GET() {
1664
1713
  return Response.json({
@@ -1829,7 +1878,7 @@ export const auth0Integration = auth0({
1829
1878
  exportName: "clerkIntegration",
1830
1879
  description: "Clerk auth provider and protected route middleware",
1831
1880
  env: ["NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY", "CLERK_SECRET_KEY"],
1832
- dependencies: { "@clerk/react": "^6.1.0" },
1881
+ dependencies: { "@clerk/react": "^6.4.3" },
1833
1882
  ui: clerkAuthUIFeature(),
1834
1883
  template: () => `import { clerk } from "@farm.js/clerk";
1835
1884
 
@@ -2201,6 +2250,43 @@ export const unkeyIntegration = unkey({
2201
2250
  console.log("[unkey]", event.phase, event.route?.path || "none");
2202
2251
  },
2203
2252
  });
2253
+ `
2254
+ },
2255
+ {
2256
+ provider: "sanity",
2257
+ aliases: ["cms", "sanity-cms"],
2258
+ defaultKey: "cms",
2259
+ packageName: "@farm.js/sanity",
2260
+ fileName: "sanity",
2261
+ exportName: "sanityIntegration",
2262
+ description: "Sanity content with server queries, CDN images, and webhook cache invalidation",
2263
+ env: [
2264
+ "SANITY_PROJECT_ID",
2265
+ "SANITY_DATASET",
2266
+ "SANITY_API_READ_TOKEN",
2267
+ "SANITY_WEBHOOK_SECRET"
2268
+ ],
2269
+ dependencies: { "@sanity/client": "^8.4.0" },
2270
+ ui: sanityContentUIFeature(),
2271
+ template: () => `import { sanity } from "@farm.js/sanity";
2272
+
2273
+ export const sanityIntegration = sanity({
2274
+ projectId: process.env.SANITY_PROJECT_ID,
2275
+ dataset: process.env.SANITY_DATASET,
2276
+ token: process.env.SANITY_API_READ_TOKEN,
2277
+ // The webhook fires before Sanity's CDN updates, so reads go through the API.
2278
+ useCdn: false,
2279
+ webhook: {
2280
+ secret: process.env.SANITY_WEBHOOK_SECRET,
2281
+ onChange(payload) {
2282
+ console.log("[sanity]", payload._type, payload._id);
2283
+ return undefined;
2284
+ },
2285
+ },
2286
+ log(event) {
2287
+ console.log("[sanity]", event.phase, event.route?.path || "none");
2288
+ },
2289
+ });
2204
2290
  `
2205
2291
  }
2206
2292
  ];
@@ -2540,6 +2626,7 @@ const FARM_TELEMETRY_TEMPLATES = [
2540
2626
  "jobs-trigger",
2541
2627
  "polar",
2542
2628
  "resend",
2629
+ "sanity",
2543
2630
  "stripe",
2544
2631
  "supabase",
2545
2632
  "unkey",
@@ -3157,6 +3244,7 @@ async function createApp(projectName, options = {}) {
3157
3244
  await fs.mkdir(projectPath, { recursive: true });
3158
3245
  const integrationResult = await copyTemplate(template, projectPath, renderer);
3159
3246
  await updatePackageJson(projectPath, projectName, packageManager);
3247
+ await updatePackageManagerInstructions(projectPath, packageManager.name);
3160
3248
  logger.success(`🚜 Created ${projectName}`);
3161
3249
  if (!options.skipInstall) {
3162
3250
  logger.info(`Installing dependencies with ${packageManager.name}...`);
@@ -3169,7 +3257,7 @@ async function createApp(projectName, options = {}) {
3169
3257
  if (options.skipInstall) logger.info(` ${packageManager.name} install`);
3170
3258
  logger.info(` ${getDevCommand(packageManager.name)}`);
3171
3259
  logger.info("");
3172
- for (const instruction of templateDetails[template]?.instructions ?? []) logger.info(instruction);
3260
+ for (const instruction of templateDetails[template]?.instructions ?? []) logger.info(rewritePackageManagerCommands(instruction, packageManager.name));
3173
3261
  if (integrationResult) {
3174
3262
  const details = templateDetails[template].integration;
3175
3263
  logger.info(`Open ${details.route} for the ${details.label} starter.`);
@@ -3210,6 +3298,14 @@ async function copyTemplate(template, projectPath, renderer) {
3210
3298
  }
3211
3299
  async function applyRendererTemplate(projectPath, renderer, basePackageJson) {
3212
3300
  const rendererTemplatePath = path.join(__dirname, "..", "templates", "_renderers", renderer);
3301
+ await Promise.all([
3302
+ fs.rm(path.join(projectPath, "docs.config.ts"), { force: true }),
3303
+ fs.rm(path.join(projectPath, "docs.json"), { force: true }),
3304
+ fs.rm(path.join(projectPath, "src", "app", "docs"), {
3305
+ recursive: true,
3306
+ force: true
3307
+ })
3308
+ ]);
3213
3309
  if (renderer === "vue" || renderer === "svelte") await Promise.all([
3214
3310
  fs.rm(path.join(projectPath, "src", "app", "page.tsx"), { force: true }),
3215
3311
  fs.rm(path.join(projectPath, "src", "app", "layout.tsx"), { force: true }),
@@ -3227,7 +3323,13 @@ function mergeRendererPackageJson(base, renderer) {
3227
3323
  ...base.devDependencies,
3228
3324
  ...renderer.devDependencies
3229
3325
  };
3230
- for (const name of ["react", "react-dom"]) delete dependencies[name];
3326
+ for (const name of [
3327
+ "@farming-labs/docs",
3328
+ "@farming-labs/farmjs",
3329
+ "@farming-labs/theme",
3330
+ "react",
3331
+ "react-dom"
3332
+ ]) delete dependencies[name];
3231
3333
  for (const name of ["@types/react", "@types/react-dom"]) delete devDependencies[name];
3232
3334
  return {
3233
3335
  ...base,
@@ -3453,6 +3555,35 @@ function getDevCommand(packageManager) {
3453
3555
  if (packageManager === "npm" || packageManager === "bun") return `${packageManager} run dev`;
3454
3556
  return `${packageManager} dev`;
3455
3557
  }
3558
+ function getRunCommand(packageManager, script) {
3559
+ if (packageManager === "npm" || packageManager === "bun") return `${packageManager} run ${script}`;
3560
+ return `${packageManager} ${script}`;
3561
+ }
3562
+ function rewritePackageManagerCommands(content, packageManager) {
3563
+ let output = content.replace(/\bpnpm install\b/g, `${packageManager} install`);
3564
+ output = output.replace(/\bpnpm run (dev|auth:migrate|type-check|build|check|deploy|experiment)\b/g, (match, script) => packageManager === "pnpm" ? match : getRunCommand(packageManager, script));
3565
+ return output.replace(/\bpnpm (dev|auth:migrate|type-check|build|check|deploy|experiment)\b/g, (_match, script) => getRunCommand(packageManager, script));
3566
+ }
3567
+ async function updatePackageManagerInstructions(projectPath, packageManager) {
3568
+ await Promise.all([
3569
+ "package.json",
3570
+ "README.md",
3571
+ "farm.config.ts",
3572
+ "src/app/page.tsx",
3573
+ "src/app/page.jsx",
3574
+ "src/app/page.vue",
3575
+ "src/app/page.svelte"
3576
+ ].map(async (file) => {
3577
+ const entryPath = path.join(projectPath, file);
3578
+ try {
3579
+ const content = await fs.readFile(entryPath, "utf8");
3580
+ const nextContent = rewritePackageManagerCommands(content, packageManager);
3581
+ if (nextContent !== content) await fs.writeFile(entryPath, nextContent, "utf8");
3582
+ } catch (error) {
3583
+ if (error.code !== "ENOENT") throw error;
3584
+ }
3585
+ }));
3586
+ }
3456
3587
  //#endregion
3457
3588
  export { createApp, detectPackageManager, installDependencies };
3458
3589