@farm.js/cli 0.1.0-beta.4 → 0.1.0-beta.40
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 +12 -0
- package/bin/farm.js +181 -9
- 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-Bz7WjUfh.js} +149 -169
- package/dist/add-integration-Bz7WjUfh.js.map +1 -0
- package/dist/add-integration.js +1 -1
- package/dist/add-integration.mjs +1 -1
- package/dist/build.js +5 -3
- package/dist/build.js.map +1 -1
- package/dist/build.mjs +5 -3
- package/dist/build.mjs.map +1 -1
- package/dist/index.js +992 -113
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +972 -114
- package/dist/index.mjs.map +1 -1
- package/dist/rolldown-runtime-VH7oDXx4.js +28 -0
- package/dist/telemetry.js +347 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/telemetry.mjs +337 -0
- package/dist/telemetry.mjs.map +1 -0
- package/package.json +3 -2
- package/dist/add-integration-CdVfiPjG.mjs.map +0 -1
- package/dist/add-integration-Xc0p-k-m.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,4 +8,16 @@ Farm.js is currently in beta.
|
|
|
8
8
|
npm install @farm.js/cli@beta
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Upgrade every published `@farm.js/*` dependency in an app to one release channel:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
farm upgrade --latest
|
|
15
|
+
farm upgrade --beta
|
|
16
|
+
farm upgrade --latest --dry-run
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`--latest` selects the newest stable release. `--beta` selects the newest beta release. The CLI
|
|
20
|
+
detects npm, pnpm, Yarn, or Bun from the project and leaves `workspace:`, `file:`, and other local
|
|
21
|
+
package references unchanged.
|
|
22
|
+
|
|
11
23
|
See the [Farm.js repository](https://github.com/farming-labs/farm.js) for documentation, examples, and support.
|
package/bin/farm.js
CHANGED
|
@@ -16,20 +16,63 @@ const { program } = require("commander");
|
|
|
16
16
|
const { version } = require("../package.json");
|
|
17
17
|
|
|
18
18
|
const banner = `
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
░██████████ ░███ ░█████████ ░███ ░███ ░█████ ░██████
|
|
20
|
+
░██ ░██░██ ░██ ░██ ░████ ░████ ░██ ░██ ░██
|
|
21
|
+
░██ ░██ ░██ ░██ ░██ ░██░██ ░██░██ ░██ ░██
|
|
22
|
+
░█████████ ░█████████ ░█████████ ░██ ░████ ░██ ░██ ░████████
|
|
23
|
+
░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██
|
|
24
|
+
░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██
|
|
25
|
+
░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██ ░██████ ░██████
|
|
24
26
|
`;
|
|
25
27
|
|
|
26
|
-
program
|
|
28
|
+
program
|
|
29
|
+
.name("farm")
|
|
30
|
+
.description("Farm.js CLI - A framework for product-integrated apps")
|
|
31
|
+
.version(version);
|
|
27
32
|
program.addHelpText("beforeAll", `${banner}\n`);
|
|
28
33
|
|
|
29
34
|
function collectOption(value, previous) {
|
|
30
35
|
return [...(previous || []), value];
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
function telemetryCommandPath(command) {
|
|
39
|
+
const segments = [];
|
|
40
|
+
let current = command;
|
|
41
|
+
while (current && current !== program) {
|
|
42
|
+
segments.unshift(current.name());
|
|
43
|
+
current = current.parent;
|
|
44
|
+
}
|
|
45
|
+
return segments.join(":");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function telemetryDeployTarget(commandPath, options) {
|
|
49
|
+
if (commandPath !== "deploy") return undefined;
|
|
50
|
+
if (options.vercel) return "vercel";
|
|
51
|
+
if (options.cloudflare) return "cloudflare";
|
|
52
|
+
if (options.netlify) return "netlify";
|
|
53
|
+
if (options.custom) return "custom";
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
program.hook("preAction", async (_command, actionCommand) => {
|
|
58
|
+
const commandPath = telemetryCommandPath(actionCommand);
|
|
59
|
+
if (commandPath.startsWith("telemetry")) return;
|
|
60
|
+
const {
|
|
61
|
+
resolveFarmTelemetryCommand,
|
|
62
|
+
showFarmTelemetryNotice,
|
|
63
|
+
trackFarmCommand,
|
|
64
|
+
} = require("../dist/telemetry.js");
|
|
65
|
+
await showFarmTelemetryNotice();
|
|
66
|
+
const command = resolveFarmTelemetryCommand(commandPath);
|
|
67
|
+
if (!command) return;
|
|
68
|
+
const options = actionCommand.opts();
|
|
69
|
+
await trackFarmCommand({
|
|
70
|
+
command,
|
|
71
|
+
packageVersion: version,
|
|
72
|
+
deployTarget: telemetryDeployTarget(commandPath, options),
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
33
76
|
program
|
|
34
77
|
.command("dev")
|
|
35
78
|
.description("Start development server")
|
|
@@ -80,6 +123,59 @@ program
|
|
|
80
123
|
}
|
|
81
124
|
});
|
|
82
125
|
|
|
126
|
+
const authCommand = program.command("auth").description("Manage Farm-native authentication");
|
|
127
|
+
|
|
128
|
+
authCommand
|
|
129
|
+
.command("migrate")
|
|
130
|
+
.description("Create or update the Farm Auth database schema")
|
|
131
|
+
.option("-r, --root <root>", "Root directory", process.cwd())
|
|
132
|
+
.option("-c, --config <config>", "Path to farm config file")
|
|
133
|
+
.action(async (options) => {
|
|
134
|
+
try {
|
|
135
|
+
const { migrateFarmAuth } = require("../dist/index.js");
|
|
136
|
+
await migrateFarmAuth({
|
|
137
|
+
root: options.root,
|
|
138
|
+
configPath: options.config,
|
|
139
|
+
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error("Failed to migrate Farm Auth:", error);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
program
|
|
147
|
+
.command("upgrade")
|
|
148
|
+
.description("Upgrade installed Farm.js packages to a stable or beta release")
|
|
149
|
+
.option("-r, --root <root>", "Project root", process.cwd())
|
|
150
|
+
.option("--latest", "Upgrade to the latest stable release")
|
|
151
|
+
.option("--beta", "Upgrade to the latest beta release")
|
|
152
|
+
.option("--dry-run", "Print the package-manager commands without installing")
|
|
153
|
+
.action(async (options) => {
|
|
154
|
+
try {
|
|
155
|
+
if (options.latest === options.beta) {
|
|
156
|
+
throw new Error("Choose exactly one release channel: --latest (stable) or --beta.");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const { formatFarmUpgradePlan, upgradeFarm } = require("../dist/index.js");
|
|
160
|
+
const result = await upgradeFarm({
|
|
161
|
+
root: options.root,
|
|
162
|
+
channel: options.beta ? "beta" : "latest",
|
|
163
|
+
dryRun: options.dryRun,
|
|
164
|
+
});
|
|
165
|
+
console.log(formatFarmUpgradePlan(result.plan));
|
|
166
|
+
console.log(
|
|
167
|
+
result.executed
|
|
168
|
+
? `Upgraded ${result.plan.packages.length} Farm package${
|
|
169
|
+
result.plan.packages.length === 1 ? "" : "s"
|
|
170
|
+
} to ${result.plan.channel}.`
|
|
171
|
+
: "Dry run only. No packages were changed.",
|
|
172
|
+
);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error("Failed to upgrade Farm packages:", error);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
83
179
|
program
|
|
84
180
|
.command("generate")
|
|
85
181
|
.description("Generate route/API types and integration schema artifacts")
|
|
@@ -91,6 +187,7 @@ program
|
|
|
91
187
|
)
|
|
92
188
|
.option("--dialect <dialect>", "SQL dialect for Drizzle generation (postgres, mysql, sqlite)")
|
|
93
189
|
.option("-o, --output <output>", "Custom output path")
|
|
190
|
+
.option("--check", "Fail when committed generated framework types are stale")
|
|
94
191
|
.action(async (options) => {
|
|
95
192
|
try {
|
|
96
193
|
const { generateFarmArtifacts } = require("../dist/index.js");
|
|
@@ -100,6 +197,7 @@ program
|
|
|
100
197
|
orm: options.orm,
|
|
101
198
|
dialect: options.dialect,
|
|
102
199
|
output: options.output,
|
|
200
|
+
check: options.check,
|
|
103
201
|
});
|
|
104
202
|
} catch (error) {
|
|
105
203
|
console.error("Failed to generate Farm artifacts:", error);
|
|
@@ -116,6 +214,7 @@ program
|
|
|
116
214
|
.option("--host <host>", "Host of a running local app")
|
|
117
215
|
.option("--url <url>", "Base URL of a running Farm app")
|
|
118
216
|
.option("--offline", "Inspect project files without probing a running app")
|
|
217
|
+
.option("--fix", "Apply safe additive corrections without overwriting application files")
|
|
119
218
|
.option("--timeout <ms>", "Live runtime probe timeout in milliseconds", "1200")
|
|
120
219
|
.option("--json", "Print machine-readable JSON")
|
|
121
220
|
.action(async (options) => {
|
|
@@ -132,6 +231,7 @@ program
|
|
|
132
231
|
host: options.host,
|
|
133
232
|
url: options.url,
|
|
134
233
|
offline: options.offline,
|
|
234
|
+
fix: options.fix,
|
|
135
235
|
timeoutMs,
|
|
136
236
|
});
|
|
137
237
|
console.log(options.json ? JSON.stringify(report, null, 2) : formatFarmDoctorReport(report));
|
|
@@ -142,6 +242,30 @@ program
|
|
|
142
242
|
}
|
|
143
243
|
});
|
|
144
244
|
|
|
245
|
+
program
|
|
246
|
+
.command("explain <path>")
|
|
247
|
+
.description("Explain how a URL maps to a Farm route and deployment runtime")
|
|
248
|
+
.option("-r, --root <root>", "Root directory", process.cwd())
|
|
249
|
+
.option("-c, --config <config>", "Path to farm config file")
|
|
250
|
+
.option("--json", "Print machine-readable JSON")
|
|
251
|
+
.action(async (pathname, options) => {
|
|
252
|
+
try {
|
|
253
|
+
const { explainFarmRoute, formatFarmRouteExplanation } = require("../dist/index.js");
|
|
254
|
+
const explanation = await explainFarmRoute(pathname, {
|
|
255
|
+
root: options.root,
|
|
256
|
+
configPath: options.config,
|
|
257
|
+
});
|
|
258
|
+
console.log(
|
|
259
|
+
options.json
|
|
260
|
+
? JSON.stringify(explanation, null, 2)
|
|
261
|
+
: formatFarmRouteExplanation(explanation),
|
|
262
|
+
);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error("Failed to explain Farm route:", error);
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
145
269
|
program
|
|
146
270
|
.command("preview")
|
|
147
271
|
.description("Create a public URL for a running local Farm app")
|
|
@@ -380,15 +504,63 @@ program
|
|
|
380
504
|
.option("--cloudflare", "Deploy to Cloudflare")
|
|
381
505
|
.option("--netlify", "Deploy to Netlify")
|
|
382
506
|
.option("--prod", "Deploy to production (Vercel: uses prebuilt output)")
|
|
507
|
+
.option("--plan", "Print the resolved deployment plan without building or deploying")
|
|
383
508
|
.option("--custom", "Use your own credentials (not Farm.js managed)")
|
|
384
509
|
.action(async (options) => {
|
|
385
510
|
try {
|
|
386
511
|
const { deployFarm } = require("../dist/index.js");
|
|
387
512
|
await deployFarm(options);
|
|
388
513
|
} catch (error) {
|
|
389
|
-
|
|
390
|
-
|
|
514
|
+
const code = error?.name === "FarmDeployError" ? ` [${error.code}]` : "";
|
|
515
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
516
|
+
console.error(`Failed to deploy${code}: ${message}`);
|
|
517
|
+
process.exitCode = 1;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
const telemetryCommand = program
|
|
522
|
+
.command("telemetry")
|
|
523
|
+
.description("Control anonymous Farm.js product telemetry");
|
|
524
|
+
|
|
525
|
+
telemetryCommand
|
|
526
|
+
.command("status")
|
|
527
|
+
.description("Show the current telemetry setting")
|
|
528
|
+
.action(async () => {
|
|
529
|
+
const { getFarmTelemetryStatus } = require("../dist/telemetry.js");
|
|
530
|
+
const status = await getFarmTelemetryStatus();
|
|
531
|
+
console.log(`Anonymous telemetry: ${status.enabled ? "enabled" : "disabled"}`);
|
|
532
|
+
console.log(`Active for this command: ${status.active ? "yes" : "no"}`);
|
|
533
|
+
console.log(`Setting source: ${status.source}`);
|
|
534
|
+
if (status.reason) console.log(`Reason: ${status.reason}`);
|
|
535
|
+
console.log(`Local anonymous ID: ${status.anonymousId ? "created" : "not created"}`);
|
|
536
|
+
console.log(`Configuration: ${status.configFile}`);
|
|
537
|
+
console.log("Privacy details: https://farmjs.dev/docs/telemetry");
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
telemetryCommand
|
|
541
|
+
.command("enable")
|
|
542
|
+
.description("Enable anonymous Farm.js product telemetry")
|
|
543
|
+
.action(async () => {
|
|
544
|
+
const { setFarmTelemetryEnabled } = require("../dist/telemetry.js");
|
|
545
|
+
const status = await setFarmTelemetryEnabled(true);
|
|
546
|
+
console.log("Anonymous Farm.js telemetry is enabled.");
|
|
547
|
+
if (!status.active && status.reason)
|
|
548
|
+
console.log(`It is inactive here because ${status.reason}.`);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
telemetryCommand
|
|
552
|
+
.command("disable")
|
|
553
|
+
.description("Opt out and delete the local anonymous installation ID")
|
|
554
|
+
.action(async () => {
|
|
555
|
+
const { setFarmTelemetryEnabled } = require("../dist/telemetry.js");
|
|
556
|
+
const status = await setFarmTelemetryEnabled(false);
|
|
557
|
+
console.log("Anonymous Farm.js telemetry is disabled and its local ID was deleted.");
|
|
558
|
+
if (status.enabled) {
|
|
559
|
+
console.log("An environment variable currently overrides the saved setting.");
|
|
391
560
|
}
|
|
392
561
|
});
|
|
393
562
|
|
|
394
|
-
program.
|
|
563
|
+
program.parseAsync().catch((error) => {
|
|
564
|
+
console.error("Farm CLI failed:", error);
|
|
565
|
+
process.exitCode = 1;
|
|
566
|
+
});
|