@farm.js/cli 0.1.0-beta.16 → 0.1.0-beta.17
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/bin/farm.js +4 -2
- package/dist/index.js +111 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +113 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -5,10 +5,10 @@ import { createServer, startDevServer } from "@farm.js/core/server";
|
|
|
5
5
|
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { execFileSync
|
|
8
|
+
import { execFileSync } from "child_process";
|
|
9
9
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "fs";
|
|
10
10
|
import path$1 from "path";
|
|
11
|
-
import { farmRouteRuleMatches, generateFarmTypeArtifacts, getFarmDocsRouteTypeEntries, getFarmPresetRuntime, getFarmSourceRoots, getIntegrationSchemas, getPresetForDeployTarget,
|
|
11
|
+
import { farmRouteRuleMatches, generateFarmTypeArtifacts, getFarmDocsRouteTypeEntries, getFarmPresetRuntime, getFarmSourceRoots, getIntegrationSchemas, getPresetForDeployTarget, loadConfig, logger, mergeFarmRouteRuntimeConfigs, normalizeDeployTarget, resolveConfig, resolveDeployConfig, resolveDeployOutputPath, resolveFarmRouteRuleRuntimeConfig, resolveFarmRouteRuntimeConfig, resolveRouteRenderingConfig, scanProgrammaticPagePaths } from "@farm.js/core";
|
|
12
12
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
13
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
14
14
|
import pc from "picocolors";
|
|
@@ -18,6 +18,15 @@ import { pathToFileURL } from "node:url";
|
|
|
18
18
|
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/deploy.ts
|
|
21
|
+
var FarmDeployError = class extends Error {
|
|
22
|
+
constructor(code, platform, message, options) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "FarmDeployError";
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.platform = platform;
|
|
27
|
+
this.cause = options?.cause;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
21
30
|
/**
|
|
22
31
|
* Deploy Farm.js application
|
|
23
32
|
*/
|
|
@@ -32,7 +41,7 @@ async function deployFarm(options = {}) {
|
|
|
32
41
|
root: plan.root,
|
|
33
42
|
preset: plan.preset
|
|
34
43
|
});
|
|
35
|
-
if (!existsSync$1(plan.outputDir)) throw new
|
|
44
|
+
if (!existsSync$1(plan.outputDir)) throw new FarmDeployError("INVALID_BUILD_OUTPUT", plan.target, `Build output not found at ${plan.outputDir}. Please run 'farm build' first.`);
|
|
36
45
|
await deployPlatform(plan.target, plan.root, plan.outputDir, deployConfig, options.prod);
|
|
37
46
|
return plan;
|
|
38
47
|
}
|
|
@@ -94,26 +103,64 @@ async function resolveFarmDeployContext(options) {
|
|
|
94
103
|
};
|
|
95
104
|
}
|
|
96
105
|
function createDeployCommand(platform, root, outputDir, deployConfig, prod, cloudflareAgent) {
|
|
97
|
-
if (platform === "vercel")
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
if (platform === "vercel") {
|
|
107
|
+
const args = [
|
|
108
|
+
"deploy",
|
|
109
|
+
"--prebuilt",
|
|
110
|
+
"--yes",
|
|
111
|
+
...prod ? ["--prod"] : []
|
|
112
|
+
];
|
|
113
|
+
return {
|
|
114
|
+
command: formatCommand$1("vercel", args),
|
|
115
|
+
cwd: path$1.resolve(root),
|
|
116
|
+
executable: "vercel",
|
|
117
|
+
args
|
|
118
|
+
};
|
|
119
|
+
}
|
|
101
120
|
if (platform === "netlify") {
|
|
102
|
-
const
|
|
121
|
+
const args = createNetlifyDeployArgs(deployConfig.netlify?.site);
|
|
103
122
|
return {
|
|
104
|
-
command:
|
|
105
|
-
cwd: outputDir
|
|
123
|
+
command: formatCommand$1("netlify", args),
|
|
124
|
+
cwd: outputDir,
|
|
125
|
+
executable: "netlify",
|
|
126
|
+
args
|
|
106
127
|
};
|
|
107
128
|
}
|
|
108
|
-
if (cloudflareAgent)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
129
|
+
if (cloudflareAgent) {
|
|
130
|
+
const args = [
|
|
131
|
+
"deploy",
|
|
132
|
+
"--config",
|
|
133
|
+
cloudflareAgent.configPath,
|
|
134
|
+
...cloudflareAgent.environment ? ["--env", cloudflareAgent.environment] : []
|
|
135
|
+
];
|
|
136
|
+
return {
|
|
137
|
+
command: formatCommand$1("wrangler", args),
|
|
138
|
+
cwd: path$1.resolve(root),
|
|
139
|
+
executable: "wrangler",
|
|
140
|
+
args
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const args = [
|
|
144
|
+
"pages",
|
|
145
|
+
"deploy",
|
|
146
|
+
".",
|
|
147
|
+
`--project-name=${deployConfig.cloudflare?.projectName || deployConfig.projectName || "farm-app"}`
|
|
148
|
+
];
|
|
112
149
|
return {
|
|
113
|
-
command:
|
|
114
|
-
cwd: outputDir
|
|
150
|
+
command: formatCommand$1("wrangler", args),
|
|
151
|
+
cwd: outputDir,
|
|
152
|
+
executable: "wrangler",
|
|
153
|
+
args
|
|
115
154
|
};
|
|
116
155
|
}
|
|
156
|
+
function createNetlifyDeployArgs(site) {
|
|
157
|
+
return [
|
|
158
|
+
"deploy",
|
|
159
|
+
"--prod",
|
|
160
|
+
"--dir=.",
|
|
161
|
+
...site ? [`--site=${site}`] : []
|
|
162
|
+
];
|
|
163
|
+
}
|
|
117
164
|
/**
|
|
118
165
|
* Deploy using platform's native CLI (user credentials)
|
|
119
166
|
*/
|
|
@@ -134,19 +181,20 @@ async function deployPlatform(platform, root, outputDir, deployConfig, prod) {
|
|
|
134
181
|
async function deployVercel(root, outputDir, prod) {
|
|
135
182
|
logger.info("🚀 Deploying to Vercel...");
|
|
136
183
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
184
|
+
execFileSync("vercel", ["--version"], {
|
|
185
|
+
stdio: "ignore",
|
|
186
|
+
cwd: root
|
|
187
|
+
});
|
|
188
|
+
} catch (error) {
|
|
189
|
+
throw new FarmDeployError("CLI_NOT_INSTALLED", "vercel", "Vercel CLI is not installed. Install it with: npm i -g vercel", { cause: error });
|
|
142
190
|
}
|
|
143
191
|
try {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
192
|
+
execFileSync("vercel", ["whoami"], {
|
|
193
|
+
stdio: "ignore",
|
|
194
|
+
cwd: root
|
|
195
|
+
});
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new FarmDeployError("CLI_NOT_AUTHENTICATED", "vercel", "Vercel CLI is not authenticated. Run 'vercel login', then retry the deployment.", { cause: error });
|
|
150
198
|
}
|
|
151
199
|
try {
|
|
152
200
|
const { existsSync, statSync, readdirSync } = await import("fs");
|
|
@@ -155,14 +203,8 @@ async function deployVercel(root, outputDir, prod) {
|
|
|
155
203
|
const configFile = path$1.join(outputDir, "config.json");
|
|
156
204
|
const serverIndex = path$1.join(functionsDir, "index.mjs");
|
|
157
205
|
logger.info("🔍 Verifying deployment structure...");
|
|
158
|
-
if (!existsSync(functionsDir)) {
|
|
159
|
-
|
|
160
|
-
process.exit(1);
|
|
161
|
-
}
|
|
162
|
-
if (!existsSync(serverIndex)) {
|
|
163
|
-
logger.error(`❌ Server entry point not found at ${serverIndex}`);
|
|
164
|
-
process.exit(1);
|
|
165
|
-
}
|
|
206
|
+
if (!existsSync(functionsDir)) throw new FarmDeployError("INVALID_BUILD_OUTPUT", "vercel", `Functions directory not found at ${functionsDir}.`);
|
|
207
|
+
if (!existsSync(serverIndex)) throw new FarmDeployError("INVALID_BUILD_OUTPUT", "vercel", `Server entry point not found at ${serverIndex}.`);
|
|
166
208
|
logger.info(`✅ Functions directory: ${functionsDir}`);
|
|
167
209
|
if (!existsSync(staticDir)) logger.warn(`⚠️ Static directory not found at ${staticDir}`);
|
|
168
210
|
else {
|
|
@@ -243,14 +285,19 @@ async function deployVercel(root, outputDir, prod) {
|
|
|
243
285
|
logger.info(` Static: ${staticDir}`);
|
|
244
286
|
logger.info(` Config: ${configFile}`);
|
|
245
287
|
logger.info("📤 Uploading to Vercel...");
|
|
246
|
-
|
|
288
|
+
execFileSync("vercel", [
|
|
289
|
+
"deploy",
|
|
290
|
+
"--prebuilt",
|
|
291
|
+
"--yes",
|
|
292
|
+
...prod ? ["--prod"] : []
|
|
293
|
+
], {
|
|
247
294
|
stdio: "inherit",
|
|
248
295
|
cwd: root
|
|
249
296
|
});
|
|
250
297
|
logger.success("✅ Deployed to Vercel successfully!");
|
|
251
298
|
} catch (error) {
|
|
252
|
-
|
|
253
|
-
|
|
299
|
+
if (error instanceof FarmDeployError) throw error;
|
|
300
|
+
throw new FarmDeployError("DEPLOY_FAILED", "vercel", `Failed to deploy to Vercel: ${getErrorMessage(error)}`, { cause: error });
|
|
254
301
|
}
|
|
255
302
|
}
|
|
256
303
|
/** Deploy to a composed Worker or fall back to Cloudflare Pages. */
|
|
@@ -271,8 +318,7 @@ async function deployCloudflare(root, outputDir, projectName) {
|
|
|
271
318
|
});
|
|
272
319
|
logger.success("✅ Deployed Farm and Cloudflare Agents successfully!");
|
|
273
320
|
} catch (error) {
|
|
274
|
-
|
|
275
|
-
process.exit(1);
|
|
321
|
+
throw new FarmDeployError("DEPLOY_FAILED", "cloudflare", `Failed to deploy to Cloudflare: ${getErrorMessage(error)}`, { cause: error });
|
|
276
322
|
}
|
|
277
323
|
return;
|
|
278
324
|
}
|
|
@@ -290,8 +336,7 @@ async function deployCloudflare(root, outputDir, projectName) {
|
|
|
290
336
|
});
|
|
291
337
|
logger.success("✅ Deployed to Cloudflare Pages successfully!");
|
|
292
338
|
} catch (error) {
|
|
293
|
-
|
|
294
|
-
process.exit(1);
|
|
339
|
+
throw new FarmDeployError("DEPLOY_FAILED", "cloudflare", `Failed to deploy to Cloudflare: ${getErrorMessage(error)}`, { cause: error });
|
|
295
340
|
}
|
|
296
341
|
}
|
|
297
342
|
/** Read the trusted Workers deployment handoff emitted by @farm.js/cf-agent. */
|
|
@@ -343,10 +388,8 @@ function assertWranglerInstalled(root) {
|
|
|
343
388
|
stdio: "ignore",
|
|
344
389
|
cwd: root
|
|
345
390
|
});
|
|
346
|
-
} catch {
|
|
347
|
-
|
|
348
|
-
logger.info("💡 Install it in this project with: npm i -D wrangler");
|
|
349
|
-
process.exit(1);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
throw new FarmDeployError("CLI_NOT_INSTALLED", "cloudflare", "Wrangler CLI is not installed. Install it in this project with: npm i -D wrangler", { cause: error });
|
|
350
393
|
}
|
|
351
394
|
}
|
|
352
395
|
function isRecord(value) {
|
|
@@ -358,22 +401,33 @@ function isRecord(value) {
|
|
|
358
401
|
async function deployNetlify(root, outputDir, site) {
|
|
359
402
|
logger.info("🚀 Deploying to Netlify...");
|
|
360
403
|
try {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
404
|
+
execFileSync("netlify", ["--version"], {
|
|
405
|
+
stdio: "ignore",
|
|
406
|
+
cwd: root
|
|
407
|
+
});
|
|
408
|
+
} catch (error) {
|
|
409
|
+
throw new FarmDeployError("CLI_NOT_INSTALLED", "netlify", "Netlify CLI is not installed. Install it with: npm i -g netlify-cli", { cause: error });
|
|
366
410
|
}
|
|
367
411
|
try {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
412
|
+
execFileSync("netlify", createNetlifyDeployArgs(site), {
|
|
413
|
+
stdio: "inherit",
|
|
414
|
+
cwd: outputDir
|
|
415
|
+
});
|
|
371
416
|
logger.success("✅ Deployed to Netlify successfully!");
|
|
372
417
|
} catch (error) {
|
|
373
|
-
|
|
374
|
-
process.exit(1);
|
|
418
|
+
throw new FarmDeployError("DEPLOY_FAILED", "netlify", `Failed to deploy to Netlify: ${getErrorMessage(error)}`, { cause: error });
|
|
375
419
|
}
|
|
376
420
|
}
|
|
421
|
+
function formatCommand$1(executable, args) {
|
|
422
|
+
return [executable, ...args].map(formatCommandArgument).join(" ");
|
|
423
|
+
}
|
|
424
|
+
function formatCommandArgument(argument) {
|
|
425
|
+
if (/^[A-Za-z0-9_./:=@+-]+$/.test(argument)) return argument;
|
|
426
|
+
return `'${argument.replace(/'/g, `'"'"'`)}'`;
|
|
427
|
+
}
|
|
428
|
+
function getErrorMessage(error) {
|
|
429
|
+
return error instanceof Error ? error.message : String(error);
|
|
430
|
+
}
|
|
377
431
|
//#endregion
|
|
378
432
|
//#region src/preview-gateway.ts
|
|
379
433
|
const DEFAULT_GATEWAY_URL = "https://preview.farming-labs.dev";
|
|
@@ -2071,9 +2125,8 @@ function discoverMatchingPages(config, pathname) {
|
|
|
2071
2125
|
}
|
|
2072
2126
|
const sourceDirectory = path.join(source.root, source.srcDir);
|
|
2073
2127
|
if (!existsSync(sourceDirectory)) continue;
|
|
2074
|
-
for (const
|
|
2075
|
-
if (
|
|
2076
|
-
const filePath = path.join(sourceDirectory, entry.name);
|
|
2128
|
+
for (const filePath of walkFiles(sourceDirectory)) {
|
|
2129
|
+
if (!/\.(?:tsx?|jsx?)$/.test(filePath) || filePath.endsWith(".d.ts")) continue;
|
|
2077
2130
|
const moduleSource = readFileSync(filePath, "utf8");
|
|
2078
2131
|
for (const pattern of scanProgrammaticPagePaths(moduleSource)) {
|
|
2079
2132
|
const match = matchRoutePattern(pattern, pathname);
|
|
@@ -3152,6 +3205,6 @@ function formatError(error) {
|
|
|
3152
3205
|
return error instanceof Error ? error.message : String(error);
|
|
3153
3206
|
}
|
|
3154
3207
|
//#endregion
|
|
3155
|
-
export { FarmGeneratedArtifactsStaleError, addFarmIntegration, buildFarm, createFarmDeployPlan, createFarmUpgradePlan, createFrameworkMigrationPlan, createGatewaySession, createPreviewGatewayPlan, createPreviewTunnelPlan, createServer, deployFarm, detectFarmPackageManager, explainFarmRoute, formatFarmCronJobs, formatFarmDeployPlan, formatFarmDoctorReport, formatFarmRouteExplanation, formatFarmUpgradePlan, forwardGatewayRequest, generateFarmArtifacts, inspectFrameworkMigrations, listFarmCronJobs, listFarmIntegrationProviders, loadFarmCronConfig, migrateFarm, migrateFarmAuth, parsePreviewPublicUrl, previewFarm, resolveCloudflareAgentDeployPlan, resolvePreviewTarget, runFarmCronJob, runFarmDoctor, runPreviewGateway, startDevServer, startFarmCronScheduler, upgradeFarm };
|
|
3208
|
+
export { FarmDeployError, FarmGeneratedArtifactsStaleError, addFarmIntegration, buildFarm, createFarmDeployPlan, createFarmUpgradePlan, createFrameworkMigrationPlan, createGatewaySession, createPreviewGatewayPlan, createPreviewTunnelPlan, createServer, deployFarm, detectFarmPackageManager, explainFarmRoute, formatFarmCronJobs, formatFarmDeployPlan, formatFarmDoctorReport, formatFarmRouteExplanation, formatFarmUpgradePlan, forwardGatewayRequest, generateFarmArtifacts, inspectFrameworkMigrations, listFarmCronJobs, listFarmIntegrationProviders, loadFarmCronConfig, migrateFarm, migrateFarmAuth, parsePreviewPublicUrl, previewFarm, resolveCloudflareAgentDeployPlan, resolvePreviewTarget, runFarmCronJob, runFarmDoctor, runPreviewGateway, startDevServer, startFarmCronScheduler, upgradeFarm };
|
|
3156
3209
|
|
|
3157
3210
|
//# sourceMappingURL=index.mjs.map
|