@farm.js/core 0.1.0-beta.10 → 0.1.0-beta.13
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/{chunk-3QDB3IA6.mjs → chunk-3WIRO3N7.mjs} +2 -2
- package/dist/chunk-3WIRO3N7.mjs.map +1 -0
- package/dist/chunk-53MVSX3R.mjs +168 -0
- package/dist/chunk-53MVSX3R.mjs.map +1 -0
- package/dist/{chunk-AW6I64AP.mjs → chunk-6ZXIQSXE.mjs} +16 -1
- package/dist/chunk-6ZXIQSXE.mjs.map +1 -0
- package/dist/chunk-7ZVN3YZI.mjs +333 -0
- package/dist/chunk-7ZVN3YZI.mjs.map +1 -0
- package/dist/{chunk-7N62DNSO.mjs → chunk-H3TE3LOV.mjs} +2 -2
- package/dist/{chunk-QTZZ2ISQ.mjs → chunk-KLA67WKG.mjs} +1 -1
- package/dist/chunk-KLA67WKG.mjs.map +1 -0
- package/dist/{chunk-K5ZTUF22.mjs → chunk-L2PE36GQ.mjs} +7 -3
- package/dist/chunk-L2PE36GQ.mjs.map +1 -0
- package/dist/{chunk-4LND3PXF.mjs → chunk-OPHK6OJN.mjs} +513 -48
- package/dist/chunk-OPHK6OJN.mjs.map +1 -0
- package/dist/chunk-USLFXFFH.mjs +46 -0
- package/dist/chunk-USLFXFFH.mjs.map +1 -0
- package/dist/{chunk-DTOWEQRV.mjs → chunk-VSDZEB5M.mjs} +368 -103
- package/dist/chunk-VSDZEB5M.mjs.map +1 -0
- package/dist/{chunk-E2AI2CW7.mjs → chunk-Z3YG4OZT.mjs} +727 -148
- package/dist/chunk-Z3YG4OZT.mjs.map +1 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/{devtools-A22KUJZT.mjs → devtools-GAZ7F3KL.mjs} +4 -3
- package/dist/{devtools-A22KUJZT.mjs.map → devtools-GAZ7F3KL.mjs.map} +1 -1
- package/dist/docs.cjs +622 -124
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.mjs +5 -3
- package/dist/font.cjs +19 -2
- package/dist/font.cjs.map +1 -1
- package/dist/font.mjs +7 -3
- package/dist/index.cjs +2208 -681
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +27 -19
- package/dist/index.mjs.map +1 -1
- package/dist/internal/build-runtime.cjs +2035 -517
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.mjs +13 -10
- package/dist/internal/client-runtime.cjs +169 -2
- package/dist/internal/client-runtime.cjs.map +1 -1
- package/dist/internal/client-runtime.mjs +170 -2
- package/dist/internal/client-runtime.mjs.map +1 -1
- package/dist/internal/config-runtime.cjs +22 -0
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.mjs +3 -2
- package/dist/internal/metadata-image-runtime.cjs +199 -0
- package/dist/internal/metadata-image-runtime.cjs.map +1 -0
- package/dist/internal/metadata-image-runtime.mjs +8 -0
- package/dist/internal/metadata-image-runtime.mjs.map +1 -0
- package/dist/internal/production-runtime.cjs +310 -0
- package/dist/internal/production-runtime.cjs.map +1 -1
- package/dist/internal/production-runtime.mjs +10 -0
- package/dist/internal/production-runtime.mjs.map +1 -1
- package/dist/navigation.cjs.map +1 -1
- package/dist/navigation.mjs +2 -2
- package/dist/plugin.cjs +1523 -340
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +9 -5
- package/dist/server.cjs +1636 -411
- package/dist/server.cjs.map +1 -1
- package/dist/server.mjs +17 -19
- package/dist/server.mjs.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +1577 -350
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +9 -5
- package/package.json +10 -1
- package/dist/chunk-3QDB3IA6.mjs.map +0 -1
- package/dist/chunk-4LND3PXF.mjs.map +0 -1
- package/dist/chunk-AW6I64AP.mjs.map +0 -1
- package/dist/chunk-DTOWEQRV.mjs.map +0 -1
- package/dist/chunk-E2AI2CW7.mjs.map +0 -1
- package/dist/chunk-K5ZTUF22.mjs.map +0 -1
- package/dist/chunk-QM746KUO.mjs +0 -56
- package/dist/chunk-QM746KUO.mjs.map +0 -1
- package/dist/chunk-QTZZ2ISQ.mjs.map +0 -1
- /package/dist/{chunk-7N62DNSO.mjs.map → chunk-H3TE3LOV.mjs.map} +0 -0
|
@@ -784,9 +784,9 @@ function getFarmIntegrationPluginServerRuntime(plugin) {
|
|
|
784
784
|
const value = plugin[FARM_INTEGRATION_PLUGIN_SERVER_RUNTIME];
|
|
785
785
|
return typeof value === "boolean" ? value : void 0;
|
|
786
786
|
}
|
|
787
|
-
function defineTypedIntegrationRoute(method,
|
|
787
|
+
function defineTypedIntegrationRoute(method, path31, input) {
|
|
788
788
|
return {
|
|
789
|
-
path:
|
|
789
|
+
path: path31,
|
|
790
790
|
method,
|
|
791
791
|
middleware: input.middleware,
|
|
792
792
|
before: input.before,
|
|
@@ -796,7 +796,7 @@ function defineTypedIntegrationRoute(method, path29, input) {
|
|
|
796
796
|
input: normalizeIntegrationRouteInputSchemas(input),
|
|
797
797
|
handler: input.handler,
|
|
798
798
|
__operation: defineIntegrationAPIOperation({
|
|
799
|
-
path:
|
|
799
|
+
path: path31,
|
|
800
800
|
method,
|
|
801
801
|
bodyFormat: input.bodyFormat,
|
|
802
802
|
responseFormat: input.responseFormat,
|
|
@@ -808,52 +808,52 @@ function defineTypedIntegrationRoute(method, path29, input) {
|
|
|
808
808
|
}
|
|
809
809
|
function createIntegrationRouteFactory() {
|
|
810
810
|
return {
|
|
811
|
-
get(
|
|
811
|
+
get(path31, input) {
|
|
812
812
|
return defineTypedIntegrationRoute(
|
|
813
813
|
"GET",
|
|
814
|
-
|
|
814
|
+
path31,
|
|
815
815
|
input
|
|
816
816
|
);
|
|
817
817
|
},
|
|
818
|
-
post(
|
|
818
|
+
post(path31, input) {
|
|
819
819
|
return defineTypedIntegrationRoute(
|
|
820
820
|
"POST",
|
|
821
|
-
|
|
821
|
+
path31,
|
|
822
822
|
{
|
|
823
823
|
bodyFormat: "json",
|
|
824
824
|
...input
|
|
825
825
|
}
|
|
826
826
|
);
|
|
827
827
|
},
|
|
828
|
-
put(
|
|
828
|
+
put(path31, input) {
|
|
829
829
|
return defineTypedIntegrationRoute(
|
|
830
830
|
"PUT",
|
|
831
|
-
|
|
831
|
+
path31,
|
|
832
832
|
{
|
|
833
833
|
bodyFormat: "json",
|
|
834
834
|
...input
|
|
835
835
|
}
|
|
836
836
|
);
|
|
837
837
|
},
|
|
838
|
-
patch(
|
|
839
|
-
return defineTypedIntegrationRoute("PATCH",
|
|
838
|
+
patch(path31, input) {
|
|
839
|
+
return defineTypedIntegrationRoute("PATCH", path31, {
|
|
840
840
|
bodyFormat: "json",
|
|
841
841
|
...input
|
|
842
842
|
});
|
|
843
843
|
},
|
|
844
|
-
delete(
|
|
845
|
-
return defineTypedIntegrationRoute("DELETE",
|
|
844
|
+
delete(path31, input) {
|
|
845
|
+
return defineTypedIntegrationRoute("DELETE", path31, {
|
|
846
846
|
bodyFormat: "json",
|
|
847
847
|
...input
|
|
848
848
|
});
|
|
849
849
|
},
|
|
850
|
-
options(
|
|
851
|
-
return defineTypedIntegrationRoute("OPTIONS",
|
|
850
|
+
options(path31, input) {
|
|
851
|
+
return defineTypedIntegrationRoute("OPTIONS", path31, input);
|
|
852
852
|
},
|
|
853
|
-
head(
|
|
853
|
+
head(path31, input) {
|
|
854
854
|
return defineTypedIntegrationRoute(
|
|
855
855
|
"HEAD",
|
|
856
|
-
|
|
856
|
+
path31,
|
|
857
857
|
input
|
|
858
858
|
);
|
|
859
859
|
}
|
|
@@ -1070,8 +1070,8 @@ async function parseIntegrationConfigSchema(integration, schema, value) {
|
|
|
1070
1070
|
function createIntegrationConfigValidationError(integration, error) {
|
|
1071
1071
|
const issues = Array.isArray(error.issues) && error.issues.length > 0 ? error.issues.map((issue) => {
|
|
1072
1072
|
const normalizedPath = normalizeIntegrationValidationPath(issue.path);
|
|
1073
|
-
const
|
|
1074
|
-
return `${
|
|
1073
|
+
const path31 = normalizedPath.length ? `${normalizedPath.join(".")}: ` : "";
|
|
1074
|
+
return `${path31}${issue.message || "Invalid config"}`;
|
|
1075
1075
|
}).join("; ") : error.message || "Invalid config";
|
|
1076
1076
|
return new Error(`Integration "${integration.type}" config validation failed: ${issues}`);
|
|
1077
1077
|
}
|
|
@@ -1756,8 +1756,8 @@ function normalizeIntegrationValidationIssues(source, error) {
|
|
|
1756
1756
|
}
|
|
1757
1757
|
];
|
|
1758
1758
|
}
|
|
1759
|
-
function normalizeIntegrationValidationPath(
|
|
1760
|
-
return (
|
|
1759
|
+
function normalizeIntegrationValidationPath(path31) {
|
|
1760
|
+
return (path31 || []).map((segment) => {
|
|
1761
1761
|
const key = typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment;
|
|
1762
1762
|
return typeof key === "symbol" ? key.description || key.toString() : key;
|
|
1763
1763
|
});
|
|
@@ -2956,26 +2956,26 @@ async function prepareFarmWorkflowsForNitro(config) {
|
|
|
2956
2956
|
const root = config.root || process.cwd();
|
|
2957
2957
|
const distDir = config.distDir || ".farm";
|
|
2958
2958
|
const fs8 = await import("fs/promises");
|
|
2959
|
-
const
|
|
2960
|
-
const generatedDir =
|
|
2959
|
+
const path31 = await import("path");
|
|
2960
|
+
const generatedDir = path31.join(root, distDir, ".nitro", "farm-workflows");
|
|
2961
2961
|
await fs8.mkdir(generatedDir, { recursive: true });
|
|
2962
2962
|
const tasks = {};
|
|
2963
2963
|
const scheduledTasks = createScheduledTasks(workflows);
|
|
2964
2964
|
for (const workflow of workflows) {
|
|
2965
|
-
const wrapperPath =
|
|
2965
|
+
const wrapperPath = path31.join(generatedDir, `${safeFileName(workflow.id)}.mjs`);
|
|
2966
2966
|
await fs8.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
|
|
2967
2967
|
tasks[workflow.id] = {
|
|
2968
2968
|
handler: wrapperPath,
|
|
2969
2969
|
description: workflow.description || `Farm workflow ${workflow.id}`
|
|
2970
2970
|
};
|
|
2971
2971
|
}
|
|
2972
|
-
const handlerPath =
|
|
2972
|
+
const handlerPath = path31.join(generatedDir, "http-handler.mjs");
|
|
2973
2973
|
await fs8.writeFile(
|
|
2974
2974
|
handlerPath,
|
|
2975
2975
|
createNitroWorkflowHTTPHandler(workflowConfig, workflows),
|
|
2976
2976
|
"utf8"
|
|
2977
2977
|
);
|
|
2978
|
-
const manifestPath =
|
|
2978
|
+
const manifestPath = path31.join(generatedDir, "manifest.json");
|
|
2979
2979
|
await fs8.writeFile(
|
|
2980
2980
|
manifestPath,
|
|
2981
2981
|
JSON.stringify(
|
|
@@ -3058,10 +3058,10 @@ function resolveWorkflowDefinition(module2) {
|
|
|
3058
3058
|
}
|
|
3059
3059
|
async function findWorkflowFiles(root, dirs) {
|
|
3060
3060
|
const fs8 = await import("fs/promises");
|
|
3061
|
-
const
|
|
3061
|
+
const path31 = await import("path");
|
|
3062
3062
|
const files = [];
|
|
3063
3063
|
for (const dir of dirs) {
|
|
3064
|
-
const absoluteDir =
|
|
3064
|
+
const absoluteDir = path31.isAbsolute(dir) ? dir : path31.join(root, dir);
|
|
3065
3065
|
if (!await pathExists(absoluteDir)) continue;
|
|
3066
3066
|
await walkWorkflowDir(absoluteDir, files);
|
|
3067
3067
|
}
|
|
@@ -3069,10 +3069,10 @@ async function findWorkflowFiles(root, dirs) {
|
|
|
3069
3069
|
}
|
|
3070
3070
|
async function walkWorkflowDir(dir, files) {
|
|
3071
3071
|
const fs8 = await import("fs/promises");
|
|
3072
|
-
const
|
|
3072
|
+
const path31 = await import("path");
|
|
3073
3073
|
const entries = await fs8.readdir(dir, { withFileTypes: true });
|
|
3074
3074
|
for (const entry of entries) {
|
|
3075
|
-
const filePath =
|
|
3075
|
+
const filePath = path31.join(dir, entry.name);
|
|
3076
3076
|
if (entry.isDirectory()) {
|
|
3077
3077
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
3078
3078
|
await walkWorkflowDir(filePath, files);
|
|
@@ -3092,12 +3092,12 @@ function isWorkflowFile(fileName) {
|
|
|
3092
3092
|
}
|
|
3093
3093
|
async function loadWorkflowModule(filePath, root) {
|
|
3094
3094
|
const fs8 = await import("fs/promises");
|
|
3095
|
-
const
|
|
3095
|
+
const path31 = await import("path");
|
|
3096
3096
|
const { pathToFileURL: pathToFileURL5 } = await import("url");
|
|
3097
3097
|
const { build: build2 } = await import("esbuild");
|
|
3098
|
-
const outDir =
|
|
3098
|
+
const outDir = path31.join(root, ".farm", ".workflow-loader");
|
|
3099
3099
|
await fs8.mkdir(outDir, { recursive: true });
|
|
3100
|
-
const outfile =
|
|
3100
|
+
const outfile = path31.join(
|
|
3101
3101
|
outDir,
|
|
3102
3102
|
`workflow-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`
|
|
3103
3103
|
);
|
|
@@ -3376,9 +3376,9 @@ async function prepareFarmCronForNitro(config) {
|
|
|
3376
3376
|
const root = config.root || process.cwd();
|
|
3377
3377
|
const distDir = config.distDir || ".farm";
|
|
3378
3378
|
const fs8 = await import("fs/promises");
|
|
3379
|
-
const
|
|
3380
|
-
const manifestPath =
|
|
3381
|
-
const generatedDir =
|
|
3379
|
+
const path31 = await import("path");
|
|
3380
|
+
const manifestPath = path31.join(root, distDir, FARM_CRON_MANIFEST);
|
|
3381
|
+
const generatedDir = path31.join(root, distDir, ".nitro", "farm-cron");
|
|
3382
3382
|
if (!cron.enabled) {
|
|
3383
3383
|
await Promise.all([
|
|
3384
3384
|
fs8.rm(manifestPath, { force: true }),
|
|
@@ -3395,7 +3395,7 @@ async function prepareFarmCronForNitro(config) {
|
|
|
3395
3395
|
const tasks = {};
|
|
3396
3396
|
for (const job of cron.jobs) {
|
|
3397
3397
|
const taskName = getFarmCronTaskName(job.name);
|
|
3398
|
-
const wrapperPath =
|
|
3398
|
+
const wrapperPath = path31.join(generatedDir, `${safeFileName2(job.name)}.mjs`);
|
|
3399
3399
|
await fs8.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
|
|
3400
3400
|
tasks[taskName] = {
|
|
3401
3401
|
handler: wrapperPath,
|
|
@@ -3403,7 +3403,7 @@ async function prepareFarmCronForNitro(config) {
|
|
|
3403
3403
|
};
|
|
3404
3404
|
}
|
|
3405
3405
|
const manifest = createFarmCronManifest(cron);
|
|
3406
|
-
await fs8.mkdir(
|
|
3406
|
+
await fs8.mkdir(path31.dirname(manifestPath), { recursive: true });
|
|
3407
3407
|
await fs8.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
3408
3408
|
`, "utf8");
|
|
3409
3409
|
return {
|
|
@@ -3485,7 +3485,7 @@ function normalizeCronJob(name, job) {
|
|
|
3485
3485
|
if (!job || typeof job !== "object" || Array.isArray(job)) {
|
|
3486
3486
|
throw new TypeError(`Farm cron ${JSON.stringify(name)} must be a configuration object.`);
|
|
3487
3487
|
}
|
|
3488
|
-
const
|
|
3488
|
+
const path31 = normalizeCronPath(name, job.path);
|
|
3489
3489
|
const rawSchedule = Array.isArray(job.schedule) ? job.schedule : [job.schedule];
|
|
3490
3490
|
const schedule = [...new Set(rawSchedule.map((value) => normalizeCronExpression(name, value)))];
|
|
3491
3491
|
if (schedule.length === 0) {
|
|
@@ -3494,7 +3494,7 @@ function normalizeCronJob(name, job) {
|
|
|
3494
3494
|
return {
|
|
3495
3495
|
name,
|
|
3496
3496
|
schedule,
|
|
3497
|
-
path:
|
|
3497
|
+
path: path31,
|
|
3498
3498
|
description: job.description?.trim() || void 0
|
|
3499
3499
|
};
|
|
3500
3500
|
}
|
|
@@ -3502,13 +3502,13 @@ function normalizeCronPath(name, value) {
|
|
|
3502
3502
|
if (typeof value !== "string" || !value.trim().startsWith("/")) {
|
|
3503
3503
|
throw new TypeError(`Farm cron ${JSON.stringify(name)} path must start with "/".`);
|
|
3504
3504
|
}
|
|
3505
|
-
const
|
|
3506
|
-
if (
|
|
3505
|
+
const path31 = value.trim();
|
|
3506
|
+
if (path31.startsWith("//") || path31.includes("?") || path31.includes("#")) {
|
|
3507
3507
|
throw new TypeError(
|
|
3508
3508
|
`Farm cron ${JSON.stringify(name)} path must be an application pathname without a host, query, or hash.`
|
|
3509
3509
|
);
|
|
3510
3510
|
}
|
|
3511
|
-
return
|
|
3511
|
+
return path31.length > 1 ? path31.replace(/\/+$/, "") : path31;
|
|
3512
3512
|
}
|
|
3513
3513
|
function normalizeCronExpression(name, value) {
|
|
3514
3514
|
if (typeof value !== "string") {
|
|
@@ -4904,8 +4904,8 @@ function createFarmDeploymentMismatchResponse(mismatch) {
|
|
|
4904
4904
|
}
|
|
4905
4905
|
);
|
|
4906
4906
|
}
|
|
4907
|
-
function createFarmDeploymentCookie(deploymentId,
|
|
4908
|
-
const normalizedPath =
|
|
4907
|
+
function createFarmDeploymentCookie(deploymentId, path31 = "/", secure = false) {
|
|
4908
|
+
const normalizedPath = path31.startsWith("/") ? path31 : `/${path31}`;
|
|
4909
4909
|
return [
|
|
4910
4910
|
`${FARM_DEPLOYMENT_COOKIE}=${encodeURIComponent(deploymentId)}`,
|
|
4911
4911
|
`Path=${normalizedPath}`,
|
|
@@ -4976,7 +4976,7 @@ var init_devtools_config = __esm({
|
|
|
4976
4976
|
|
|
4977
4977
|
// src/image-config.ts
|
|
4978
4978
|
function resolveFarmImageConfig(config) {
|
|
4979
|
-
const
|
|
4979
|
+
const path31 = normalizeImagePath(config?.path ?? DEFAULT_FARM_IMAGE_PATH);
|
|
4980
4980
|
const deviceSizes = normalizeIntegerList(
|
|
4981
4981
|
config?.deviceSizes ?? DEFAULT_FARM_IMAGE_DEVICE_SIZES,
|
|
4982
4982
|
"images.deviceSizes"
|
|
@@ -5004,7 +5004,7 @@ function resolveFarmImageConfig(config) {
|
|
|
5004
5004
|
);
|
|
5005
5005
|
return Object.freeze({
|
|
5006
5006
|
provider: config?.provider ?? "auto",
|
|
5007
|
-
path:
|
|
5007
|
+
path: path31,
|
|
5008
5008
|
domains: Object.freeze([
|
|
5009
5009
|
...new Set(
|
|
5010
5010
|
(config?.domains ?? []).map((domain) => domain.trim().toLowerCase()).filter(Boolean)
|
|
@@ -5043,11 +5043,11 @@ function getPublicFarmImageConfig(config) {
|
|
|
5043
5043
|
};
|
|
5044
5044
|
}
|
|
5045
5045
|
function normalizeImagePath(value) {
|
|
5046
|
-
const
|
|
5047
|
-
if (!
|
|
5046
|
+
const path31 = value.trim().replace(/\/+$/, "") || "/";
|
|
5047
|
+
if (!path31.startsWith("/") || path31.includes("?") || path31.includes("#")) {
|
|
5048
5048
|
throw new TypeError("images.path must be an absolute pathname without a query or hash");
|
|
5049
5049
|
}
|
|
5050
|
-
return
|
|
5050
|
+
return path31;
|
|
5051
5051
|
}
|
|
5052
5052
|
function normalizeIntegerList(values, name, max) {
|
|
5053
5053
|
if (values.length === 0) {
|
|
@@ -5361,6 +5361,33 @@ var init_auth_config = __esm({
|
|
|
5361
5361
|
}
|
|
5362
5362
|
});
|
|
5363
5363
|
|
|
5364
|
+
// src/preload.ts
|
|
5365
|
+
function resolveFarmPerformanceConfig(config) {
|
|
5366
|
+
return {
|
|
5367
|
+
preload: {
|
|
5368
|
+
mode: config?.preload?.mode === "warn" ? "warn" : "enforce",
|
|
5369
|
+
maxImages: normalizeBudget(config?.preload?.maxImages, DEFAULT_PRELOAD_CONFIG.maxImages),
|
|
5370
|
+
maxFonts: normalizeBudget(config?.preload?.maxFonts, DEFAULT_PRELOAD_CONFIG.maxFonts)
|
|
5371
|
+
}
|
|
5372
|
+
};
|
|
5373
|
+
}
|
|
5374
|
+
function normalizeBudget(value, fallback) {
|
|
5375
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
|
|
5376
|
+
}
|
|
5377
|
+
var DEFAULT_PRELOAD_CONFIG;
|
|
5378
|
+
var init_preload = __esm({
|
|
5379
|
+
"src/preload.ts"() {
|
|
5380
|
+
"use strict";
|
|
5381
|
+
DEFAULT_PRELOAD_CONFIG = {
|
|
5382
|
+
mode: "enforce",
|
|
5383
|
+
maxImages: 1,
|
|
5384
|
+
maxFonts: 2
|
|
5385
|
+
};
|
|
5386
|
+
__name(resolveFarmPerformanceConfig, "resolveFarmPerformanceConfig");
|
|
5387
|
+
__name(normalizeBudget, "normalizeBudget");
|
|
5388
|
+
}
|
|
5389
|
+
});
|
|
5390
|
+
|
|
5364
5391
|
// src/config-entry.ts
|
|
5365
5392
|
var init_config_entry = __esm({
|
|
5366
5393
|
"src/config-entry.ts"() {
|
|
@@ -5481,18 +5508,18 @@ function sanitizeDocsConfig(config) {
|
|
|
5481
5508
|
return cloneSerializable(config) || {};
|
|
5482
5509
|
}
|
|
5483
5510
|
async function findDocsConfigPath(rootDir, configPath) {
|
|
5484
|
-
const { existsSync:
|
|
5511
|
+
const { existsSync: existsSync17 } = await import("fs");
|
|
5485
5512
|
const root = import_path2.default.resolve(rootDir || process.cwd());
|
|
5486
5513
|
if (configPath) {
|
|
5487
5514
|
const resolvedPath = import_path2.default.isAbsolute(configPath) ? configPath : import_path2.default.join(root, configPath);
|
|
5488
|
-
if (!
|
|
5515
|
+
if (!existsSync17(resolvedPath)) {
|
|
5489
5516
|
throw new Error(`Could not find docs config at ${configPath}.`);
|
|
5490
5517
|
}
|
|
5491
5518
|
return import_path2.default.resolve(resolvedPath);
|
|
5492
5519
|
}
|
|
5493
5520
|
for (const filename of DOCS_CONFIG_FILENAMES) {
|
|
5494
5521
|
const resolvedPath = import_path2.default.join(root, filename);
|
|
5495
|
-
if (
|
|
5522
|
+
if (existsSync17(resolvedPath)) {
|
|
5496
5523
|
return resolvedPath;
|
|
5497
5524
|
}
|
|
5498
5525
|
}
|
|
@@ -5680,6 +5707,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
5680
5707
|
headers: /* @__PURE__ */ __name(() => [...headers, ...routeRuleHeaders], "headers"),
|
|
5681
5708
|
routeRules,
|
|
5682
5709
|
images: resolveFarmImageConfig(userConfig.images),
|
|
5710
|
+
performance: resolveFarmPerformanceConfig(userConfig.performance),
|
|
5683
5711
|
publicDir: userConfig.publicDir || "public",
|
|
5684
5712
|
i18n: resolveFarmI18nConfig(userConfig.i18n, { root, mode }),
|
|
5685
5713
|
openapi: {
|
|
@@ -5718,7 +5746,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
5718
5746
|
return resolved;
|
|
5719
5747
|
}
|
|
5720
5748
|
async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "production" ? "production" : "development", loadEnvironment) {
|
|
5721
|
-
const { existsSync:
|
|
5749
|
+
const { existsSync: existsSync17 } = await import("fs");
|
|
5722
5750
|
const loadEnv = loadEnvironment || (await import("vite")).loadEnv;
|
|
5723
5751
|
const root = rootDir || process.cwd();
|
|
5724
5752
|
const loadedEnv = loadEnv(mode, root, "");
|
|
@@ -5742,7 +5770,7 @@ async function loadConfig(rootDir, configPath, mode = process.env.NODE_ENV === "
|
|
|
5742
5770
|
try {
|
|
5743
5771
|
const absolutePath = relativePath2.startsWith("/") ? relativePath2 : import_path2.default.join(root, relativePath2);
|
|
5744
5772
|
const normalizedPath = import_path2.default.resolve(absolutePath);
|
|
5745
|
-
if (!
|
|
5773
|
+
if (!existsSync17(normalizedPath)) {
|
|
5746
5774
|
continue;
|
|
5747
5775
|
}
|
|
5748
5776
|
const loadedConfig = await loadFarmConfigFile(normalizedPath, { root });
|
|
@@ -5773,6 +5801,7 @@ var init_config2 = __esm({
|
|
|
5773
5801
|
init_image_config();
|
|
5774
5802
|
init_config();
|
|
5775
5803
|
init_auth_config();
|
|
5804
|
+
init_preload();
|
|
5776
5805
|
init_config_entry();
|
|
5777
5806
|
FARM_RESOLVED_CUSTOM_CONTEXT = /* @__PURE__ */ Symbol.for("farm.resolvedCustomContext");
|
|
5778
5807
|
__name(hasCustomFarmRouteContext, "hasCustomFarmRouteContext");
|
|
@@ -6140,6 +6169,210 @@ async function resolveRouteRenderingConfigFromFile(mod, filePath) {
|
|
|
6140
6169
|
const source = await (0, import_promises3.readFile)(filePath, "utf8").catch(() => void 0);
|
|
6141
6170
|
return resolveRouteRenderingConfig(mod, source);
|
|
6142
6171
|
}
|
|
6172
|
+
function analyzeStaticRouteCandidate(mod, source, options = {}) {
|
|
6173
|
+
const blockers = [];
|
|
6174
|
+
if (!source) {
|
|
6175
|
+
blockers.push("route source is unavailable");
|
|
6176
|
+
}
|
|
6177
|
+
if (options.isDynamic) {
|
|
6178
|
+
blockers.push("the route has dynamic path segments");
|
|
6179
|
+
}
|
|
6180
|
+
if (hasExplicitRenderingConfig(mod, source)) {
|
|
6181
|
+
blockers.push("the route already has explicit rendering config");
|
|
6182
|
+
}
|
|
6183
|
+
if (source) {
|
|
6184
|
+
blockers.push(...findRequestBoundSourceBlockers(source));
|
|
6185
|
+
}
|
|
6186
|
+
return {
|
|
6187
|
+
candidate: blockers.length === 0,
|
|
6188
|
+
blockers
|
|
6189
|
+
};
|
|
6190
|
+
}
|
|
6191
|
+
function findRequestBoundSourceBlockers(source) {
|
|
6192
|
+
const blockers = /* @__PURE__ */ new Set();
|
|
6193
|
+
const code = stripCommentsAndLiteralContents(source);
|
|
6194
|
+
const sourceWithoutComments = stripComments(source);
|
|
6195
|
+
for (const binding of readRequestApiImportBindings(sourceWithoutComments)) {
|
|
6196
|
+
if (new RegExp(`\\b${escapeRegExp2(binding.local)}\\s*(?:\\?\\.\\s*)?\\(`).test(code)) {
|
|
6197
|
+
blockers.add(`the route reads ${binding.label}`);
|
|
6198
|
+
}
|
|
6199
|
+
}
|
|
6200
|
+
for (const namespace of readNamespaceImportBindings(sourceWithoutComments)) {
|
|
6201
|
+
for (const [name, label] of REQUEST_API_LABELS) {
|
|
6202
|
+
if (new RegExp(
|
|
6203
|
+
`\\b${escapeRegExp2(namespace)}\\s*(?:\\?\\.\\s*|\\.\\s*)${name}\\s*(?:\\?\\.\\s*)?\\(`
|
|
6204
|
+
).test(code)) {
|
|
6205
|
+
blockers.add(`the route reads ${label}`);
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
}
|
|
6209
|
+
const params = readDefaultRouteParameters(code);
|
|
6210
|
+
if (params) {
|
|
6211
|
+
for (const [name, label] of ROUTE_PROP_LABELS) {
|
|
6212
|
+
if (new RegExp(`\\b${name}\\b`).test(params)) {
|
|
6213
|
+
blockers.add(`the route reads ${label}`);
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
const propsName = params.match(/^\s*([A-Za-z_$][\w$]*)\s*(?::|,|$)/)?.[1];
|
|
6217
|
+
if (propsName) {
|
|
6218
|
+
for (const [name, label] of ROUTE_PROP_LABELS) {
|
|
6219
|
+
if (new RegExp(`\\b${escapeRegExp2(propsName)}\\s*\\.\\s*${name}\\b`).test(code)) {
|
|
6220
|
+
blockers.add(`the route reads ${label}`);
|
|
6221
|
+
}
|
|
6222
|
+
if (new RegExp(`\\{[^}]*\\b${name}\\b[^}]*\\}\\s*=\\s*${escapeRegExp2(propsName)}\\b`).test(
|
|
6223
|
+
code
|
|
6224
|
+
)) {
|
|
6225
|
+
blockers.add(`the route reads ${label}`);
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
}
|
|
6230
|
+
return [...blockers];
|
|
6231
|
+
}
|
|
6232
|
+
function readRequestApiImportBindings(source) {
|
|
6233
|
+
const bindings = [];
|
|
6234
|
+
for (const clause of readStaticImportClauses(source)) {
|
|
6235
|
+
const namedGroup = clause.match(/\{([\s\S]*?)\}/)?.[1];
|
|
6236
|
+
for (const rawSpecifier of (namedGroup ?? "").split(",")) {
|
|
6237
|
+
const specifier = rawSpecifier.trim().replace(/^type\s+/, "");
|
|
6238
|
+
const imported = specifier.match(/^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);
|
|
6239
|
+
if (!imported?.[1]) continue;
|
|
6240
|
+
const label = REQUEST_API_LABELS.get(imported[1]);
|
|
6241
|
+
if (label) bindings.push({ local: imported[2] ?? imported[1], label });
|
|
6242
|
+
}
|
|
6243
|
+
const local = clause.match(/^\s*([A-Za-z_$][\w$]*)\s*(?:,|$)/)?.[1];
|
|
6244
|
+
if (local) {
|
|
6245
|
+
const label = REQUEST_API_LABELS.get(local);
|
|
6246
|
+
if (label) bindings.push({ local, label });
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
return bindings;
|
|
6250
|
+
}
|
|
6251
|
+
function readNamespaceImportBindings(source) {
|
|
6252
|
+
return readStaticImportClauses(source).map((clause) => clause.match(/\*\s*as\s*([A-Za-z_$][\w$]*)/)?.[1]).filter((binding) => Boolean(binding));
|
|
6253
|
+
}
|
|
6254
|
+
function readStaticImportClauses(source) {
|
|
6255
|
+
return [...source.matchAll(/\bimport\s+(?!\()([\s\S]*?)\s+from\s*["'][^"']+["']/g)].map((match) => match[1]).filter((clause) => Boolean(clause));
|
|
6256
|
+
}
|
|
6257
|
+
function readDefaultRouteParameters(code) {
|
|
6258
|
+
const inlineParams = code.match(/\bexport\s+default\s+(?:async\s+)?function\b[^(]*\(([^)]*)\)/)?.[1] ?? code.match(/\bexport\s+default\s+(?:async\s+)?\(([^)]*)\)\s*=>/)?.[1];
|
|
6259
|
+
if (inlineParams !== void 0) return inlineParams;
|
|
6260
|
+
const binding = code.match(/\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*;?/)?.[1] ?? code.match(/\bexport\s*\{\s*([A-Za-z_$][\w$]*)\s+as\s+default\s*\}/)?.[1];
|
|
6261
|
+
if (!binding) return void 0;
|
|
6262
|
+
const escapedBinding = escapeRegExp2(binding);
|
|
6263
|
+
return code.match(new RegExp(`\\bfunction\\s+${escapedBinding}\\s*\\(([^)]*)\\)`))?.[1] ?? code.match(
|
|
6264
|
+
new RegExp(
|
|
6265
|
+
`\\b(?:const|let|var)\\s+${escapedBinding}\\s*=\\s*(?:async\\s+)?\\(([^)]*)\\)\\s*=>`
|
|
6266
|
+
)
|
|
6267
|
+
)?.[1] ?? code.match(
|
|
6268
|
+
new RegExp(`\\b(?:const|let|var)\\s+${escapedBinding}\\s*=\\s*function\\s*\\(([^)]*)\\)`)
|
|
6269
|
+
)?.[1];
|
|
6270
|
+
}
|
|
6271
|
+
function stripCommentsAndLiteralContents(source) {
|
|
6272
|
+
return sanitizeSource(source, true);
|
|
6273
|
+
}
|
|
6274
|
+
function stripComments(source) {
|
|
6275
|
+
return sanitizeSource(source, false);
|
|
6276
|
+
}
|
|
6277
|
+
function sanitizeSource(source, maskLiterals) {
|
|
6278
|
+
const output = [...source];
|
|
6279
|
+
const mask = /* @__PURE__ */ __name((index) => {
|
|
6280
|
+
if (output[index] !== "\n" && output[index] !== "\r") output[index] = " ";
|
|
6281
|
+
}, "mask");
|
|
6282
|
+
const scanQuoted = /* @__PURE__ */ __name((start, quote) => {
|
|
6283
|
+
let index = start;
|
|
6284
|
+
if (maskLiterals) mask(index);
|
|
6285
|
+
index += 1;
|
|
6286
|
+
while (index < source.length) {
|
|
6287
|
+
if (source[index] === "\\") {
|
|
6288
|
+
if (maskLiterals) mask(index);
|
|
6289
|
+
if (index + 1 < source.length && maskLiterals) mask(index + 1);
|
|
6290
|
+
index += 2;
|
|
6291
|
+
continue;
|
|
6292
|
+
}
|
|
6293
|
+
const character = source[index];
|
|
6294
|
+
if (maskLiterals) mask(index);
|
|
6295
|
+
index += 1;
|
|
6296
|
+
if (character === quote) break;
|
|
6297
|
+
}
|
|
6298
|
+
return index;
|
|
6299
|
+
}, "scanQuoted");
|
|
6300
|
+
const scanCode = /* @__PURE__ */ __name((start, stopAtTemplateBrace) => {
|
|
6301
|
+
let index = start;
|
|
6302
|
+
let braceDepth = 0;
|
|
6303
|
+
while (index < source.length) {
|
|
6304
|
+
const character = source[index];
|
|
6305
|
+
const next = source[index + 1];
|
|
6306
|
+
if (character === "/" && next === "/") {
|
|
6307
|
+
while (index < source.length && source[index] !== "\n" && source[index] !== "\r") {
|
|
6308
|
+
mask(index++);
|
|
6309
|
+
}
|
|
6310
|
+
continue;
|
|
6311
|
+
}
|
|
6312
|
+
if (character === "/" && next === "*") {
|
|
6313
|
+
mask(index++);
|
|
6314
|
+
mask(index++);
|
|
6315
|
+
while (index < source.length) {
|
|
6316
|
+
const closesComment = source[index] === "*" && source[index + 1] === "/";
|
|
6317
|
+
mask(index++);
|
|
6318
|
+
if (closesComment) {
|
|
6319
|
+
mask(index++);
|
|
6320
|
+
break;
|
|
6321
|
+
}
|
|
6322
|
+
}
|
|
6323
|
+
continue;
|
|
6324
|
+
}
|
|
6325
|
+
if (character === "'" || character === '"') {
|
|
6326
|
+
index = scanQuoted(index, character);
|
|
6327
|
+
continue;
|
|
6328
|
+
}
|
|
6329
|
+
if (character === "`") {
|
|
6330
|
+
if (maskLiterals) mask(index);
|
|
6331
|
+
index += 1;
|
|
6332
|
+
while (index < source.length) {
|
|
6333
|
+
if (source[index] === "\\") {
|
|
6334
|
+
if (maskLiterals) mask(index);
|
|
6335
|
+
if (index + 1 < source.length && maskLiterals) mask(index + 1);
|
|
6336
|
+
index += 2;
|
|
6337
|
+
} else if (source[index] === "`") {
|
|
6338
|
+
if (maskLiterals) mask(index);
|
|
6339
|
+
index += 1;
|
|
6340
|
+
break;
|
|
6341
|
+
} else if (source[index] === "$" && source[index + 1] === "{") {
|
|
6342
|
+
if (maskLiterals) {
|
|
6343
|
+
mask(index);
|
|
6344
|
+
mask(index + 1);
|
|
6345
|
+
}
|
|
6346
|
+
index = scanCode(index + 2, true);
|
|
6347
|
+
} else {
|
|
6348
|
+
if (maskLiterals) mask(index);
|
|
6349
|
+
index += 1;
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
continue;
|
|
6353
|
+
}
|
|
6354
|
+
if (character === "{") {
|
|
6355
|
+
braceDepth += 1;
|
|
6356
|
+
} else if (character === "}") {
|
|
6357
|
+
if (stopAtTemplateBrace && braceDepth === 0) {
|
|
6358
|
+
if (maskLiterals) mask(index);
|
|
6359
|
+
return index + 1;
|
|
6360
|
+
}
|
|
6361
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
6362
|
+
}
|
|
6363
|
+
index += 1;
|
|
6364
|
+
}
|
|
6365
|
+
return index;
|
|
6366
|
+
}, "scanCode");
|
|
6367
|
+
scanCode(0, false);
|
|
6368
|
+
return output.join("");
|
|
6369
|
+
}
|
|
6370
|
+
function escapeRegExp2(value) {
|
|
6371
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6372
|
+
}
|
|
6373
|
+
function hasExplicitRenderingConfig(mod, source) {
|
|
6374
|
+
return typeof mod?.ssg === "boolean" || typeof mod?.ppr === "boolean" || typeof mod?.experimental_ppr === "boolean" || typeof mod?.revalidate !== "undefined" || typeof mod?.dynamic !== "undefined" || typeof parseRouteRenderingDirective(source) !== "undefined";
|
|
6375
|
+
}
|
|
6143
6376
|
function parseRouteRenderingDirective(source) {
|
|
6144
6377
|
if (!source) {
|
|
6145
6378
|
return void 0;
|
|
@@ -6264,9 +6497,10 @@ function skipHorizontalWhitespace(source, start) {
|
|
|
6264
6497
|
}
|
|
6265
6498
|
return index;
|
|
6266
6499
|
}
|
|
6267
|
-
async function collectSSGPages(routes, loadModule2) {
|
|
6500
|
+
async function collectSSGPages(routes, loadModule2, options = {}) {
|
|
6268
6501
|
const ssgPages = [];
|
|
6269
6502
|
const ssrRoutes = [];
|
|
6503
|
+
const staticCandidateRoutes = [];
|
|
6270
6504
|
for (const route of routes) {
|
|
6271
6505
|
try {
|
|
6272
6506
|
const mod = await loadModule2(route.filePath);
|
|
@@ -6274,7 +6508,8 @@ async function collectSSGPages(routes, loadModule2) {
|
|
|
6274
6508
|
ssrRoutes.push(route.path);
|
|
6275
6509
|
continue;
|
|
6276
6510
|
}
|
|
6277
|
-
const
|
|
6511
|
+
const source = await (0, import_promises3.readFile)(route.filePath, "utf8").catch(() => void 0);
|
|
6512
|
+
const rendering = resolveRouteRenderingConfig(mod, source);
|
|
6278
6513
|
if (rendering.ssg) {
|
|
6279
6514
|
if (route.isDynamic) {
|
|
6280
6515
|
const getStaticPaths = mod.getStaticPaths || mod.generateStaticParams;
|
|
@@ -6301,12 +6536,26 @@ async function collectSSGPages(routes, loadModule2) {
|
|
|
6301
6536
|
}
|
|
6302
6537
|
} else {
|
|
6303
6538
|
ssrRoutes.push(route.path);
|
|
6539
|
+
if (options.suggestStaticRendering !== false && analyzeStaticRouteCandidate(mod, source, { isDynamic: route.isDynamic }).candidate) {
|
|
6540
|
+
staticCandidateRoutes.push(route.path);
|
|
6541
|
+
}
|
|
6304
6542
|
}
|
|
6305
6543
|
} catch (error) {
|
|
6306
6544
|
console.error(`Error processing route ${route.path}:`, error);
|
|
6307
6545
|
ssrRoutes.push(route.path);
|
|
6308
6546
|
}
|
|
6309
6547
|
}
|
|
6548
|
+
if (staticCandidateRoutes.length > 0) {
|
|
6549
|
+
const visibleRoutes = staticCandidateRoutes.slice(0, 10);
|
|
6550
|
+
const remainingCount = staticCandidateRoutes.length - visibleRoutes.length;
|
|
6551
|
+
const remainingSuffix = remainingCount > 0 ? `
|
|
6552
|
+
\u2026and ${remainingCount} more` : "";
|
|
6553
|
+
console.warn(
|
|
6554
|
+
`[Farm.js] ${staticCandidateRoutes.length} route${staticCandidateRoutes.length === 1 ? " appears" : "s appear"} eligible for static rendering:
|
|
6555
|
+
${visibleRoutes.join("\n ")}${remainingSuffix}
|
|
6556
|
+
Add \`export const dynamic = "force-static";\` after verifying that imported code does not read cookies, headers, authentication, or other request data.`
|
|
6557
|
+
);
|
|
6558
|
+
}
|
|
6310
6559
|
return { ssg: ssgPages, ssr: ssrRoutes };
|
|
6311
6560
|
}
|
|
6312
6561
|
function materializeSSGRoutePath(routePattern, params) {
|
|
@@ -6408,7 +6657,7 @@ function matchSSGPage(urlPath, ssgPages) {
|
|
|
6408
6657
|
const normalizedPath = urlPath === "/" ? "/" : urlPath.replace(/\/$/, "");
|
|
6409
6658
|
return ssgPages.find((page2) => page2.urlPath === normalizedPath);
|
|
6410
6659
|
}
|
|
6411
|
-
var import_promises3, OPTIONAL_CATCH_ALL_SEGMENT, REQUIRED_CATCH_ALL_SEGMENT, REQUIRED_DYNAMIC_SEGMENT;
|
|
6660
|
+
var import_promises3, OPTIONAL_CATCH_ALL_SEGMENT, REQUIRED_CATCH_ALL_SEGMENT, REQUIRED_DYNAMIC_SEGMENT, REQUEST_API_LABELS, ROUTE_PROP_LABELS;
|
|
6412
6661
|
var init_ssg = __esm({
|
|
6413
6662
|
"src/ssg.ts"() {
|
|
6414
6663
|
"use strict";
|
|
@@ -6416,8 +6665,35 @@ var init_ssg = __esm({
|
|
|
6416
6665
|
OPTIONAL_CATCH_ALL_SEGMENT = /^\[\[\.\.\.([^\]]+)\]\]$/;
|
|
6417
6666
|
REQUIRED_CATCH_ALL_SEGMENT = /^\[\.\.\.([^\]]+)\]$/;
|
|
6418
6667
|
REQUIRED_DYNAMIC_SEGMENT = /^\[([^\]]+)\]$/;
|
|
6668
|
+
REQUEST_API_LABELS = /* @__PURE__ */ new Map([
|
|
6669
|
+
["cookies", "request cookies"],
|
|
6670
|
+
["headers", "request headers"],
|
|
6671
|
+
["getCurrentRequest", "the current Request"],
|
|
6672
|
+
["useSearchParams", "URL search parameters"],
|
|
6673
|
+
["auth", "request authentication"],
|
|
6674
|
+
["getServerSession", "request authentication"],
|
|
6675
|
+
["getSession", "request authentication"],
|
|
6676
|
+
["currentUser", "request authentication"]
|
|
6677
|
+
]);
|
|
6678
|
+
ROUTE_PROP_LABELS = /* @__PURE__ */ new Map([
|
|
6679
|
+
["searchParams", "URL search parameters"],
|
|
6680
|
+
["middleware", "middleware request data"],
|
|
6681
|
+
["middlewareData", "middleware request data"],
|
|
6682
|
+
["context", "request context"]
|
|
6683
|
+
]);
|
|
6419
6684
|
__name(resolveRouteRenderingConfig, "resolveRouteRenderingConfig");
|
|
6420
6685
|
__name(resolveRouteRenderingConfigFromFile, "resolveRouteRenderingConfigFromFile");
|
|
6686
|
+
__name(analyzeStaticRouteCandidate, "analyzeStaticRouteCandidate");
|
|
6687
|
+
__name(findRequestBoundSourceBlockers, "findRequestBoundSourceBlockers");
|
|
6688
|
+
__name(readRequestApiImportBindings, "readRequestApiImportBindings");
|
|
6689
|
+
__name(readNamespaceImportBindings, "readNamespaceImportBindings");
|
|
6690
|
+
__name(readStaticImportClauses, "readStaticImportClauses");
|
|
6691
|
+
__name(readDefaultRouteParameters, "readDefaultRouteParameters");
|
|
6692
|
+
__name(stripCommentsAndLiteralContents, "stripCommentsAndLiteralContents");
|
|
6693
|
+
__name(stripComments, "stripComments");
|
|
6694
|
+
__name(sanitizeSource, "sanitizeSource");
|
|
6695
|
+
__name(escapeRegExp2, "escapeRegExp");
|
|
6696
|
+
__name(hasExplicitRenderingConfig, "hasExplicitRenderingConfig");
|
|
6421
6697
|
__name(parseRouteRenderingDirective, "parseRouteRenderingDirective");
|
|
6422
6698
|
__name(parseKnownRenderingDirective, "parseKnownRenderingDirective");
|
|
6423
6699
|
__name(normalizeDynamicMode, "normalizeDynamicMode");
|
|
@@ -7098,7 +7374,7 @@ function getProgrammaticRouteSearchClientOptions(search) {
|
|
|
7098
7374
|
if (search.temporary?.length) options.temporary = [...search.temporary];
|
|
7099
7375
|
return Object.keys(options).length > 0 ? options : void 0;
|
|
7100
7376
|
}
|
|
7101
|
-
function resolveProgrammaticRouteSearch(searchConfig, rawSearch,
|
|
7377
|
+
function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path31, routePath) {
|
|
7102
7378
|
const schema = getProgrammaticRouteSearchSchema(searchConfig);
|
|
7103
7379
|
const search = parseProgrammaticSchema(schema, rawSearch, "search", routePath);
|
|
7104
7380
|
const options = getProgrammaticRouteSearchOptions(searchConfig);
|
|
@@ -7107,7 +7383,7 @@ function resolveProgrammaticRouteSearch(searchConfig, rawSearch, path29, routePa
|
|
|
7107
7383
|
schema,
|
|
7108
7384
|
rawSearch,
|
|
7109
7385
|
parsedSearch: search,
|
|
7110
|
-
path:
|
|
7386
|
+
path: path31
|
|
7111
7387
|
});
|
|
7112
7388
|
return { search, canonicalPath };
|
|
7113
7389
|
}
|
|
@@ -7274,7 +7550,7 @@ function createRouteModuleFromProgrammaticPage(route) {
|
|
|
7274
7550
|
mod.__farmRouteData = route.data;
|
|
7275
7551
|
mod.__farmRouteParsesProps = true;
|
|
7276
7552
|
mod.__farmResolveRouteProps = (props) => resolveProgrammaticRouteProps(route, props);
|
|
7277
|
-
mod.__farmResolveRouteCanonicalPath = (rawSearch,
|
|
7553
|
+
mod.__farmResolveRouteCanonicalPath = (rawSearch, path31) => resolveProgrammaticRouteSearch(route.search, rawSearch, path31, route.path).canonicalPath;
|
|
7278
7554
|
}
|
|
7279
7555
|
if (route.pending || route.error || route.notFound) {
|
|
7280
7556
|
mod.__farmRouteComponents = {
|
|
@@ -7672,25 +7948,25 @@ var init_routes = __esm({
|
|
|
7672
7948
|
];
|
|
7673
7949
|
__name(defineRoutes, "defineRoutes");
|
|
7674
7950
|
routesBuilder = {
|
|
7675
|
-
page(
|
|
7951
|
+
page(path31, options) {
|
|
7676
7952
|
return normalizeProgrammaticRoute({
|
|
7677
7953
|
kind: "page",
|
|
7678
|
-
path:
|
|
7954
|
+
path: path31,
|
|
7679
7955
|
...options
|
|
7680
7956
|
});
|
|
7681
7957
|
},
|
|
7682
|
-
layout(
|
|
7958
|
+
layout(path31, options) {
|
|
7683
7959
|
return normalizeProgrammaticRoute({
|
|
7684
7960
|
kind: "layout",
|
|
7685
|
-
path:
|
|
7961
|
+
path: path31,
|
|
7686
7962
|
...options
|
|
7687
7963
|
});
|
|
7688
7964
|
},
|
|
7689
|
-
api(
|
|
7965
|
+
api(path31, options) {
|
|
7690
7966
|
const { render, runtime, regions, maxDuration, ...methods } = options;
|
|
7691
7967
|
return normalizeProgrammaticRoute({
|
|
7692
7968
|
kind: "api",
|
|
7693
|
-
path:
|
|
7969
|
+
path: path31,
|
|
7694
7970
|
render,
|
|
7695
7971
|
runtime,
|
|
7696
7972
|
regions,
|
|
@@ -7833,6 +8109,19 @@ var init_routes_server = __esm({
|
|
|
7833
8109
|
}
|
|
7834
8110
|
});
|
|
7835
8111
|
|
|
8112
|
+
// src/island.ts
|
|
8113
|
+
function isFarmIslandStrategy(value) {
|
|
8114
|
+
return FARM_ISLAND_STRATEGIES.includes(value);
|
|
8115
|
+
}
|
|
8116
|
+
var FARM_ISLAND_STRATEGIES;
|
|
8117
|
+
var init_island = __esm({
|
|
8118
|
+
"src/island.ts"() {
|
|
8119
|
+
"use strict";
|
|
8120
|
+
FARM_ISLAND_STRATEGIES = ["load", "interaction", "visible", "idle"];
|
|
8121
|
+
__name(isFarmIslandStrategy, "isFarmIslandStrategy");
|
|
8122
|
+
}
|
|
8123
|
+
});
|
|
8124
|
+
|
|
7836
8125
|
// src/utils/client-component.ts
|
|
7837
8126
|
function readIfExists(filePath) {
|
|
7838
8127
|
try {
|
|
@@ -7890,53 +8179,180 @@ function hasHydrateExport(content) {
|
|
|
7890
8179
|
}
|
|
7891
8180
|
return /\bexport\s+const\s+hydrate\s*=\s*true\b/.test(content) || /\bexport\s*\{\s*hydrate\s*\}\b/.test(content);
|
|
7892
8181
|
}
|
|
8182
|
+
function tokenizeModuleSource(content) {
|
|
8183
|
+
const tokens = [];
|
|
8184
|
+
let index = 0;
|
|
8185
|
+
let line = 1;
|
|
8186
|
+
while (index < content.length) {
|
|
8187
|
+
const character = content[index];
|
|
8188
|
+
if (/\s/.test(character)) {
|
|
8189
|
+
if (character === "\n") line++;
|
|
8190
|
+
index++;
|
|
8191
|
+
continue;
|
|
8192
|
+
}
|
|
8193
|
+
if (character === "/" && content[index + 1] === "/") {
|
|
8194
|
+
index += 2;
|
|
8195
|
+
while (index < content.length && content[index] !== "\n") index++;
|
|
8196
|
+
continue;
|
|
8197
|
+
}
|
|
8198
|
+
if (character === "/" && content[index + 1] === "*") {
|
|
8199
|
+
index += 2;
|
|
8200
|
+
while (index < content.length) {
|
|
8201
|
+
if (content[index] === "\n") line++;
|
|
8202
|
+
if (content[index] === "*" && content[index + 1] === "/") {
|
|
8203
|
+
index += 2;
|
|
8204
|
+
break;
|
|
8205
|
+
}
|
|
8206
|
+
index++;
|
|
8207
|
+
}
|
|
8208
|
+
continue;
|
|
8209
|
+
}
|
|
8210
|
+
if (character === '"' || character === "'") {
|
|
8211
|
+
const quote = character;
|
|
8212
|
+
const tokenLine = line;
|
|
8213
|
+
let value = "";
|
|
8214
|
+
index++;
|
|
8215
|
+
while (index < content.length) {
|
|
8216
|
+
const next = content[index];
|
|
8217
|
+
if (next === "\\") {
|
|
8218
|
+
value += next;
|
|
8219
|
+
if (index + 1 < content.length) value += content[index + 1];
|
|
8220
|
+
index += 2;
|
|
8221
|
+
continue;
|
|
8222
|
+
}
|
|
8223
|
+
if (next === quote) {
|
|
8224
|
+
index++;
|
|
8225
|
+
break;
|
|
8226
|
+
}
|
|
8227
|
+
if (next === "\n") line++;
|
|
8228
|
+
value += next;
|
|
8229
|
+
index++;
|
|
8230
|
+
}
|
|
8231
|
+
tokens.push({ kind: "string", value, line: tokenLine });
|
|
8232
|
+
continue;
|
|
8233
|
+
}
|
|
8234
|
+
if (character === "`") {
|
|
8235
|
+
index++;
|
|
8236
|
+
while (index < content.length) {
|
|
8237
|
+
const next = content[index];
|
|
8238
|
+
if (next === "\\") {
|
|
8239
|
+
index += 2;
|
|
8240
|
+
continue;
|
|
8241
|
+
}
|
|
8242
|
+
if (next === "`") {
|
|
8243
|
+
index++;
|
|
8244
|
+
break;
|
|
8245
|
+
}
|
|
8246
|
+
if (next === "\n") line++;
|
|
8247
|
+
index++;
|
|
8248
|
+
}
|
|
8249
|
+
continue;
|
|
8250
|
+
}
|
|
8251
|
+
if (/[A-Za-z_$]/.test(character)) {
|
|
8252
|
+
const start = index++;
|
|
8253
|
+
while (index < content.length && /[\w$]/.test(content[index])) index++;
|
|
8254
|
+
tokens.push({ kind: "identifier", value: content.slice(start, index), line });
|
|
8255
|
+
continue;
|
|
8256
|
+
}
|
|
8257
|
+
tokens.push({ kind: "punctuation", value: character, line });
|
|
8258
|
+
index++;
|
|
8259
|
+
}
|
|
8260
|
+
return tokens;
|
|
8261
|
+
}
|
|
8262
|
+
function isIslandExportStart(tokens, index) {
|
|
8263
|
+
const token = tokens[index];
|
|
8264
|
+
const previous = tokens[index - 1];
|
|
8265
|
+
const startsStatement = !previous || previous.value === ";" || previous.value === "{" || previous.value === "}" || token.line > previous.line;
|
|
8266
|
+
return startsStatement && token.value === "export" && tokens[index + 1]?.value === "const" && tokens[index + 2]?.value === "island";
|
|
8267
|
+
}
|
|
8268
|
+
function getIslandStrategyExport(content) {
|
|
8269
|
+
if (!content) return null;
|
|
8270
|
+
const tokens = tokenizeModuleSource(content);
|
|
8271
|
+
for (let index = 0; index < tokens.length - 2; index++) {
|
|
8272
|
+
if (!isIslandExportStart(tokens, index)) continue;
|
|
8273
|
+
let valueIndex = index + 3;
|
|
8274
|
+
if (tokens[valueIndex]?.value === ":") {
|
|
8275
|
+
while (valueIndex < tokens.length && tokens[valueIndex].value !== "=") valueIndex++;
|
|
8276
|
+
}
|
|
8277
|
+
if (tokens[valueIndex]?.value !== "=") break;
|
|
8278
|
+
valueIndex++;
|
|
8279
|
+
const literal = tokens[valueIndex];
|
|
8280
|
+
if (!literal || literal.kind !== "string" || !isFarmIslandStrategy(literal.value)) break;
|
|
8281
|
+
let trailingIndex = valueIndex + 1;
|
|
8282
|
+
if (tokens[trailingIndex]?.value === "as" && tokens[trailingIndex + 1]?.value === "const") {
|
|
8283
|
+
trailingIndex += 2;
|
|
8284
|
+
}
|
|
8285
|
+
const trailing = tokens[trailingIndex];
|
|
8286
|
+
if (trailing && trailing.value !== ";" && trailing.line === literal.line) break;
|
|
8287
|
+
return literal.value;
|
|
8288
|
+
}
|
|
8289
|
+
if (tokens.some((_token, index) => isIslandExportStart(tokens, index))) {
|
|
8290
|
+
throw new Error(
|
|
8291
|
+
'Farm island configuration must be a static "load", "interaction", "visible", or "idle" string literal.'
|
|
8292
|
+
);
|
|
8293
|
+
}
|
|
8294
|
+
return null;
|
|
8295
|
+
}
|
|
7893
8296
|
function stripUseClientDirective(content) {
|
|
7894
8297
|
return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
|
|
7895
8298
|
}
|
|
7896
|
-
function parseClientModuleMetadata(content) {
|
|
8299
|
+
function parseClientModuleMetadata(content, inspectIslandExport) {
|
|
7897
8300
|
if (!content) {
|
|
7898
8301
|
return {
|
|
7899
8302
|
isClientComponent: false,
|
|
7900
|
-
hasHydrateExport: false
|
|
8303
|
+
hasHydrateExport: false,
|
|
8304
|
+
islandStrategy: null
|
|
7901
8305
|
};
|
|
7902
8306
|
}
|
|
8307
|
+
const isClientComponent = hasUseClientDirective(content);
|
|
8308
|
+
const hasHydrate = hasHydrateExport(content);
|
|
7903
8309
|
return {
|
|
7904
|
-
isClientComponent
|
|
7905
|
-
hasHydrateExport:
|
|
8310
|
+
isClientComponent,
|
|
8311
|
+
hasHydrateExport: hasHydrate,
|
|
8312
|
+
islandStrategy: inspectIslandExport || isClientComponent || hasHydrate ? getIslandStrategyExport(content) : null
|
|
7906
8313
|
};
|
|
7907
8314
|
}
|
|
7908
8315
|
function getClientModuleMetadata(modulePath, root) {
|
|
7909
8316
|
const resolvedPath = resolveModuleSourcePath(modulePath, root);
|
|
7910
|
-
return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set());
|
|
8317
|
+
return inspectClientModuleMetadata(resolvedPath, root, /* @__PURE__ */ new Set(), true);
|
|
7911
8318
|
}
|
|
7912
|
-
function inspectClientModuleMetadata(resolvedPath, root, visited) {
|
|
8319
|
+
function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandExport) {
|
|
7913
8320
|
if (!resolvedPath || visited.has(resolvedPath)) {
|
|
7914
8321
|
return {
|
|
7915
8322
|
isClientComponent: false,
|
|
7916
|
-
shouldHydrate: false
|
|
8323
|
+
shouldHydrate: false,
|
|
8324
|
+
islandStrategy: null
|
|
7917
8325
|
};
|
|
7918
8326
|
}
|
|
7919
8327
|
visited.add(resolvedPath);
|
|
7920
8328
|
const content = readIfExists(resolvedPath);
|
|
7921
|
-
const parsed = parseClientModuleMetadata(content);
|
|
8329
|
+
const parsed = parseClientModuleMetadata(content, inspectIslandExport);
|
|
7922
8330
|
if (parsed.isClientComponent) {
|
|
7923
8331
|
return {
|
|
7924
8332
|
isClientComponent: true,
|
|
7925
|
-
shouldHydrate: true
|
|
8333
|
+
shouldHydrate: true,
|
|
8334
|
+
islandStrategy: parsed.islandStrategy ?? "load"
|
|
7926
8335
|
};
|
|
7927
8336
|
}
|
|
7928
8337
|
let importsClientBoundary = false;
|
|
8338
|
+
let importedIslandStrategy = null;
|
|
7929
8339
|
for (const specifier of getRelativeImportSpecifiers(content)) {
|
|
7930
8340
|
const importedPath = resolveImportedModuleSourcePath(resolvedPath, specifier, root);
|
|
7931
|
-
const importedMetadata = inspectClientModuleMetadata(importedPath, root, visited);
|
|
8341
|
+
const importedMetadata = inspectClientModuleMetadata(importedPath, root, visited, false);
|
|
7932
8342
|
if (importedMetadata.isClientComponent || importedMetadata.shouldHydrate) {
|
|
7933
8343
|
importsClientBoundary = true;
|
|
7934
|
-
|
|
8344
|
+
if (importedIslandStrategy === null) {
|
|
8345
|
+
importedIslandStrategy = importedMetadata.islandStrategy;
|
|
8346
|
+
} else if (importedIslandStrategy !== importedMetadata.islandStrategy) {
|
|
8347
|
+
importedIslandStrategy = "load";
|
|
8348
|
+
}
|
|
7935
8349
|
}
|
|
7936
8350
|
}
|
|
8351
|
+
const shouldHydrate = parsed.hasHydrateExport || importsClientBoundary;
|
|
7937
8352
|
return {
|
|
7938
8353
|
isClientComponent: false,
|
|
7939
|
-
shouldHydrate
|
|
8354
|
+
shouldHydrate,
|
|
8355
|
+
islandStrategy: shouldHydrate ? parsed.islandStrategy ?? importedIslandStrategy ?? "load" : null
|
|
7940
8356
|
};
|
|
7941
8357
|
}
|
|
7942
8358
|
function getRelativeImportSpecifiers(content) {
|
|
@@ -7976,6 +8392,7 @@ var init_client_component = __esm({
|
|
|
7976
8392
|
import_fs2 = __toESM(require("fs"));
|
|
7977
8393
|
import_path5 = __toESM(require("path"));
|
|
7978
8394
|
import_url2 = require("url");
|
|
8395
|
+
init_island();
|
|
7979
8396
|
__name(readIfExists, "readIfExists");
|
|
7980
8397
|
__name(resolveModuleSourcePath, "resolveModuleSourcePath");
|
|
7981
8398
|
RESOLVABLE_SOURCE_EXTENSIONS = [
|
|
@@ -7990,6 +8407,9 @@ var init_client_component = __esm({
|
|
|
7990
8407
|
];
|
|
7991
8408
|
__name(hasUseClientDirective, "hasUseClientDirective");
|
|
7992
8409
|
__name(hasHydrateExport, "hasHydrateExport");
|
|
8410
|
+
__name(tokenizeModuleSource, "tokenizeModuleSource");
|
|
8411
|
+
__name(isIslandExportStart, "isIslandExportStart");
|
|
8412
|
+
__name(getIslandStrategyExport, "getIslandStrategyExport");
|
|
7993
8413
|
__name(stripUseClientDirective, "stripUseClientDirective");
|
|
7994
8414
|
__name(parseClientModuleMetadata, "parseClientModuleMetadata");
|
|
7995
8415
|
__name(getClientModuleMetadata, "getClientModuleMetadata");
|
|
@@ -8231,6 +8651,9 @@ var init_route_slots = __esm({
|
|
|
8231
8651
|
});
|
|
8232
8652
|
|
|
8233
8653
|
// src/routing/route-manager.ts
|
|
8654
|
+
function shouldSuggestStaticRenderingForI18n(i18n) {
|
|
8655
|
+
return !i18n || i18n.routing === "prefix-always" || i18n.routing === "prefix-except-default" && i18n.detection.every((signal) => signal === "url");
|
|
8656
|
+
}
|
|
8234
8657
|
function routeSpecificity(entry) {
|
|
8235
8658
|
return entry.route.segments.reduce((score, segment) => {
|
|
8236
8659
|
if (!segment.isDynamic) return score + 100;
|
|
@@ -8302,6 +8725,7 @@ var init_route_manager = __esm({
|
|
|
8302
8725
|
init_route_runtime();
|
|
8303
8726
|
init_routing();
|
|
8304
8727
|
init_route_slots();
|
|
8728
|
+
__name(shouldSuggestStaticRenderingForI18n, "shouldSuggestStaticRenderingForI18n");
|
|
8305
8729
|
__name(routeSpecificity, "routeSpecificity");
|
|
8306
8730
|
_RouteManager = class _RouteManager {
|
|
8307
8731
|
constructor(config, viteServer) {
|
|
@@ -8538,6 +8962,7 @@ var init_route_manager = __esm({
|
|
|
8538
8962
|
modulePath: toUrlPath(entry.modulePath),
|
|
8539
8963
|
shouldHydrate: metadata.shouldHydrate,
|
|
8540
8964
|
isClientComponent: metadata.isClientComponent,
|
|
8965
|
+
islandStrategy: metadata.islandStrategy,
|
|
8541
8966
|
search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
|
|
8542
8967
|
segments: entry.route.segments.map((seg) => ({
|
|
8543
8968
|
segment: seg.segment,
|
|
@@ -9000,8 +9425,10 @@ var init_route_manager = __esm({
|
|
|
9000
9425
|
isDynamic: entry.route.segments.some((seg) => seg.isDynamic),
|
|
9001
9426
|
pattern: entry.pattern
|
|
9002
9427
|
}));
|
|
9003
|
-
const result = await collectSSGPages(routes, (filePath) => this.loadRouteModule(filePath));
|
|
9004
9428
|
const i18n = this.getI18nConfig();
|
|
9429
|
+
const result = await collectSSGPages(routes, (filePath) => this.loadRouteModule(filePath), {
|
|
9430
|
+
suggestStaticRendering: shouldSuggestStaticRenderingForI18n(i18n)
|
|
9431
|
+
});
|
|
9005
9432
|
if (!i18n) {
|
|
9006
9433
|
return result;
|
|
9007
9434
|
}
|
|
@@ -10423,7 +10850,8 @@ ${imports}
|
|
|
10423
10850
|
function renderFarmFontDevHead(root) {
|
|
10424
10851
|
const registry = registries.get(normalizeRoot(root));
|
|
10425
10852
|
if (!registry || registry.production || registry.size === 0) return "";
|
|
10426
|
-
return registry.renderPreloadTags(false)
|
|
10853
|
+
return `${registry.renderPreloadTags(false)}
|
|
10854
|
+
<link rel="stylesheet" href="/@farm/fonts.css">`;
|
|
10427
10855
|
}
|
|
10428
10856
|
function findFontBindings(ast) {
|
|
10429
10857
|
const named = /* @__PURE__ */ new Map();
|
|
@@ -10666,7 +11094,8 @@ function serializeFontResult(font) {
|
|
|
10666
11094
|
fontFamily: stack,
|
|
10667
11095
|
...font.style ? { fontStyle: font.style } : {},
|
|
10668
11096
|
...font.weight !== void 0 && !String(font.weight).includes(" ") ? { fontWeight: font.weight } : {}
|
|
10669
|
-
}
|
|
11097
|
+
},
|
|
11098
|
+
preloads: font.preloadResources
|
|
10670
11099
|
});
|
|
10671
11100
|
}
|
|
10672
11101
|
function renderFontDefinitionCss(font, production, basePath) {
|
|
@@ -11179,6 +11608,10 @@ ${FONT_SECTION_END}
|
|
|
11179
11608
|
fallback,
|
|
11180
11609
|
display,
|
|
11181
11610
|
preload: raw.preload !== false,
|
|
11611
|
+
preloadResources: raw.preload === false ? [] : normalizedSources.map(({ resource }) => ({
|
|
11612
|
+
href: resourceUrl(resource, production, this.basePath),
|
|
11613
|
+
type: fontContentType(resource.extension)
|
|
11614
|
+
})),
|
|
11182
11615
|
weight: defaultWeight,
|
|
11183
11616
|
style: raw.style === void 0 ? void 0 : defaultStyle,
|
|
11184
11617
|
sources: normalizedSources
|
|
@@ -11275,7 +11708,7 @@ ${FONT_SECTION_END}
|
|
|
11275
11708
|
const normalizedExtension = extension.toLowerCase();
|
|
11276
11709
|
const hash = (0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex").slice(0, 12);
|
|
11277
11710
|
const baseName = sanitizeFileName(import_node_path5.default.basename(fileName, extension)) || "font";
|
|
11278
|
-
const outputFileName = `assets/fonts/${baseName}
|
|
11711
|
+
const outputFileName = `assets/fonts/${baseName}-h${hash}${normalizedExtension}`;
|
|
11279
11712
|
const key = `${hash}${normalizedExtension}`;
|
|
11280
11713
|
const existing = this.resources.get(key);
|
|
11281
11714
|
if (existing) return existing;
|
|
@@ -11347,6 +11780,172 @@ ${FONT_SECTION_END}
|
|
|
11347
11780
|
}
|
|
11348
11781
|
});
|
|
11349
11782
|
|
|
11783
|
+
// src/metadata-image.ts
|
|
11784
|
+
function isResponse(value) {
|
|
11785
|
+
return typeof Response !== "undefined" && (value instanceof Response || Boolean(
|
|
11786
|
+
value && typeof value === "object" && typeof value.arrayBuffer === "function" && value.headers
|
|
11787
|
+
));
|
|
11788
|
+
}
|
|
11789
|
+
function isThenable(value) {
|
|
11790
|
+
return Boolean(
|
|
11791
|
+
value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function"
|
|
11792
|
+
);
|
|
11793
|
+
}
|
|
11794
|
+
async function prepareMetadataImageNode(node) {
|
|
11795
|
+
if (isThenable(node)) {
|
|
11796
|
+
return prepareMetadataImageNode(await node);
|
|
11797
|
+
}
|
|
11798
|
+
if (Array.isArray(node)) {
|
|
11799
|
+
return Promise.all(node.map((child) => prepareMetadataImageNode(child)));
|
|
11800
|
+
}
|
|
11801
|
+
if (!import_react4.default.isValidElement(node)) {
|
|
11802
|
+
return node;
|
|
11803
|
+
}
|
|
11804
|
+
const element = node;
|
|
11805
|
+
const type = element.type;
|
|
11806
|
+
const props = element.props || {};
|
|
11807
|
+
if (typeof type === "function") {
|
|
11808
|
+
if (type.prototype?.isReactComponent) {
|
|
11809
|
+
throw new Error(
|
|
11810
|
+
"Metadata image components must be stateless function components; React class components are not supported."
|
|
11811
|
+
);
|
|
11812
|
+
}
|
|
11813
|
+
return prepareMetadataImageNode(await type(props));
|
|
11814
|
+
}
|
|
11815
|
+
if (type && typeof type === "object") {
|
|
11816
|
+
if (type.$$typeof === REACT_MEMO_TYPE) {
|
|
11817
|
+
return prepareMetadataImageNode(import_react4.default.createElement(type.type, props));
|
|
11818
|
+
}
|
|
11819
|
+
if (type.$$typeof === REACT_FORWARD_REF_TYPE) {
|
|
11820
|
+
return prepareMetadataImageNode(await type.render(props, null));
|
|
11821
|
+
}
|
|
11822
|
+
if (type.$$typeof === REACT_LAZY_TYPE) {
|
|
11823
|
+
return prepareMetadataImageNode(import_react4.default.createElement(type._init(type._payload), props));
|
|
11824
|
+
}
|
|
11825
|
+
}
|
|
11826
|
+
const preparedChildren = await prepareMetadataImageNode(props.children);
|
|
11827
|
+
const preparedProps = { ...props };
|
|
11828
|
+
if (typeof preparedProps.className === "string") {
|
|
11829
|
+
preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(" ");
|
|
11830
|
+
delete preparedProps.className;
|
|
11831
|
+
}
|
|
11832
|
+
delete preparedProps.children;
|
|
11833
|
+
return import_react4.default.createElement(type, {
|
|
11834
|
+
...preparedProps,
|
|
11835
|
+
key: element.key,
|
|
11836
|
+
children: preparedChildren
|
|
11837
|
+
});
|
|
11838
|
+
}
|
|
11839
|
+
async function normalizeFonts(fonts) {
|
|
11840
|
+
if (!fonts?.length) return void 0;
|
|
11841
|
+
return Promise.all(
|
|
11842
|
+
fonts.map(async (font) => {
|
|
11843
|
+
const data = await font.data;
|
|
11844
|
+
const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;
|
|
11845
|
+
return { ...font, data: arrayBuffer };
|
|
11846
|
+
})
|
|
11847
|
+
);
|
|
11848
|
+
}
|
|
11849
|
+
function resolveCacheControl(revalidate) {
|
|
11850
|
+
if (revalidate === false) {
|
|
11851
|
+
return "public, max-age=31536000, immutable";
|
|
11852
|
+
}
|
|
11853
|
+
if (typeof revalidate === "number" && Number.isFinite(revalidate) && revalidate > 0) {
|
|
11854
|
+
return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;
|
|
11855
|
+
}
|
|
11856
|
+
return "public, max-age=0, must-revalidate";
|
|
11857
|
+
}
|
|
11858
|
+
function toArrayBuffer(value) {
|
|
11859
|
+
if (value instanceof ArrayBuffer) return value;
|
|
11860
|
+
const bytes = new Uint8Array(value.byteLength);
|
|
11861
|
+
bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
11862
|
+
return bytes.buffer;
|
|
11863
|
+
}
|
|
11864
|
+
async function createEntityTag(body) {
|
|
11865
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", body);
|
|
11866
|
+
const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 32);
|
|
11867
|
+
return `"${hash}"`;
|
|
11868
|
+
}
|
|
11869
|
+
async function finalizeMetadataImageResponse(body, headers, options) {
|
|
11870
|
+
const responseHeaders = new Headers(headers);
|
|
11871
|
+
const etag = await createEntityTag(body);
|
|
11872
|
+
responseHeaders.set("ETag", etag);
|
|
11873
|
+
responseHeaders.set("Content-Length", String(body.byteLength));
|
|
11874
|
+
responseHeaders.set("X-Content-Type-Options", "nosniff");
|
|
11875
|
+
const matchesEntityTag = options.ifNoneMatch?.trim() === "*" || options.ifNoneMatch?.split(",").some((candidate) => candidate.trim().replace(/^W\//, "") === etag);
|
|
11876
|
+
if (matchesEntityTag) {
|
|
11877
|
+
return new Response(null, { status: 304, headers: responseHeaders });
|
|
11878
|
+
}
|
|
11879
|
+
return new Response(options.method?.toUpperCase() === "HEAD" ? null : body, {
|
|
11880
|
+
status: 200,
|
|
11881
|
+
headers: responseHeaders
|
|
11882
|
+
});
|
|
11883
|
+
}
|
|
11884
|
+
async function createFarmMetadataImageResponse(value, imageModule, options = {}) {
|
|
11885
|
+
const method = (options.method || "GET").toUpperCase();
|
|
11886
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
11887
|
+
return new Response(null, { status: 405, headers: { Allow: "GET, HEAD" } });
|
|
11888
|
+
}
|
|
11889
|
+
if (isResponse(value)) {
|
|
11890
|
+
return method === "HEAD" ? new Response(null, { status: value.status, headers: value.headers }) : value;
|
|
11891
|
+
}
|
|
11892
|
+
const cacheControl = resolveCacheControl(imageModule.revalidate);
|
|
11893
|
+
const explicitContentType = imageModule.contentType?.split(";", 1)[0]?.trim().toLowerCase();
|
|
11894
|
+
if (import_react4.default.isValidElement(value) && explicitContentType !== "image/svg+xml") {
|
|
11895
|
+
const { ImageResponse } = await import("@vercel/og");
|
|
11896
|
+
const element = await prepareMetadataImageNode(value);
|
|
11897
|
+
const response = new ImageResponse(element, {
|
|
11898
|
+
width: imageModule.size?.width || 1200,
|
|
11899
|
+
height: imageModule.size?.height || 630,
|
|
11900
|
+
fonts: await normalizeFonts(imageModule.fonts),
|
|
11901
|
+
emoji: imageModule.emoji,
|
|
11902
|
+
debug: imageModule.debug,
|
|
11903
|
+
headers: { "cache-control": cacheControl }
|
|
11904
|
+
});
|
|
11905
|
+
const headers = new Headers(response.headers);
|
|
11906
|
+
headers.set("Cache-Control", cacheControl);
|
|
11907
|
+
return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);
|
|
11908
|
+
}
|
|
11909
|
+
let body;
|
|
11910
|
+
if (typeof value === "string") {
|
|
11911
|
+
body = toArrayBuffer(new TextEncoder().encode(value));
|
|
11912
|
+
} else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
11913
|
+
body = toArrayBuffer(value);
|
|
11914
|
+
} else if (import_react4.default.isValidElement(value)) {
|
|
11915
|
+
body = toArrayBuffer(new TextEncoder().encode((0, import_server.renderToStaticMarkup)(value)));
|
|
11916
|
+
} else {
|
|
11917
|
+
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
11918
|
+
}
|
|
11919
|
+
return finalizeMetadataImageResponse(
|
|
11920
|
+
body,
|
|
11921
|
+
{
|
|
11922
|
+
"Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
|
|
11923
|
+
"Cache-Control": cacheControl
|
|
11924
|
+
},
|
|
11925
|
+
options
|
|
11926
|
+
);
|
|
11927
|
+
}
|
|
11928
|
+
var import_react4, import_server, REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE, REACT_LAZY_TYPE;
|
|
11929
|
+
var init_metadata_image = __esm({
|
|
11930
|
+
"src/metadata-image.ts"() {
|
|
11931
|
+
"use strict";
|
|
11932
|
+
import_react4 = __toESM(require("react"));
|
|
11933
|
+
import_server = require("react-dom/server");
|
|
11934
|
+
REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
11935
|
+
REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
11936
|
+
REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
|
|
11937
|
+
__name(isResponse, "isResponse");
|
|
11938
|
+
__name(isThenable, "isThenable");
|
|
11939
|
+
__name(prepareMetadataImageNode, "prepareMetadataImageNode");
|
|
11940
|
+
__name(normalizeFonts, "normalizeFonts");
|
|
11941
|
+
__name(resolveCacheControl, "resolveCacheControl");
|
|
11942
|
+
__name(toArrayBuffer, "toArrayBuffer");
|
|
11943
|
+
__name(createEntityTag, "createEntityTag");
|
|
11944
|
+
__name(finalizeMetadataImageResponse, "finalizeMetadataImageResponse");
|
|
11945
|
+
__name(createFarmMetadataImageResponse, "createFarmMetadataImageResponse");
|
|
11946
|
+
}
|
|
11947
|
+
});
|
|
11948
|
+
|
|
11350
11949
|
// src/server/renderer.ts
|
|
11351
11950
|
function hasRequestHeader(req, name) {
|
|
11352
11951
|
const value = req.headers[name.toLowerCase()];
|
|
@@ -11410,7 +12009,7 @@ function createPPRRefreshScript() {
|
|
|
11410
12009
|
return `<script>(function(){if(window.__FARM_PPR_REFRESHING__)return;window.__FARM_PPR_REFRESHING__=true;function replaceRoot(html){var doc=new DOMParser().parseFromString(html,"text/html");var next=doc.getElementById("root");var current=document.getElementById("root");if(!next||!current)return;current.innerHTML=next.innerHTML;}fetch(window.location.href,{credentials:"same-origin",headers:{"x-farm-ppr-refresh":"1"}}).then(function(response){return response.ok?response.text():null;}).then(function(html){if(html)replaceRoot(html);}).catch(function(){});})();</script>`;
|
|
11411
12010
|
}
|
|
11412
12011
|
function createPreHydrationClickQueueScript() {
|
|
11413
|
-
return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches('button,[role="button"],input[type="button"],input[type="submit"],input[type="reset"]'))return target;target=target.parentElement}return null}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]"))return;if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,createdAt:Date.now()});event.preventDefault();event.stopImmediatePropagation()},true);})();</script>`;
|
|
12012
|
+
return `<script>(function(){if(window.__FARM_PREHYDRATION_CLICK_QUEUE__)return;var queue=[];window.__FARM_PREHYDRATION_CLICK_QUEUE__=queue;window.__FARM_HYDRATED__=false;document.documentElement.dataset.farmHydrated="false";function isModified(event){return !!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}function closestQueuedTarget(target){while(target&&target!==document.documentElement){if(target.matches&&target.matches('button,[role="button"],input[type="button"],input[type="submit"],input[type="reset"]'))return target;target=target.parentElement}return null}document.addEventListener("click",function(event){if(window.__FARM_HYDRATED__)return;if(event.defaultPrevented||event.button!==0||isModified(event))return;var target=closestQueuedTarget(event.target);if(!target||target.closest&&target.closest("a[href]")||target.closest&&target.closest('[data-farm-island-hydrated="true"]'))return;if(queue.some(function(item){return item.target===target}))return;queue.push({target:target,createdAt:Date.now()});document.dispatchEvent(new CustomEvent("farm:island-interaction",{detail:{target:target}}));event.preventDefault();event.stopImmediatePropagation()},true);})();</script>`;
|
|
11414
12013
|
}
|
|
11415
12014
|
function searchParamsToObject(searchParams) {
|
|
11416
12015
|
const output = {};
|
|
@@ -11502,12 +12101,12 @@ function createRouteStateProps(input) {
|
|
|
11502
12101
|
context: input.pluginExposedContext.size > 0 ? { data: input.pluginExposedContext } : void 0
|
|
11503
12102
|
};
|
|
11504
12103
|
}
|
|
11505
|
-
var
|
|
12104
|
+
var import_react5, import_server2, fs2, path11, import_stream, cachedClerkProvider, importRuntimeModule, _FarmRouteErrorBoundary, FarmRouteErrorBoundary, _ServerRenderer, ServerRenderer;
|
|
11506
12105
|
var init_renderer = __esm({
|
|
11507
12106
|
"src/server/renderer.ts"() {
|
|
11508
12107
|
"use strict";
|
|
11509
|
-
|
|
11510
|
-
|
|
12108
|
+
import_react5 = __toESM(require("react"));
|
|
12109
|
+
import_server2 = require("react-dom/server");
|
|
11511
12110
|
fs2 = __toESM(require("fs"));
|
|
11512
12111
|
path11 = __toESM(require("path"));
|
|
11513
12112
|
init_utils();
|
|
@@ -11530,6 +12129,7 @@ var init_renderer = __esm({
|
|
|
11530
12129
|
init_routing();
|
|
11531
12130
|
init_response();
|
|
11532
12131
|
init_font_vite();
|
|
12132
|
+
init_metadata_image();
|
|
11533
12133
|
cachedClerkProvider = null;
|
|
11534
12134
|
importRuntimeModule = new Function("specifier", "return import(specifier);");
|
|
11535
12135
|
__name(hasRequestHeader, "hasRequestHeader");
|
|
@@ -11546,7 +12146,7 @@ var init_renderer = __esm({
|
|
|
11546
12146
|
__name(createDeferredHydrationScript, "createDeferredHydrationScript");
|
|
11547
12147
|
__name(toMiddlewareMap2, "toMiddlewareMap");
|
|
11548
12148
|
__name(isWebResponse, "isWebResponse");
|
|
11549
|
-
_FarmRouteErrorBoundary = class _FarmRouteErrorBoundary extends
|
|
12149
|
+
_FarmRouteErrorBoundary = class _FarmRouteErrorBoundary extends import_react5.default.Component {
|
|
11550
12150
|
constructor(props) {
|
|
11551
12151
|
super(props);
|
|
11552
12152
|
this.state = { hasError: false, error: null };
|
|
@@ -11557,7 +12157,7 @@ var init_renderer = __esm({
|
|
|
11557
12157
|
render() {
|
|
11558
12158
|
if (this.state.hasError) {
|
|
11559
12159
|
const Fallback = this.props.Fallback;
|
|
11560
|
-
return
|
|
12160
|
+
return import_react5.default.createElement(Fallback, {
|
|
11561
12161
|
...this.props.fallbackProps,
|
|
11562
12162
|
error: this.state.error,
|
|
11563
12163
|
reset: /* @__PURE__ */ __name(() => this.setState({ hasError: false, error: null }), "reset")
|
|
@@ -11726,14 +12326,14 @@ var init_renderer = __esm({
|
|
|
11726
12326
|
searchParams: Promise.resolve({}),
|
|
11727
12327
|
path: page2.urlPath
|
|
11728
12328
|
};
|
|
11729
|
-
let pageElement =
|
|
12329
|
+
let pageElement = import_react5.default.createElement(
|
|
11730
12330
|
PageComponent,
|
|
11731
12331
|
pageProps
|
|
11732
12332
|
);
|
|
11733
12333
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
11734
12334
|
const layoutModule = layoutModules[i];
|
|
11735
12335
|
const LayoutComponent = layoutModule.default;
|
|
11736
|
-
pageElement =
|
|
12336
|
+
pageElement = import_react5.default.createElement(
|
|
11737
12337
|
LayoutComponent,
|
|
11738
12338
|
{
|
|
11739
12339
|
children: pageElement,
|
|
@@ -12059,6 +12659,7 @@ var init_renderer = __esm({
|
|
|
12059
12659
|
req.__FARM_ROUTE__ = pathname;
|
|
12060
12660
|
req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
|
|
12061
12661
|
req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
|
|
12662
|
+
req.__FARM_ISLAND_STRATEGY__ = moduleMetadata.islandStrategy;
|
|
12062
12663
|
req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
|
|
12063
12664
|
req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
|
|
12064
12665
|
loadingBoundaryEntry.modulePath.indexOf("/src/app/")
|
|
@@ -12111,12 +12712,12 @@ var init_renderer = __esm({
|
|
|
12111
12712
|
await _runWithMiddlewareData(middlewareDataForContext, async () => {
|
|
12112
12713
|
await _runWithMiddlewareContext(middlewareContext, async () => {
|
|
12113
12714
|
await _runWithCurrentRequest(currentRequest, async () => {
|
|
12114
|
-
let pageElement =
|
|
12715
|
+
let pageElement = import_react5.default.createElement(
|
|
12115
12716
|
PageComponent,
|
|
12116
12717
|
pageProps
|
|
12117
12718
|
);
|
|
12118
12719
|
if (LoadingFallbackComponent) {
|
|
12119
|
-
const loadingFallback =
|
|
12720
|
+
const loadingFallback = import_react5.default.createElement(LoadingFallbackComponent, {
|
|
12120
12721
|
...createRouteStateProps({
|
|
12121
12722
|
params,
|
|
12122
12723
|
searchParamsObject,
|
|
@@ -12125,16 +12726,21 @@ var init_renderer = __esm({
|
|
|
12125
12726
|
pluginExposedContext
|
|
12126
12727
|
})
|
|
12127
12728
|
});
|
|
12128
|
-
pageElement =
|
|
12129
|
-
|
|
12729
|
+
pageElement = import_react5.default.createElement(
|
|
12730
|
+
import_react5.default.Suspense,
|
|
12130
12731
|
{ fallback: loadingFallback },
|
|
12131
12732
|
pageElement
|
|
12132
12733
|
);
|
|
12133
12734
|
}
|
|
12134
12735
|
if (isClientComponent || shouldHydrate) {
|
|
12135
|
-
pageElement =
|
|
12736
|
+
pageElement = import_react5.default.createElement(
|
|
12136
12737
|
"div",
|
|
12137
|
-
{
|
|
12738
|
+
{
|
|
12739
|
+
id: "__farm_page__",
|
|
12740
|
+
"data-farm-client": "true",
|
|
12741
|
+
"data-farm-island": "page",
|
|
12742
|
+
"data-farm-island-strategy": moduleMetadata.islandStrategy ?? "load"
|
|
12743
|
+
},
|
|
12138
12744
|
pageElement
|
|
12139
12745
|
);
|
|
12140
12746
|
}
|
|
@@ -12146,11 +12752,11 @@ var init_renderer = __esm({
|
|
|
12146
12752
|
const slotProps = {};
|
|
12147
12753
|
for (const slot of renderedRouteSlots) {
|
|
12148
12754
|
if (slot.ownerPattern !== layoutEntry.pattern) continue;
|
|
12149
|
-
let slotElement =
|
|
12755
|
+
let slotElement = import_react5.default.createElement(
|
|
12150
12756
|
slot.module.default,
|
|
12151
12757
|
slot.props
|
|
12152
12758
|
);
|
|
12153
|
-
slotElement =
|
|
12759
|
+
slotElement = import_react5.default.createElement(
|
|
12154
12760
|
"div",
|
|
12155
12761
|
{
|
|
12156
12762
|
id: slot.containerId,
|
|
@@ -12161,7 +12767,7 @@ var init_renderer = __esm({
|
|
|
12161
12767
|
);
|
|
12162
12768
|
slotProps[slot.name] = slotElement;
|
|
12163
12769
|
}
|
|
12164
|
-
wrappedElement =
|
|
12770
|
+
wrappedElement = import_react5.default.createElement(
|
|
12165
12771
|
LayoutComponent,
|
|
12166
12772
|
{
|
|
12167
12773
|
children: wrappedElement,
|
|
@@ -12171,7 +12777,7 @@ var init_renderer = __esm({
|
|
|
12171
12777
|
);
|
|
12172
12778
|
}
|
|
12173
12779
|
if (ErrorFallbackComponent) {
|
|
12174
|
-
wrappedElement =
|
|
12780
|
+
wrappedElement = import_react5.default.createElement(
|
|
12175
12781
|
FarmRouteErrorBoundary,
|
|
12176
12782
|
{
|
|
12177
12783
|
Fallback: ErrorFallbackComponent,
|
|
@@ -12304,7 +12910,7 @@ var init_renderer = __esm({
|
|
|
12304
12910
|
if (!cachedClerkProvider) {
|
|
12305
12911
|
cachedClerkProvider = await importRuntimeModule("@clerk/react");
|
|
12306
12912
|
}
|
|
12307
|
-
wrapped =
|
|
12913
|
+
wrapped = import_react5.default.createElement(
|
|
12308
12914
|
cachedClerkProvider.ClerkProvider,
|
|
12309
12915
|
provider.props || {},
|
|
12310
12916
|
wrapped
|
|
@@ -12379,6 +12985,13 @@ var init_renderer = __esm({
|
|
|
12379
12985
|
return reference;
|
|
12380
12986
|
}
|
|
12381
12987
|
async renderMetadataImage(req, res, options) {
|
|
12988
|
+
const method = (req.method || "GET").toUpperCase();
|
|
12989
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
12990
|
+
res.statusCode = 405;
|
|
12991
|
+
res.setHeader("Allow", "GET, HEAD");
|
|
12992
|
+
res.end();
|
|
12993
|
+
return;
|
|
12994
|
+
}
|
|
12382
12995
|
if (options.image.sourceType === "static") {
|
|
12383
12996
|
if (!options.image.staticInfo) {
|
|
12384
12997
|
throw new Error(`Static metadata image ${options.image.modulePath} is missing file info`);
|
|
@@ -12404,42 +13017,12 @@ var init_renderer = __esm({
|
|
|
12404
13017
|
await this.writeMetadataImageResponse(req, res, handlerResult, imageModule);
|
|
12405
13018
|
}
|
|
12406
13019
|
async writeMetadataImageResponse(req, res, value, imageModule) {
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
res.end();
|
|
12414
|
-
return;
|
|
12415
|
-
}
|
|
12416
|
-
const body2 = Buffer.from(await value.arrayBuffer());
|
|
12417
|
-
res.write(body2);
|
|
12418
|
-
res.end();
|
|
12419
|
-
return;
|
|
12420
|
-
}
|
|
12421
|
-
const contentType = imageModule.contentType || "image/svg+xml; charset=utf-8";
|
|
12422
|
-
let body;
|
|
12423
|
-
if (typeof value === "string") {
|
|
12424
|
-
body = value;
|
|
12425
|
-
} else if (value instanceof ArrayBuffer) {
|
|
12426
|
-
body = Buffer.from(value);
|
|
12427
|
-
} else if (ArrayBuffer.isView(value)) {
|
|
12428
|
-
body = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
12429
|
-
} else if (import_react4.default.isValidElement(value)) {
|
|
12430
|
-
body = (0, import_server.renderToStaticMarkup)(value);
|
|
12431
|
-
} else {
|
|
12432
|
-
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
12433
|
-
}
|
|
12434
|
-
res.statusCode = res.statusCode || 200;
|
|
12435
|
-
res.setHeader("Content-Type", contentType);
|
|
12436
|
-
res.setHeader("Cache-Control", "public, max-age=0, must-revalidate");
|
|
12437
|
-
if (req.method === "HEAD") {
|
|
12438
|
-
res.end();
|
|
12439
|
-
return;
|
|
12440
|
-
}
|
|
12441
|
-
res.write(body);
|
|
12442
|
-
res.end();
|
|
13020
|
+
const ifNoneMatch = req.headers["if-none-match"];
|
|
13021
|
+
const response = await createFarmMetadataImageResponse(value, imageModule, {
|
|
13022
|
+
method: req.method,
|
|
13023
|
+
ifNoneMatch: Array.isArray(ifNoneMatch) ? ifNoneMatch[0] : ifNoneMatch
|
|
13024
|
+
});
|
|
13025
|
+
await sendWebResponse(res, response);
|
|
12443
13026
|
}
|
|
12444
13027
|
async writeStaticMetadataImageResponse(req, res, image) {
|
|
12445
13028
|
const method = (req.method || "GET").toUpperCase();
|
|
@@ -12486,7 +13069,7 @@ var init_renderer = __esm({
|
|
|
12486
13069
|
return false;
|
|
12487
13070
|
}
|
|
12488
13071
|
const ErrorComponent = errorModule.default;
|
|
12489
|
-
const errorElement =
|
|
13072
|
+
const errorElement = import_react5.default.createElement(ErrorComponent, {
|
|
12490
13073
|
...createRouteStateProps({
|
|
12491
13074
|
params: options.params,
|
|
12492
13075
|
searchParamsObject: options.searchParamsObject,
|
|
@@ -12504,7 +13087,7 @@ var init_renderer = __esm({
|
|
|
12504
13087
|
);
|
|
12505
13088
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
12506
13089
|
const LayoutComponent = layoutModules[i].default;
|
|
12507
|
-
wrapped =
|
|
13090
|
+
wrapped = import_react5.default.createElement(
|
|
12508
13091
|
LayoutComponent,
|
|
12509
13092
|
{
|
|
12510
13093
|
children: wrapped,
|
|
@@ -12569,6 +13152,7 @@ var init_renderer = __esm({
|
|
|
12569
13152
|
search: routeEntry.search,
|
|
12570
13153
|
isClientComponent: routeEntry.isClientComponent,
|
|
12571
13154
|
shouldHydrate: routeEntry.shouldHydrate,
|
|
13155
|
+
islandStrategy: routeEntry.islandStrategy,
|
|
12572
13156
|
preloads: [routeEntry.modulePath],
|
|
12573
13157
|
assets: []
|
|
12574
13158
|
};
|
|
@@ -12605,6 +13189,7 @@ window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
|
|
|
12605
13189
|
window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
|
|
12606
13190
|
window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
|
|
12607
13191
|
window.__FARM_SHOULD_HYDRATE__ = ${JSON.stringify(req.__FARM_SHOULD_HYDRATE__ === true)};
|
|
13192
|
+
window.__FARM_ISLAND_STRATEGY__ = ${JSON.stringify(req.__FARM_ISLAND_STRATEGY__ || "load")};
|
|
12608
13193
|
window.__FARM_PAGE_MODULE__ = ${JSON.stringify(relativePath2)};
|
|
12609
13194
|
window.__FARM_LOADING_MODULE__ = ${JSON.stringify(
|
|
12610
13195
|
req.__FARM_LOADING_MODULE_PATH__ || null
|
|
@@ -12622,8 +13207,8 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12622
13207
|
const i18nSnapshot = getFarmI18nClientSnapshot();
|
|
12623
13208
|
const i18nAlternateTags = i18nSnapshot ? renderI18nAlternateLinks(req.__FARM_ROUTE__ || req.url || "/", i18nSnapshot) : "";
|
|
12624
13209
|
const fontHead = renderFarmFontDevHead(this.config.root || process.cwd());
|
|
12625
|
-
const streamRoot =
|
|
12626
|
-
const { pipe, abort } = (0,
|
|
13210
|
+
const streamRoot = import_react5.default.createElement("div", { style: { display: "contents" } }, element);
|
|
13211
|
+
const { pipe, abort } = (0, import_server2.renderToPipeableStream)(streamRoot, {
|
|
12627
13212
|
onShellReady() {
|
|
12628
13213
|
const shellReadyMs = Date.now() - streamStartTime;
|
|
12629
13214
|
emitFarmEvent({
|
|
@@ -12781,12 +13366,12 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12781
13366
|
break;
|
|
12782
13367
|
}
|
|
12783
13368
|
}
|
|
12784
|
-
let element =
|
|
13369
|
+
let element = import_react5.default.createElement(
|
|
12785
13370
|
NotFoundComponent,
|
|
12786
13371
|
{ pathname }
|
|
12787
13372
|
);
|
|
12788
13373
|
if (LayoutComponent) {
|
|
12789
|
-
element =
|
|
13374
|
+
element = import_react5.default.createElement(
|
|
12790
13375
|
LayoutComponent,
|
|
12791
13376
|
{ children: element }
|
|
12792
13377
|
);
|
|
@@ -12936,6 +13521,7 @@ var init_app = __esm({
|
|
|
12936
13521
|
init_server2();
|
|
12937
13522
|
init_cache();
|
|
12938
13523
|
init_auth_config();
|
|
13524
|
+
init_preload();
|
|
12939
13525
|
defaultDocsConfig = {
|
|
12940
13526
|
enabled: false,
|
|
12941
13527
|
entry: "/docs",
|
|
@@ -13001,6 +13587,7 @@ var init_app = __esm({
|
|
|
13001
13587
|
context: config.context || (() => void 0),
|
|
13002
13588
|
serverActions: resolveServerActionsConfig(config.serverActions),
|
|
13003
13589
|
images: resolveFarmImageConfig(config.images),
|
|
13590
|
+
performance: resolveFarmPerformanceConfig(config.performance),
|
|
13004
13591
|
i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
|
|
13005
13592
|
root,
|
|
13006
13593
|
mode: process.env.NODE_ENV === "production" ? "production" : "development"
|
|
@@ -14594,6 +15181,49 @@ var init_search_client = __esm({
|
|
|
14594
15181
|
}
|
|
14595
15182
|
});
|
|
14596
15183
|
|
|
15184
|
+
// src/docs/fonts.ts
|
|
15185
|
+
function resolveFarmDocsFontAssets(root) {
|
|
15186
|
+
return FARM_DOCS_FONT_SOURCES.flatMap(({ family, packagePath }) => {
|
|
15187
|
+
const sourcePath = import_node_path8.default.join(root, "node_modules", packagePath);
|
|
15188
|
+
if (!(0, import_node_fs5.existsSync)(sourcePath)) return [];
|
|
15189
|
+
const source = (0, import_node_fs5.readFileSync)(sourcePath);
|
|
15190
|
+
const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex").slice(0, 12);
|
|
15191
|
+
const extension = import_node_path8.default.extname(packagePath);
|
|
15192
|
+
const baseName = import_node_path8.default.basename(packagePath, extension);
|
|
15193
|
+
return [
|
|
15194
|
+
{
|
|
15195
|
+
family,
|
|
15196
|
+
sourcePath,
|
|
15197
|
+
url: `/assets/fonts/${baseName}-h${fingerprint}${extension}`
|
|
15198
|
+
}
|
|
15199
|
+
];
|
|
15200
|
+
});
|
|
15201
|
+
}
|
|
15202
|
+
function toFarmDocsPublicFontAssets(assets) {
|
|
15203
|
+
return assets.map(({ family, url }) => ({ family, url }));
|
|
15204
|
+
}
|
|
15205
|
+
var import_node_crypto3, import_node_fs5, import_node_path8, FARM_DOCS_FONT_SOURCES;
|
|
15206
|
+
var init_fonts = __esm({
|
|
15207
|
+
"src/docs/fonts.ts"() {
|
|
15208
|
+
"use strict";
|
|
15209
|
+
import_node_crypto3 = require("crypto");
|
|
15210
|
+
import_node_fs5 = require("fs");
|
|
15211
|
+
import_node_path8 = __toESM(require("path"));
|
|
15212
|
+
FARM_DOCS_FONT_SOURCES = [
|
|
15213
|
+
{
|
|
15214
|
+
family: "Geist Sans",
|
|
15215
|
+
packagePath: "geist/dist/fonts/geist-sans/Geist-Variable.woff2"
|
|
15216
|
+
},
|
|
15217
|
+
{
|
|
15218
|
+
family: "Geist Mono",
|
|
15219
|
+
packagePath: "geist/dist/fonts/geist-mono/GeistMono-Variable.woff2"
|
|
15220
|
+
}
|
|
15221
|
+
];
|
|
15222
|
+
__name(resolveFarmDocsFontAssets, "resolveFarmDocsFontAssets");
|
|
15223
|
+
__name(toFarmDocsPublicFontAssets, "toFarmDocsPublicFontAssets");
|
|
15224
|
+
}
|
|
15225
|
+
});
|
|
15226
|
+
|
|
14597
15227
|
// src/default-styles.ts
|
|
14598
15228
|
var defaultGlobalCSS;
|
|
14599
15229
|
var init_default_styles = __esm({
|
|
@@ -15001,12 +15631,12 @@ var init_module = __esm({
|
|
|
15001
15631
|
function isMiddlewareResponse(value) {
|
|
15002
15632
|
return value instanceof Response;
|
|
15003
15633
|
}
|
|
15004
|
-
var fs4,
|
|
15634
|
+
var fs4, path19, _MiddlewareManager, MiddlewareManager;
|
|
15005
15635
|
var init_manager = __esm({
|
|
15006
15636
|
"src/middleware/manager.ts"() {
|
|
15007
15637
|
"use strict";
|
|
15008
15638
|
fs4 = __toESM(require("fs"));
|
|
15009
|
-
|
|
15639
|
+
path19 = __toESM(require("path"));
|
|
15010
15640
|
init_context();
|
|
15011
15641
|
init_module();
|
|
15012
15642
|
init_utils();
|
|
@@ -15086,8 +15716,8 @@ var init_manager = __esm({
|
|
|
15086
15716
|
const entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
15087
15717
|
for (const entry of entries) {
|
|
15088
15718
|
if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
|
|
15089
|
-
const subPath =
|
|
15090
|
-
const subRoutePath =
|
|
15719
|
+
const subPath = path19.join(dir, entry.name);
|
|
15720
|
+
const subRoutePath = path19.posix.join(routePath, entry.name);
|
|
15091
15721
|
await this.discoverInDirectory(subPath, subRoutePath, discovered);
|
|
15092
15722
|
}
|
|
15093
15723
|
}
|
|
@@ -15098,7 +15728,7 @@ var init_manager = __esm({
|
|
|
15098
15728
|
findMiddlewareFile(dir) {
|
|
15099
15729
|
const extensions = [".ts", ".tsx", ".js", ".jsx"];
|
|
15100
15730
|
for (const ext of extensions) {
|
|
15101
|
-
const filePath =
|
|
15731
|
+
const filePath = path19.join(dir, `middleware${ext}`);
|
|
15102
15732
|
if (fs4.existsSync(filePath)) {
|
|
15103
15733
|
return filePath;
|
|
15104
15734
|
}
|
|
@@ -15449,7 +16079,7 @@ var init_manager = __esm({
|
|
|
15449
16079
|
// src/write-file-if-changed.ts
|
|
15450
16080
|
function writeFileIfChanged(filePath, content) {
|
|
15451
16081
|
try {
|
|
15452
|
-
if ((0,
|
|
16082
|
+
if ((0, import_node_fs6.readFileSync)(filePath, "utf8") === content) {
|
|
15453
16083
|
return false;
|
|
15454
16084
|
}
|
|
15455
16085
|
} catch (error) {
|
|
@@ -15457,14 +16087,14 @@ function writeFileIfChanged(filePath, content) {
|
|
|
15457
16087
|
throw error;
|
|
15458
16088
|
}
|
|
15459
16089
|
}
|
|
15460
|
-
(0,
|
|
16090
|
+
(0, import_node_fs6.writeFileSync)(filePath, content, "utf8");
|
|
15461
16091
|
return true;
|
|
15462
16092
|
}
|
|
15463
|
-
var
|
|
16093
|
+
var import_node_fs6;
|
|
15464
16094
|
var init_write_file_if_changed = __esm({
|
|
15465
16095
|
"src/write-file-if-changed.ts"() {
|
|
15466
16096
|
"use strict";
|
|
15467
|
-
|
|
16097
|
+
import_node_fs6 = require("fs");
|
|
15468
16098
|
__name(writeFileIfChanged, "writeFileIfChanged");
|
|
15469
16099
|
}
|
|
15470
16100
|
});
|
|
@@ -15565,11 +16195,11 @@ var init_type_generator = __esm({
|
|
|
15565
16195
|
routeGroups.get(key).push(route);
|
|
15566
16196
|
}
|
|
15567
16197
|
const nestedStructure = {};
|
|
15568
|
-
for (const [
|
|
16198
|
+
for (const [path31, routeList] of routeGroups) {
|
|
15569
16199
|
const route = routeList[0];
|
|
15570
16200
|
const importPath = this.getRouteImportPath(route, options.outFile);
|
|
15571
16201
|
const routeName = this.pathToRouteName(route.path);
|
|
15572
|
-
const cleanPath =
|
|
16202
|
+
const cleanPath = path31 === "/api" ? "" : path31.replace(/^\/api\//, "");
|
|
15573
16203
|
const parts = cleanPath ? cleanPath.split("/") : [];
|
|
15574
16204
|
const allMethods = routeList.flatMap((r) => r.methods);
|
|
15575
16205
|
for (const method of allMethods) {
|
|
@@ -15628,8 +16258,8 @@ ${typeExports}
|
|
|
15628
16258
|
const relativeImport = (0, import_path10.relative)((0, import_path10.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
15629
16259
|
return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
|
|
15630
16260
|
}
|
|
15631
|
-
pathToRouteName(
|
|
15632
|
-
return (
|
|
16261
|
+
pathToRouteName(path31) {
|
|
16262
|
+
return (path31 === "/api" ? "root" : path31.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
|
|
15633
16263
|
}
|
|
15634
16264
|
structureToTypeString(obj, indent) {
|
|
15635
16265
|
const spaces = " ".repeat(indent);
|
|
@@ -15649,15 +16279,15 @@ ${typeExports}
|
|
|
15649
16279
|
toTypePropertyKey(key) {
|
|
15650
16280
|
return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
|
|
15651
16281
|
}
|
|
15652
|
-
getBaseExportName(
|
|
15653
|
-
const cleanPath =
|
|
16282
|
+
getBaseExportName(path31) {
|
|
16283
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
15654
16284
|
if (cleanPath === "") {
|
|
15655
16285
|
return "api";
|
|
15656
16286
|
}
|
|
15657
16287
|
return cleanPath;
|
|
15658
16288
|
}
|
|
15659
|
-
getExportName(
|
|
15660
|
-
const cleanPath =
|
|
16289
|
+
getExportName(path31, method) {
|
|
16290
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
15661
16291
|
if (cleanPath === "") {
|
|
15662
16292
|
return method.toLowerCase();
|
|
15663
16293
|
}
|
|
@@ -15719,12 +16349,12 @@ function createRoutePattern(route) {
|
|
|
15719
16349
|
}).join("/");
|
|
15720
16350
|
}
|
|
15721
16351
|
async function generateRouteTypes(options) {
|
|
15722
|
-
const root =
|
|
16352
|
+
const root = path20.resolve(options.root);
|
|
15723
16353
|
const srcDir = options.srcDir || "src";
|
|
15724
16354
|
const outFile = options.outFile || DEFAULT_OUT_FILE;
|
|
15725
|
-
const outPath =
|
|
16355
|
+
const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
|
|
15726
16356
|
const content = await createRouteTypeDeclarations(options, outPath);
|
|
15727
|
-
fs5.mkdirSync(
|
|
16357
|
+
fs5.mkdirSync(path20.dirname(outPath), { recursive: true });
|
|
15728
16358
|
writeFileIfChanged(outPath, content);
|
|
15729
16359
|
return outPath;
|
|
15730
16360
|
}
|
|
@@ -15734,7 +16364,7 @@ async function createRouteTypeDeclarations(options, outPath) {
|
|
|
15734
16364
|
const patterns = /* @__PURE__ */ new Set();
|
|
15735
16365
|
const glob = await import("fast-glob");
|
|
15736
16366
|
for (const source of sourceRoots) {
|
|
15737
|
-
const appDir =
|
|
16367
|
+
const appDir = path20.join(source.root, source.srcDir, "app");
|
|
15738
16368
|
if (fs5.existsSync(appDir)) {
|
|
15739
16369
|
const pageFiles = await glob.default("**/page.{ts,tsx,js,jsx,md,mdx}", {
|
|
15740
16370
|
cwd: appDir,
|
|
@@ -15763,7 +16393,7 @@ async function createRouteTypeDeclarations(options, outPath) {
|
|
|
15763
16393
|
const patternLiterals = sortedPatterns.map(routePatternToRouteLiteral);
|
|
15764
16394
|
const routePathType = suppressLintOnLink ? "string" : typeLiterals.length ? typeLiterals.join(" | ") : "never";
|
|
15765
16395
|
const routePatternType = suppressLintOnLink ? "string" : patternLiterals.length ? patternLiterals.join(" | ") : "never";
|
|
15766
|
-
const routeTypesImportPath = `./${
|
|
16396
|
+
const routeTypesImportPath = `./${path20.basename(outPath).replace(/\.d\.ts$/, "")}`;
|
|
15767
16397
|
const augmentationBlock = suppressLintOnLink ? "" : `
|
|
15768
16398
|
declare module "@farm.js/core/client" {
|
|
15769
16399
|
interface LinkDefaultRoute {
|
|
@@ -15799,11 +16429,11 @@ export type RoutePattern = ${routePatternType};${augmentationBlock}
|
|
|
15799
16429
|
`;
|
|
15800
16430
|
return content;
|
|
15801
16431
|
}
|
|
15802
|
-
var
|
|
16432
|
+
var path20, fs5, DEFAULT_OUT_FILE;
|
|
15803
16433
|
var init_generate_route_types = __esm({
|
|
15804
16434
|
"src/routing/generate-route-types.ts"() {
|
|
15805
16435
|
"use strict";
|
|
15806
|
-
|
|
16436
|
+
path20 = __toESM(require("path"));
|
|
15807
16437
|
fs5 = __toESM(require("fs"));
|
|
15808
16438
|
init_utils();
|
|
15809
16439
|
init_route_slots();
|
|
@@ -15821,17 +16451,17 @@ var init_generate_route_types = __esm({
|
|
|
15821
16451
|
|
|
15822
16452
|
// src/env-types.ts
|
|
15823
16453
|
async function generateEnvTypes(options) {
|
|
15824
|
-
const root =
|
|
16454
|
+
const root = path21.resolve(options.root);
|
|
15825
16455
|
const srcDir = options.srcDir || "src";
|
|
15826
16456
|
const outFile = options.outFile || DEFAULT_OUT_FILE2;
|
|
15827
|
-
const outPath =
|
|
16457
|
+
const outPath = path21.isAbsolute(outFile) ? outFile : path21.join(root, srcDir, outFile);
|
|
15828
16458
|
const content = createEnvTypeDeclarations(options, outPath);
|
|
15829
|
-
fs6.mkdirSync(
|
|
16459
|
+
fs6.mkdirSync(path21.dirname(outPath), { recursive: true });
|
|
15830
16460
|
writeFileIfChanged(outPath, content);
|
|
15831
16461
|
return outPath;
|
|
15832
16462
|
}
|
|
15833
16463
|
function createEnvTypeDeclarations(options, outPath) {
|
|
15834
|
-
const root =
|
|
16464
|
+
const root = path21.resolve(options.root);
|
|
15835
16465
|
const configPath = findConfigPath(root, options.configPath);
|
|
15836
16466
|
const configPaths = [
|
|
15837
16467
|
...(options.layerConfigPaths ?? []).filter((value) => fs6.existsSync(value)),
|
|
@@ -15894,11 +16524,11 @@ export {};
|
|
|
15894
16524
|
}
|
|
15895
16525
|
function findConfigPath(root, configPath) {
|
|
15896
16526
|
if (configPath) {
|
|
15897
|
-
const resolvedPath =
|
|
16527
|
+
const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
|
|
15898
16528
|
return fs6.existsSync(resolvedPath) ? resolvedPath : null;
|
|
15899
16529
|
}
|
|
15900
16530
|
for (const filename of CONFIG_FILENAMES2) {
|
|
15901
|
-
const resolvedPath =
|
|
16531
|
+
const resolvedPath = path21.join(root, filename);
|
|
15902
16532
|
if (fs6.existsSync(resolvedPath)) {
|
|
15903
16533
|
return resolvedPath;
|
|
15904
16534
|
}
|
|
@@ -15959,15 +16589,15 @@ export {};
|
|
|
15959
16589
|
`;
|
|
15960
16590
|
}
|
|
15961
16591
|
function toTypeImportPath(outPath, targetPath) {
|
|
15962
|
-
const relativePath2 =
|
|
16592
|
+
const relativePath2 = path21.relative(path21.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
|
|
15963
16593
|
return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
|
|
15964
16594
|
}
|
|
15965
|
-
var fs6,
|
|
16595
|
+
var fs6, path21, DEFAULT_OUT_FILE2, CONFIG_FILENAMES2;
|
|
15966
16596
|
var init_env_types = __esm({
|
|
15967
16597
|
"src/env-types.ts"() {
|
|
15968
16598
|
"use strict";
|
|
15969
16599
|
fs6 = __toESM(require("fs"));
|
|
15970
|
-
|
|
16600
|
+
path21 = __toESM(require("path"));
|
|
15971
16601
|
init_write_file_if_changed();
|
|
15972
16602
|
DEFAULT_OUT_FILE2 = "farm-env.d.ts";
|
|
15973
16603
|
CONFIG_FILENAMES2 = [
|
|
@@ -16000,8 +16630,8 @@ var init_env_types = __esm({
|
|
|
16000
16630
|
|
|
16001
16631
|
// src/image-types.ts
|
|
16002
16632
|
function generateFarmImageTypes(options) {
|
|
16003
|
-
const outputPath = options.outFile ?
|
|
16004
|
-
(0,
|
|
16633
|
+
const outputPath = options.outFile ? import_node_path9.default.resolve(options.root, options.outFile) : import_node_path9.default.join(options.root, options.srcDir || "src", "farm-images.d.ts");
|
|
16634
|
+
(0, import_node_fs7.mkdirSync)(import_node_path9.default.dirname(outputPath), { recursive: true });
|
|
16005
16635
|
writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
|
|
16006
16636
|
return outputPath;
|
|
16007
16637
|
}
|
|
@@ -16025,12 +16655,12 @@ declare module "*?url" {
|
|
|
16025
16655
|
}
|
|
16026
16656
|
`;
|
|
16027
16657
|
}
|
|
16028
|
-
var
|
|
16658
|
+
var import_node_fs7, import_node_path9, FARM_STATIC_IMAGE_EXTENSIONS;
|
|
16029
16659
|
var init_image_types = __esm({
|
|
16030
16660
|
"src/image-types.ts"() {
|
|
16031
16661
|
"use strict";
|
|
16032
|
-
|
|
16033
|
-
|
|
16662
|
+
import_node_fs7 = require("fs");
|
|
16663
|
+
import_node_path9 = __toESM(require("path"));
|
|
16034
16664
|
init_write_file_if_changed();
|
|
16035
16665
|
FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
|
|
16036
16666
|
__name(generateFarmImageTypes, "generateFarmImageTypes");
|
|
@@ -16042,9 +16672,9 @@ var init_image_types = __esm({
|
|
|
16042
16672
|
async function generateFarmI18nTypes(options) {
|
|
16043
16673
|
if (!options.config.enabled) return void 0;
|
|
16044
16674
|
const { signatures } = await readFarmI18nCatalogs(options.config);
|
|
16045
|
-
const outFile = options.outFile ? (0,
|
|
16675
|
+
const outFile = options.outFile ? (0, import_node_path10.resolve)(options.root, options.outFile) : (0, import_node_path10.join)((0, import_node_path10.resolve)(options.root), options.srcDir || "src", "farm-i18n.d.ts");
|
|
16046
16676
|
const content = renderFarmI18nTypes(options.config.locales, signatures);
|
|
16047
|
-
(0,
|
|
16677
|
+
(0, import_node_fs8.mkdirSync)((0, import_node_path10.dirname)(outFile), { recursive: true });
|
|
16048
16678
|
writeFileIfChanged(outFile, content);
|
|
16049
16679
|
return outFile;
|
|
16050
16680
|
}
|
|
@@ -16085,12 +16715,12 @@ function argumentType(kind) {
|
|
|
16085
16715
|
return "string";
|
|
16086
16716
|
}
|
|
16087
16717
|
}
|
|
16088
|
-
var
|
|
16718
|
+
var import_node_fs8, import_node_path10;
|
|
16089
16719
|
var init_type_generator2 = __esm({
|
|
16090
16720
|
"src/i18n/type-generator.ts"() {
|
|
16091
16721
|
"use strict";
|
|
16092
|
-
|
|
16093
|
-
|
|
16722
|
+
import_node_fs8 = require("fs");
|
|
16723
|
+
import_node_path10 = require("path");
|
|
16094
16724
|
init_catalog();
|
|
16095
16725
|
init_write_file_if_changed();
|
|
16096
16726
|
__name(generateFarmI18nTypes, "generateFarmI18nTypes");
|
|
@@ -16245,7 +16875,7 @@ var init_type_artifacts = __esm({
|
|
|
16245
16875
|
var version;
|
|
16246
16876
|
var init_package = __esm({
|
|
16247
16877
|
"package.json"() {
|
|
16248
|
-
version = "0.1.0-beta.
|
|
16878
|
+
version = "0.1.0-beta.13";
|
|
16249
16879
|
}
|
|
16250
16880
|
});
|
|
16251
16881
|
|
|
@@ -16425,12 +17055,12 @@ async function createBlurDataURL(bytes) {
|
|
|
16425
17055
|
return void 0;
|
|
16426
17056
|
}
|
|
16427
17057
|
}
|
|
16428
|
-
var import_promises7,
|
|
17058
|
+
var import_promises7, import_node_path11, import_image_size2, FARM_IMAGE_ID_PREFIX, STATIC_IMAGE_RE, SCRIPT_IMPORTER_RE;
|
|
16429
17059
|
var init_image_vite = __esm({
|
|
16430
17060
|
"src/image-vite.ts"() {
|
|
16431
17061
|
"use strict";
|
|
16432
17062
|
import_promises7 = require("fs/promises");
|
|
16433
|
-
|
|
17063
|
+
import_node_path11 = __toESM(require("path"));
|
|
16434
17064
|
import_image_size2 = require("image-size");
|
|
16435
17065
|
FARM_IMAGE_ID_PREFIX = "\0farm:image:";
|
|
16436
17066
|
STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
|
|
@@ -16441,6 +17071,22 @@ var init_image_vite = __esm({
|
|
|
16441
17071
|
}
|
|
16442
17072
|
});
|
|
16443
17073
|
|
|
17074
|
+
// src/font.ts
|
|
17075
|
+
function resolveFarmLayoutFonts(layouts) {
|
|
17076
|
+
let resolved;
|
|
17077
|
+
for (const layout2 of layouts) {
|
|
17078
|
+
if (!layout2.fonts) continue;
|
|
17079
|
+
resolved = { ...resolved, ...layout2.fonts };
|
|
17080
|
+
}
|
|
17081
|
+
return resolved;
|
|
17082
|
+
}
|
|
17083
|
+
var init_font = __esm({
|
|
17084
|
+
"src/font.ts"() {
|
|
17085
|
+
"use strict";
|
|
17086
|
+
__name(resolveFarmLayoutFonts, "resolveFarmLayoutFonts");
|
|
17087
|
+
}
|
|
17088
|
+
});
|
|
17089
|
+
|
|
16444
17090
|
// src/image-server.ts
|
|
16445
17091
|
function createFarmImageHandler(config, options) {
|
|
16446
17092
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
@@ -16857,6 +17503,106 @@ var init_image_server = __esm({
|
|
|
16857
17503
|
}
|
|
16858
17504
|
});
|
|
16859
17505
|
|
|
17506
|
+
// src/server/vite-config.ts
|
|
17507
|
+
function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
|
|
17508
|
+
const resolvedProjectRoot = import_node_path12.default.resolve(projectRoot);
|
|
17509
|
+
return appDirectories.map((appDirectory) => {
|
|
17510
|
+
const relativeAppDirectory = import_node_path12.default.relative(resolvedProjectRoot, import_node_path12.default.resolve(appDirectory)).replace(/\\/g, "/");
|
|
17511
|
+
const prefix = relativeAppDirectory || ".";
|
|
17512
|
+
return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
|
|
17513
|
+
});
|
|
17514
|
+
}
|
|
17515
|
+
function createFarmClientOptimizeDepsConfig(entries) {
|
|
17516
|
+
return {
|
|
17517
|
+
// Keep normal application dependency discovery for CJS-only packages, but
|
|
17518
|
+
// seed every Farm browser runtime so React is present in the first crawl.
|
|
17519
|
+
noDiscovery: false,
|
|
17520
|
+
// Waiting for the crawl avoids serving a partial optimizer generation and
|
|
17521
|
+
// then changing browser hashes while hydration is already in progress.
|
|
17522
|
+
holdUntilCrawlEnd: true,
|
|
17523
|
+
include: [...FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE],
|
|
17524
|
+
// Farm's HTML boots through a virtual module and imports route UI lazily.
|
|
17525
|
+
// Explicit entries let Vite finish that crawl before a navigation can
|
|
17526
|
+
// rotate the optimizer hash underneath a hydrated React runtime.
|
|
17527
|
+
...entries?.length ? { entries: [...entries] } : {}
|
|
17528
|
+
};
|
|
17529
|
+
}
|
|
17530
|
+
function mergeNoExternal(farmValue, userValue) {
|
|
17531
|
+
if (farmValue === true || userValue === true) return true;
|
|
17532
|
+
const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
|
|
17533
|
+
return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
|
|
17534
|
+
}
|
|
17535
|
+
function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
17536
|
+
const noDiscovery = userConfig.optimizeDeps?.noDiscovery ?? farmConfig.optimizeDeps?.noDiscovery;
|
|
17537
|
+
const holdUntilCrawlEnd = userConfig.optimizeDeps?.holdUntilCrawlEnd ?? (userConfig.optimizeDeps?.noDiscovery === true ? false : farmConfig.optimizeDeps?.holdUntilCrawlEnd);
|
|
17538
|
+
return {
|
|
17539
|
+
...farmConfig,
|
|
17540
|
+
...userConfig,
|
|
17541
|
+
plugins: [...farmConfig.plugins || [], ...userConfig.plugins || []],
|
|
17542
|
+
server: {
|
|
17543
|
+
...farmConfig.server,
|
|
17544
|
+
...userConfig.server
|
|
17545
|
+
},
|
|
17546
|
+
resolve: {
|
|
17547
|
+
...farmConfig.resolve,
|
|
17548
|
+
...userConfig.resolve,
|
|
17549
|
+
dedupe: Array.from(
|
|
17550
|
+
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
17551
|
+
)
|
|
17552
|
+
},
|
|
17553
|
+
optimizeDeps: {
|
|
17554
|
+
...farmConfig.optimizeDeps,
|
|
17555
|
+
...userConfig.optimizeDeps,
|
|
17556
|
+
noDiscovery,
|
|
17557
|
+
holdUntilCrawlEnd,
|
|
17558
|
+
include: Array.from(
|
|
17559
|
+
/* @__PURE__ */ new Set([
|
|
17560
|
+
...farmConfig.optimizeDeps?.include || [],
|
|
17561
|
+
...userConfig.optimizeDeps?.include || []
|
|
17562
|
+
])
|
|
17563
|
+
),
|
|
17564
|
+
exclude: Array.from(
|
|
17565
|
+
/* @__PURE__ */ new Set([
|
|
17566
|
+
...farmConfig.optimizeDeps?.exclude || [],
|
|
17567
|
+
...userConfig.optimizeDeps?.exclude || []
|
|
17568
|
+
])
|
|
17569
|
+
)
|
|
17570
|
+
},
|
|
17571
|
+
ssr: {
|
|
17572
|
+
...farmConfig.ssr,
|
|
17573
|
+
...userConfig.ssr,
|
|
17574
|
+
noExternal: mergeNoExternal(farmConfig.ssr?.noExternal, userConfig.ssr?.noExternal)
|
|
17575
|
+
}
|
|
17576
|
+
};
|
|
17577
|
+
}
|
|
17578
|
+
var import_node_path12, FARM_CLIENT_ENTRY_PATTERN, FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE;
|
|
17579
|
+
var init_vite_config = __esm({
|
|
17580
|
+
"src/server/vite-config.ts"() {
|
|
17581
|
+
"use strict";
|
|
17582
|
+
import_node_path12 = __toESM(require("path"));
|
|
17583
|
+
FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
|
|
17584
|
+
FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
|
|
17585
|
+
"react",
|
|
17586
|
+
"react-dom",
|
|
17587
|
+
"react-dom/client",
|
|
17588
|
+
"react/jsx-runtime",
|
|
17589
|
+
"react/jsx-dev-runtime",
|
|
17590
|
+
"@farm.js/core/client",
|
|
17591
|
+
"@farm.js/core/plugin/client",
|
|
17592
|
+
"@farm.js/core/deferred",
|
|
17593
|
+
"@farm.js/core/deployment",
|
|
17594
|
+
"@farm.js/core/i18n/client",
|
|
17595
|
+
"@farm.js/core/query/client",
|
|
17596
|
+
"@farm.js/core/server-fn/client",
|
|
17597
|
+
"@farm.js/core/server-query/client"
|
|
17598
|
+
];
|
|
17599
|
+
__name(createFarmClientOptimizeDepsEntries, "createFarmClientOptimizeDepsEntries");
|
|
17600
|
+
__name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
|
|
17601
|
+
__name(mergeNoExternal, "mergeNoExternal");
|
|
17602
|
+
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
17603
|
+
}
|
|
17604
|
+
});
|
|
17605
|
+
|
|
16860
17606
|
// src/docs/pixel-border-css.ts
|
|
16861
17607
|
var farmDocsPixelBorderCss;
|
|
16862
17608
|
var init_pixel_border_css = __esm({
|
|
@@ -16902,8 +17648,8 @@ var init_pixel_border_css = __esm({
|
|
|
16902
17648
|
--scrollbar-thumb-hover: var(--color-fd-ring);
|
|
16903
17649
|
--scrollbar-track: transparent;
|
|
16904
17650
|
--radius: 0px;
|
|
16905
|
-
--font-geist-sans:
|
|
16906
|
-
--font-geist-mono:
|
|
17651
|
+
--font-geist-sans: ui-sans-serif, system-ui, sans-serif;
|
|
17652
|
+
--font-geist-mono: ui-monospace, monospace;
|
|
16907
17653
|
}
|
|
16908
17654
|
|
|
16909
17655
|
.dark {
|
|
@@ -16916,28 +17662,6 @@ body,
|
|
|
16916
17662
|
background-color: var(--color-fd-background) !important;
|
|
16917
17663
|
}
|
|
16918
17664
|
|
|
16919
|
-
@font-face {
|
|
16920
|
-
font-family: "Geist Sans";
|
|
16921
|
-
font-display: block;
|
|
16922
|
-
font-style: normal;
|
|
16923
|
-
font-weight: 100 900;
|
|
16924
|
-
src:
|
|
16925
|
-
local("Geist Sans"),
|
|
16926
|
-
url("/assets/Geist-Variable-CrgPqtmy.woff2") format("woff2"),
|
|
16927
|
-
url("/node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2") format("woff2");
|
|
16928
|
-
}
|
|
16929
|
-
|
|
16930
|
-
@font-face {
|
|
16931
|
-
font-family: "Geist Mono";
|
|
16932
|
-
font-display: block;
|
|
16933
|
-
font-style: normal;
|
|
16934
|
-
font-weight: 100 900;
|
|
16935
|
-
src:
|
|
16936
|
-
local("Geist Mono"),
|
|
16937
|
-
url("/assets/GeistMono-Variable-BNLlm6Cd.woff2") format("woff2"),
|
|
16938
|
-
url("/node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2");
|
|
16939
|
-
}
|
|
16940
|
-
|
|
16941
17665
|
* {
|
|
16942
17666
|
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
|
|
16943
17667
|
scrollbar-width: thin;
|
|
@@ -18128,11 +18852,418 @@ code:not(pre code) {
|
|
|
18128
18852
|
}
|
|
18129
18853
|
});
|
|
18130
18854
|
|
|
18855
|
+
// src/docs/social-image.ts
|
|
18856
|
+
function normalizeEntry(entry) {
|
|
18857
|
+
if (!entry || entry === "/") return "";
|
|
18858
|
+
return `/${entry.replace(/^\/+|\/+$/g, "")}`;
|
|
18859
|
+
}
|
|
18860
|
+
function encodeSlugPath(slug) {
|
|
18861
|
+
return slug.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
|
|
18862
|
+
}
|
|
18863
|
+
function getSocialImageConfig(docs) {
|
|
18864
|
+
return typeof docs.config.socialImage === "object" && docs.config.socialImage ? docs.config.socialImage : void 0;
|
|
18865
|
+
}
|
|
18866
|
+
function getNavTitle(docs) {
|
|
18867
|
+
if (typeof docs.config.nav !== "object" || !docs.config.nav || !("title" in docs.config.nav)) {
|
|
18868
|
+
return "Farm.js";
|
|
18869
|
+
}
|
|
18870
|
+
return String(docs.config.nav.title || "Farm.js");
|
|
18871
|
+
}
|
|
18872
|
+
function isFalse(value) {
|
|
18873
|
+
return value ? /^(false|no|none|off|disabled)$/i.test(value.trim()) : false;
|
|
18874
|
+
}
|
|
18875
|
+
function isExternalOrRootPath(value) {
|
|
18876
|
+
return /^(https?:)?\/\//i.test(value) || value.startsWith("/");
|
|
18877
|
+
}
|
|
18878
|
+
function isFarmDocsSocialImageEnabled(page2, docs) {
|
|
18879
|
+
if (docs.config.socialImage === false || getSocialImageConfig(docs)?.enabled === false) {
|
|
18880
|
+
return false;
|
|
18881
|
+
}
|
|
18882
|
+
return !isFalse(page2.frontmatter.socialImage);
|
|
18883
|
+
}
|
|
18884
|
+
function getFarmDocsCustomSocialImage(page2) {
|
|
18885
|
+
const value = page2.frontmatter.socialImage || page2.frontmatter.openGraphImage || page2.frontmatter.ogImage;
|
|
18886
|
+
return value && !isFalse(value) && isExternalOrRootPath(value) ? value : void 0;
|
|
18887
|
+
}
|
|
18888
|
+
function resolveIllustration(page2) {
|
|
18889
|
+
const explicit = page2.frontmatter.socialIllustration?.toLowerCase();
|
|
18890
|
+
if (explicit === "auth" || explicit === "cache" || explicit === "cli" || explicit === "integrations" || explicit === "project" || explicit === "routing" || explicit === "runtime") {
|
|
18891
|
+
return explicit;
|
|
18892
|
+
}
|
|
18893
|
+
const source = `${page2.slug} ${page2.title} ${page2.section || ""}`.toLowerCase();
|
|
18894
|
+
if (/auth|session|security|csrf/.test(source)) return "auth";
|
|
18895
|
+
if (/cache|ppr|render|static|revalid|stream/.test(source)) return "cache";
|
|
18896
|
+
if (/integration|stripe|prisma|better.auth|email|job|workflow/.test(source)) {
|
|
18897
|
+
return "integrations";
|
|
18898
|
+
}
|
|
18899
|
+
if (/cli|test|deploy|preview|upgrade|migration|install/.test(source)) return "cli";
|
|
18900
|
+
if (/project|structure|config|environment|markdown|docs.engine/.test(source)) {
|
|
18901
|
+
return "project";
|
|
18902
|
+
}
|
|
18903
|
+
if (/rout|endpoint|middleware|navigation|server.function|server.action|api/.test(source)) {
|
|
18904
|
+
return "routing";
|
|
18905
|
+
}
|
|
18906
|
+
return "runtime";
|
|
18907
|
+
}
|
|
18908
|
+
function createHashValue(value) {
|
|
18909
|
+
return (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 16);
|
|
18910
|
+
}
|
|
18911
|
+
function resolveBaseUrl(requestUrl, config) {
|
|
18912
|
+
return config?.baseUrl ? new URL(config.baseUrl) : new URL(requestUrl.origin);
|
|
18913
|
+
}
|
|
18914
|
+
function createFarmDocsSocialImageDescriptor(page2, docs, requestUrl) {
|
|
18915
|
+
const config = getSocialImageConfig(docs);
|
|
18916
|
+
const siteName = config?.siteName || getNavTitle(docs);
|
|
18917
|
+
const brand = config?.brand || siteName;
|
|
18918
|
+
const title = page2.frontmatter.socialTitle || page2.title;
|
|
18919
|
+
const description = page2.frontmatter.socialDescription || page2.description || docs.config.metadata?.description || `Documentation for ${siteName}`;
|
|
18920
|
+
const section = page2.frontmatter.section || page2.section || "Documentation";
|
|
18921
|
+
const illustration = resolveIllustration(page2);
|
|
18922
|
+
const entry = normalizeEntry(docs.entry);
|
|
18923
|
+
const slugPath = encodeSlugPath(page2.slug) || "index";
|
|
18924
|
+
const imagePath = `${entry}/_social/${slugPath}/opengraph-image.svg`;
|
|
18925
|
+
const baseUrl = resolveBaseUrl(requestUrl, config);
|
|
18926
|
+
const pageUrl = new URL(page2.href, baseUrl).href;
|
|
18927
|
+
const imageAlt = `${title} \u2014 ${siteName} documentation`;
|
|
18928
|
+
const hash = createHashValue({
|
|
18929
|
+
version: FARM_DOCS_SOCIAL_IMAGE_VERSION,
|
|
18930
|
+
title,
|
|
18931
|
+
description,
|
|
18932
|
+
section,
|
|
18933
|
+
siteName,
|
|
18934
|
+
brand,
|
|
18935
|
+
pageHref: page2.href,
|
|
18936
|
+
illustration,
|
|
18937
|
+
fonts: config?.fonts
|
|
18938
|
+
});
|
|
18939
|
+
return {
|
|
18940
|
+
title,
|
|
18941
|
+
description,
|
|
18942
|
+
section,
|
|
18943
|
+
siteName,
|
|
18944
|
+
brand,
|
|
18945
|
+
pageHref: page2.href,
|
|
18946
|
+
pageUrl,
|
|
18947
|
+
imagePath,
|
|
18948
|
+
imageUrl: new URL(`${imagePath}?v=${hash}`, baseUrl).href,
|
|
18949
|
+
imageAlt,
|
|
18950
|
+
illustration,
|
|
18951
|
+
fonts: config?.fonts,
|
|
18952
|
+
hash
|
|
18953
|
+
};
|
|
18954
|
+
}
|
|
18955
|
+
function getFarmDocsSocialImageSlug(docs, requestUrl) {
|
|
18956
|
+
const entry = normalizeEntry(docs.entry);
|
|
18957
|
+
const prefix = `${entry}/_social/`;
|
|
18958
|
+
const suffix = "/opengraph-image.svg";
|
|
18959
|
+
if (!requestUrl.pathname.startsWith(prefix) || !requestUrl.pathname.endsWith(suffix)) {
|
|
18960
|
+
return null;
|
|
18961
|
+
}
|
|
18962
|
+
const rawSlug = requestUrl.pathname.slice(prefix.length, -suffix.length);
|
|
18963
|
+
if (!rawSlug) return null;
|
|
18964
|
+
try {
|
|
18965
|
+
const slug = rawSlug.split("/").map((segment) => decodeURIComponent(segment)).join("/");
|
|
18966
|
+
if (slug.split("/").some((segment) => !segment || segment === ".." || segment === ".")) {
|
|
18967
|
+
return null;
|
|
18968
|
+
}
|
|
18969
|
+
return slug === "index" ? "" : slug;
|
|
18970
|
+
} catch {
|
|
18971
|
+
return null;
|
|
18972
|
+
}
|
|
18973
|
+
}
|
|
18974
|
+
function escapeXml(value) {
|
|
18975
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
18976
|
+
}
|
|
18977
|
+
function truncate(value, length) {
|
|
18978
|
+
if (value.length <= length) return value;
|
|
18979
|
+
return `${value.slice(0, Math.max(0, length - 1)).trimEnd()}\u2026`;
|
|
18980
|
+
}
|
|
18981
|
+
function wrapText(value, maxCharacters, maxLines) {
|
|
18982
|
+
const words = value.trim().split(/\s+/).filter(Boolean);
|
|
18983
|
+
const lines = [];
|
|
18984
|
+
let current = "";
|
|
18985
|
+
let consumedWords = 0;
|
|
18986
|
+
for (const word of words) {
|
|
18987
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
18988
|
+
if (candidate.length <= maxCharacters || !current) {
|
|
18989
|
+
current = candidate;
|
|
18990
|
+
consumedWords += 1;
|
|
18991
|
+
continue;
|
|
18992
|
+
}
|
|
18993
|
+
lines.push(current);
|
|
18994
|
+
if (lines.length === maxLines) break;
|
|
18995
|
+
current = word;
|
|
18996
|
+
consumedWords += 1;
|
|
18997
|
+
}
|
|
18998
|
+
if (current && lines.length < maxLines) lines.push(current);
|
|
18999
|
+
if (consumedWords < words.length && lines.length) {
|
|
19000
|
+
lines[lines.length - 1] = truncate(`${lines[lines.length - 1]}\u2026`, maxCharacters);
|
|
19001
|
+
}
|
|
19002
|
+
return lines;
|
|
19003
|
+
}
|
|
19004
|
+
function renderTextLines(lines, x, y, lineHeight, attributes) {
|
|
19005
|
+
return lines.map(
|
|
19006
|
+
(line, index) => `<text x="${x}" y="${y + index * lineHeight}" ${attributes}>${escapeXml(line)}</text>`
|
|
19007
|
+
).join("");
|
|
19008
|
+
}
|
|
19009
|
+
function renderEmbeddedFont(name, source, weight) {
|
|
19010
|
+
if (!source) return "";
|
|
19011
|
+
return `@font-face{font-family:"${name}";src:url("${escapeXml(source)}") format("woff2");font-style:normal;font-weight:${weight};font-display:block;}`;
|
|
19012
|
+
}
|
|
19013
|
+
function renderArrow(x1, y, x2, color = "#8b8b8b") {
|
|
19014
|
+
return `<path d="M${x1} ${y}H${x2 - 9}" fill="none" stroke="${color}"/><path d="m${x2 - 9} ${y - 5} 9 5-9 5" fill="none" stroke="${color}"/>`;
|
|
19015
|
+
}
|
|
19016
|
+
function renderPanelHeader(label, status) {
|
|
19017
|
+
return `<text x="819" y="171" class="label">${escapeXml(label)}</text><text x="1134" y="171" class="label bright" text-anchor="end">${escapeXml(status)}</text>`;
|
|
19018
|
+
}
|
|
19019
|
+
function renderRoutingIllustration() {
|
|
19020
|
+
return `${renderPanelHeader("ROUTE BLUEPRINT", "TYPED")}
|
|
19021
|
+
<rect x="819" y="296" width="92" height="54" fill="#a3a3a3"/>
|
|
19022
|
+
<text x="832" y="327" class="diagram-title ink">src/app</text>
|
|
19023
|
+
<path d="M911 323h41M952 232v181M952 232h44M952 323h44M952 413h44" fill="none" stroke="#696969"/>
|
|
19024
|
+
<rect x="996" y="205" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
|
|
19025
|
+
<text x="1010" y="228" class="diagram-title">/</text><text x="1010" y="246" class="micro">STATIC</text>
|
|
19026
|
+
<rect x="996" y="296" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
|
|
19027
|
+
<text x="1010" y="319" class="diagram-title">/blog/:slug</text><text x="1010" y="337" class="micro">DYNAMIC</text>
|
|
19028
|
+
<rect x="996" y="386" width="138" height="55" fill="#f0f0f0"/>
|
|
19029
|
+
<text x="1010" y="410" class="diagram-title ink">/docs/:path*</text><text x="1010" y="428" class="micro ink-muted">CATCH-ALL</text>
|
|
19030
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19031
|
+
<text x="819" y="475" class="label bright">FILE ROUTES</text><text x="1134" y="475" class="label" text-anchor="end">TYPES INCLUDED</text>`;
|
|
19032
|
+
}
|
|
19033
|
+
function renderAuthIllustration() {
|
|
19034
|
+
return `${renderPanelHeader("REQUEST GUARD", "SERVER VERIFIED")}
|
|
19035
|
+
<rect x="819" y="269" width="86" height="54" fill="#0a0a0a" stroke="#454545"/>
|
|
19036
|
+
<text x="837" y="292" class="micro bright">REQUEST</text><text x="837" y="310" class="diagram-title">GET /app</text>
|
|
19037
|
+
${renderArrow(905, 296, 943)}
|
|
19038
|
+
<rect x="943" y="224" width="104" height="118" fill="#f0f0f0"/>
|
|
19039
|
+
<path d="M974 271v-12a21 21 0 0 1 42 0v12M968 271h54v45h-54z" fill="#050505"/>
|
|
19040
|
+
<circle cx="995" cy="292" r="4" fill="#f0f0f0"/><path d="M995 296v8" stroke="#f0f0f0" stroke-width="3"/>
|
|
19041
|
+
<text x="995" y="332" class="micro ink" text-anchor="middle">auth()</text>
|
|
19042
|
+
${renderArrow(1047, 296, 1071)}
|
|
19043
|
+
<rect x="1071" y="269" width="63" height="54" fill="#0a0a0a" stroke="#454545"/>
|
|
19044
|
+
<text x="1082" y="292" class="micro bright">ALLOW</text><text x="1082" y="310" class="micro">/app</text>
|
|
19045
|
+
<rect x="819" y="372" width="315" height="38" fill="#090909" stroke="#3d3d3d"/>
|
|
19046
|
+
<rect x="832" y="385" width="11" height="11" fill="#a3a3a3"/>
|
|
19047
|
+
<text x="856" y="395" class="code">session.user / verified</text>
|
|
19048
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19049
|
+
<text x="819" y="475" class="label bright">SESSION TYPED</text><text x="1134" y="475" class="label" text-anchor="end">CSRF PROTECTED</text>`;
|
|
19050
|
+
}
|
|
19051
|
+
function renderCacheIllustration() {
|
|
19052
|
+
return `${renderPanelHeader("PAGE / PRODUCT", "CACHE + PPR")}
|
|
19053
|
+
<rect x="819" y="204" width="315" height="54" fill="#f0f0f0"/>
|
|
19054
|
+
<text x="836" y="235" class="diagram-title ink">STATIC SHELL</text><text x="1116" y="235" class="micro ink-muted" text-anchor="end">BUILD</text>
|
|
19055
|
+
<rect x="819" y="271" width="198" height="76" fill="#a3a3a3"/>
|
|
19056
|
+
<text x="836" y="301" class="diagram-title ink">CACHED DATA</text><text x="836" y="326" class="micro ink-muted">tag: products</text>
|
|
19057
|
+
<rect x="1029" y="271" width="105" height="76" fill="#0a0a0a" stroke="#555"/>
|
|
19058
|
+
<text x="1045" y="301" class="diagram-title">LIVE</text><text x="1045" y="326" class="micro">stream</text>
|
|
19059
|
+
<path d="M1081 347v43m-8-9 8 9 8-9" fill="none" stroke="#d4d4d4"/>
|
|
19060
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19061
|
+
<text x="819" y="475" class="label bright">STATIC FIRST</text><text x="1134" y="475" class="label" text-anchor="end">DYNAMIC WHERE NEEDED</text>`;
|
|
19062
|
+
}
|
|
19063
|
+
function renderIntegrationsIllustration() {
|
|
19064
|
+
return `${renderPanelHeader("INTEGRATION GRAPH", "ONE PRODUCT")}
|
|
19065
|
+
<path d="M976 309H879V247M976 309H879v87M1030 309h93V247M1030 309h93v87" fill="none" stroke="#4a4a4a"/>
|
|
19066
|
+
<rect x="819" y="214" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="839" y="247" class="diagram-title">BETTER AUTH</text>
|
|
19067
|
+
<rect x="819" y="368" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="851" y="401" class="diagram-title">PRISMA</text>
|
|
19068
|
+
<rect x="1061" y="214" width="73" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="1077" y="247" class="diagram-title">STRIPE</text>
|
|
19069
|
+
<rect x="1061" y="368" width="73" height="57" fill="#a3a3a3"/><text x="1075" y="401" class="diagram-title ink">VERCEL</text>
|
|
19070
|
+
<rect x="976" y="277" width="94" height="64" fill="#f0f0f0"/>
|
|
19071
|
+
<text x="994" y="304" class="diagram-title ink">FARM.JS</text><text x="994" y="324" class="micro ink-muted">CORE</text>
|
|
19072
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19073
|
+
<text x="819" y="475" class="label bright">BRING YOUR STACK</text><text x="1134" y="475" class="label" text-anchor="end">CONNECTED ONCE</text>`;
|
|
19074
|
+
}
|
|
19075
|
+
function renderCliIllustration() {
|
|
19076
|
+
return `${renderPanelHeader("TERMINAL", "PRODUCTION OUTPUT")}
|
|
19077
|
+
<rect x="819" y="203" width="315" height="213" fill="#050505" stroke="#555"/>
|
|
19078
|
+
<line x1="819" y1="236" x2="1134" y2="236" stroke="#555"/>
|
|
19079
|
+
<circle cx="837" cy="220" r="4" fill="#5d5d5d"/><circle cx="850" cy="220" r="4" fill="#7a7a7a"/><circle cx="863" cy="220" r="4" fill="#a3a3a3"/>
|
|
19080
|
+
<text x="837" y="273" class="code bright"><tspan fill="#7a7a7a">$</tspan> farm build</text>
|
|
19081
|
+
<rect x="837" y="293" width="11" height="11" fill="#a3a3a3"/><path d="m839 298 3 3 6-7" fill="none" stroke="#050505" stroke-width="1.5"/>
|
|
19082
|
+
<text x="861" y="303" class="code">64 routes discovered</text>
|
|
19083
|
+
<rect x="837" y="320" width="11" height="11" fill="#a3a3a3"/><path d="m839 325 3 3 6-7" fill="none" stroke="#050505" stroke-width="1.5"/>
|
|
19084
|
+
<text x="861" y="330" class="code">client + server bundles</text>
|
|
19085
|
+
<rect x="837" y="355" width="126" height="30" fill="#f0f0f0"/><text x="853" y="374" class="micro ink">BUILD COMPLETE</text>
|
|
19086
|
+
<text x="1115" y="374" class="micro" text-anchor="end">/dist</text>
|
|
19087
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19088
|
+
<text x="819" y="475" class="label bright">REAL COMMANDS</text><text x="1134" y="475" class="label" text-anchor="end">842MS</text>`;
|
|
19089
|
+
}
|
|
19090
|
+
function renderProjectIllustration() {
|
|
19091
|
+
return `${renderPanelHeader("PROJECT MAP", "CONVENTION TYPED")}
|
|
19092
|
+
<rect x="819" y="202" width="315" height="216" fill="#050505" stroke="#555"/>
|
|
19093
|
+
<text x="837" y="227" class="diagram-title bright">my-app/</text>
|
|
19094
|
+
<path d="M847 243v143M847 259h23M847 293h23M847 327h23M847 361h23" fill="none" stroke="#666"/>
|
|
19095
|
+
<rect x="870" y="243" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="264" class="code">src/app</text><text x="1098" y="264" class="micro" text-anchor="end">ROUTES</text>
|
|
19096
|
+
<rect x="870" y="277" width="246" height="33" fill="#f0f0f0"/><text x="886" y="298" class="code ink">src/app/page.tsx</text>
|
|
19097
|
+
<rect x="870" y="311" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="332" class="code">src/app/api/users/route.ts</text><text x="1098" y="332" class="micro" text-anchor="end">API</text>
|
|
19098
|
+
<rect x="870" y="345" width="246" height="33" fill="#0a0a0a" stroke="#444"/><text x="886" y="366" class="code">farm.config.ts</text><text x="1098" y="366" class="micro" text-anchor="end">CONFIG</text>
|
|
19099
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19100
|
+
<text x="819" y="475" class="label bright">FILES BECOME FEATURES</text><text x="1134" y="475" class="label" text-anchor="end">ONE CONFIG</text>`;
|
|
19101
|
+
}
|
|
19102
|
+
function renderRuntimeIllustration() {
|
|
19103
|
+
return `${renderPanelHeader("PRODUCT ARCHITECTURE", "FULL STACK")}
|
|
19104
|
+
<rect x="819" y="211" width="315" height="55" fill="#f0f0f0"/>
|
|
19105
|
+
<text x="836" y="244" class="diagram-title ink">PRODUCT SURFACE</text><text x="1116" y="244" class="micro ink-muted" text-anchor="end">UI + ROUTES</text>
|
|
19106
|
+
<path d="M976 266v20m0 61v20" stroke="#727272"/>
|
|
19107
|
+
<rect x="855" y="286" width="242" height="61" fill="#a3a3a3"/>
|
|
19108
|
+
<text x="874" y="314" class="diagram-title ink">APPLICATION CORE</text><text x="874" y="334" class="micro ink-muted">APIS \xB7 MIDDLEWARE</text>
|
|
19109
|
+
<rect x="819" y="367" width="315" height="55" fill="#4c4c4c"/>
|
|
19110
|
+
<text x="836" y="400" class="diagram-title bright">CONNECTED STACK</text><text x="1116" y="400" class="micro" text-anchor="end">DATA \xB7 AUTH \xB7 DEPLOY</text>
|
|
19111
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19112
|
+
<text x="819" y="475" class="label bright">ONE FRAMEWORK</text><text x="1134" y="475" class="label" text-anchor="end">ONE DEPLOYMENT MODEL</text>`;
|
|
19113
|
+
}
|
|
19114
|
+
function renderIllustration(type) {
|
|
19115
|
+
switch (type) {
|
|
19116
|
+
case "auth":
|
|
19117
|
+
return renderAuthIllustration();
|
|
19118
|
+
case "cache":
|
|
19119
|
+
return renderCacheIllustration();
|
|
19120
|
+
case "cli":
|
|
19121
|
+
return renderCliIllustration();
|
|
19122
|
+
case "integrations":
|
|
19123
|
+
return renderIntegrationsIllustration();
|
|
19124
|
+
case "project":
|
|
19125
|
+
return renderProjectIllustration();
|
|
19126
|
+
case "routing":
|
|
19127
|
+
return renderRoutingIllustration();
|
|
19128
|
+
default:
|
|
19129
|
+
return renderRuntimeIllustration();
|
|
19130
|
+
}
|
|
19131
|
+
}
|
|
19132
|
+
function renderFarmDocsSocialImageSvg(descriptor) {
|
|
19133
|
+
const titleLines = wrapText(descriptor.title, 22, 2);
|
|
19134
|
+
const longestTitleLine = Math.max(...titleLines.map((line) => line.length));
|
|
19135
|
+
const titleSize = titleLines.length === 1 ? longestTitleLine > 17 ? 62 : 74 : 56;
|
|
19136
|
+
const titleLineHeight = Math.round(titleSize * 0.98);
|
|
19137
|
+
const titleY = titleLines.length === 1 ? 294 : 266;
|
|
19138
|
+
const descriptionY = titleY + (titleLines.length - 1) * titleLineHeight + 59;
|
|
19139
|
+
const descriptionLines = wrapText(descriptor.description, 68, 2);
|
|
19140
|
+
const routeY = Math.max(418, descriptionY + descriptionLines.length * 29 + 24);
|
|
19141
|
+
const section = truncate(descriptor.section.toUpperCase(), 27);
|
|
19142
|
+
const route = truncate(descriptor.pageHref, 42);
|
|
19143
|
+
const footerUrl = truncate(descriptor.pageUrl.replace(/^https?:\/\//, ""), 70);
|
|
19144
|
+
const brand = truncate(descriptor.brand.toUpperCase(), 25);
|
|
19145
|
+
const titleId = `farm-docs-og-${descriptor.hash}`;
|
|
19146
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
19147
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${FARM_DOCS_SOCIAL_IMAGE_WIDTH}" height="${FARM_DOCS_SOCIAL_IMAGE_HEIGHT}" viewBox="0 0 ${FARM_DOCS_SOCIAL_IMAGE_WIDTH} ${FARM_DOCS_SOCIAL_IMAGE_HEIGHT}" role="img" aria-labelledby="${titleId}-title ${titleId}-description">
|
|
19148
|
+
<title id="${titleId}-title">${escapeXml(descriptor.imageAlt)}</title>
|
|
19149
|
+
<desc id="${titleId}-description">${escapeXml(descriptor.description)}</desc>
|
|
19150
|
+
<metadata>${escapeXml(JSON.stringify({ generator: "Farm.js docs", page: descriptor.pageUrl, illustration: descriptor.illustration }))}</metadata>
|
|
19151
|
+
<style type="text/css">
|
|
19152
|
+
${renderEmbeddedFont("Farm Sans", descriptor.fonts?.sans, "100 900")}
|
|
19153
|
+
${renderEmbeddedFont("Farm Mono", descriptor.fonts?.mono, "100 900")}
|
|
19154
|
+
${renderEmbeddedFont("Farm Pixel", descriptor.fonts?.display, "400 700")}
|
|
19155
|
+
.sans{font-family:"Farm Sans","Arial",sans-serif}.mono,.label,.code,.diagram-title,.micro{font-family:"Farm Mono","Menlo","DejaVu Sans Mono",monospace}.pixel{font-family:"Farm Pixel","Farm Mono",monospace}.label{fill:#8b8b8b;font-size:10px;font-weight:600;letter-spacing:1.2px}.code{fill:#8b8b8b;font-size:11px}.diagram-title{fill:#e7e7e7;font-size:11px;font-weight:650}.micro{fill:#777;font-size:8px;letter-spacing:.45px}.bright{fill:#f5f5f4}.ink{fill:#050505}.ink-muted{fill:#4c4c4c}
|
|
19156
|
+
</style>
|
|
19157
|
+
<defs>
|
|
19158
|
+
<pattern id="canvas-grid" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0H0V40" fill="none" stroke="#151515"/></pattern>
|
|
19159
|
+
<pattern id="diagonal" width="12" height="12" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="12" stroke="#171717" stroke-width="2"/></pattern>
|
|
19160
|
+
<clipPath id="frame-clip"><rect x="28" y="28" width="1144" height="574"/></clipPath>
|
|
19161
|
+
</defs>
|
|
19162
|
+
<rect width="1200" height="630" fill="#050505"/>
|
|
19163
|
+
<rect width="1200" height="630" fill="url(#canvas-grid)"/>
|
|
19164
|
+
<g clip-path="url(#frame-clip)">
|
|
19165
|
+
<rect x="28" y="28" width="1144" height="574" fill="#020202"/>
|
|
19166
|
+
<rect x="782" y="114" width="390" height="411" fill="url(#diagonal)"/>
|
|
19167
|
+
</g>
|
|
19168
|
+
<rect x="28.5" y="28.5" width="1143" height="573" fill="none" stroke="#323232"/>
|
|
19169
|
+
<path d="M28 114.5h1144M28 525.5h1144M781.5 114v411" fill="none" stroke="#303030"/>
|
|
19170
|
+
|
|
19171
|
+
<g transform="translate(71 51)">
|
|
19172
|
+
<rect width="11" height="11" rx="1" fill="#f5f5f4"/><rect x="15" width="28" height="11" rx="1" fill="#f5f5f4"/>
|
|
19173
|
+
<rect y="15" width="11" height="11" rx="1" fill="#9b9b9b"/><rect x="15" y="15" width="28" height="11" rx="1" fill="#9b9b9b"/>
|
|
19174
|
+
<rect y="30" width="11" height="11" rx="1" fill="#5f5f5f"/><rect x="15" y="30" width="20" height="11" rx="1" fill="#5f5f5f"/>
|
|
19175
|
+
<text x="61" y="24" class="mono bright" font-size="24" font-weight="550">FARM<tspan fill="#777">.JS</tspan></text>
|
|
19176
|
+
<text x="61" y="43" class="label">BY FARMING LABS</text>
|
|
19177
|
+
</g>
|
|
19178
|
+
<text x="1134" y="72" class="label" text-anchor="end">${escapeXml(brand)} \xB7 DOCUMENTATION</text>
|
|
19179
|
+
|
|
19180
|
+
<text x="71" y="198" class="mono bright" font-size="13" font-weight="650">DOCS</text>
|
|
19181
|
+
<line x1="117" y1="193" x2="155" y2="193" stroke="#696969"/>
|
|
19182
|
+
<text x="166" y="198" class="mono" fill="#9b9b9b" font-size="13">${escapeXml(section)}</text>
|
|
19183
|
+
${renderTextLines(titleLines, 71, titleY, titleLineHeight, `class="pixel bright" font-size="${titleSize}" font-weight="500" letter-spacing="-2.4"`)}
|
|
19184
|
+
${renderTextLines(descriptionLines, 71, descriptionY, 29, 'class="sans" fill="#a3a3a3" font-size="20" font-weight="430" letter-spacing="-.3"')}
|
|
19185
|
+
<rect x="71" y="${routeY}" width="${Math.min(390, 56 + route.length * 8)}" height="36" fill="#050505" stroke="#3c3c3c"/>
|
|
19186
|
+
<text x="85" y="${routeY + 23}" class="mono bright" font-size="11" font-weight="600">GET</text>
|
|
19187
|
+
<text x="119" y="${routeY + 23}" class="mono" fill="#898989" font-size="11">${escapeXml(route)}</text>
|
|
19188
|
+
|
|
19189
|
+
${renderIllustration(descriptor.illustration)}
|
|
19190
|
+
|
|
19191
|
+
<text x="71" y="570" class="mono bright" font-size="13" font-weight="550">${escapeXml(footerUrl)}</text>
|
|
19192
|
+
<text x="1134" y="570" class="mono" fill="#9b9b9b" font-size="12" text-anchor="end">FARM.JS DOCUMENTATION</text>
|
|
19193
|
+
<path d="M20 20h10M20 20v10M1180 20h-10M1180 20v10M20 610h10M20 610v-10M1180 610h-10M1180 610v-10" fill="none" stroke="#9b9b9b"/>
|
|
19194
|
+
</svg>`;
|
|
19195
|
+
}
|
|
19196
|
+
function renderFarmDocsSocialMetadata(descriptor, customImage) {
|
|
19197
|
+
const imageUrl = customImage ? new URL(customImage, descriptor.pageUrl).href : descriptor.imageUrl;
|
|
19198
|
+
const customExtension = customImage?.toLowerCase().split(/[?#]/, 1)[0];
|
|
19199
|
+
const imageType = customExtension?.endsWith(".webp") ? "image/webp" : customExtension?.endsWith(".png") ? "image/png" : customExtension?.match(/\.jpe?g$/) ? "image/jpeg" : "image/svg+xml";
|
|
19200
|
+
const tag = /* @__PURE__ */ __name((property, content, name = false) => `<meta ${name ? "name" : "property"}="${property}" content="${escapeXml(content)}">`, "tag");
|
|
19201
|
+
return [
|
|
19202
|
+
tag("og:type", "article"),
|
|
19203
|
+
tag("og:site_name", descriptor.siteName),
|
|
19204
|
+
tag("og:title", descriptor.title),
|
|
19205
|
+
tag("og:description", descriptor.description),
|
|
19206
|
+
tag("og:url", descriptor.pageUrl),
|
|
19207
|
+
tag("og:image", imageUrl),
|
|
19208
|
+
tag("og:image:type", imageType),
|
|
19209
|
+
...customImage ? [] : [
|
|
19210
|
+
tag("og:image:width", String(FARM_DOCS_SOCIAL_IMAGE_WIDTH)),
|
|
19211
|
+
tag("og:image:height", String(FARM_DOCS_SOCIAL_IMAGE_HEIGHT))
|
|
19212
|
+
],
|
|
19213
|
+
tag("og:image:alt", descriptor.imageAlt),
|
|
19214
|
+
tag("twitter:card", "summary_large_image", true),
|
|
19215
|
+
tag("twitter:title", descriptor.title, true),
|
|
19216
|
+
tag("twitter:description", descriptor.description, true),
|
|
19217
|
+
tag("twitter:image", imageUrl, true),
|
|
19218
|
+
tag("twitter:image:alt", descriptor.imageAlt, true)
|
|
19219
|
+
].join("\n ");
|
|
19220
|
+
}
|
|
19221
|
+
var import_node_crypto4, FARM_DOCS_SOCIAL_IMAGE_WIDTH, FARM_DOCS_SOCIAL_IMAGE_HEIGHT, FARM_DOCS_SOCIAL_IMAGE_VERSION;
|
|
19222
|
+
var init_social_image = __esm({
|
|
19223
|
+
"src/docs/social-image.ts"() {
|
|
19224
|
+
"use strict";
|
|
19225
|
+
import_node_crypto4 = require("crypto");
|
|
19226
|
+
FARM_DOCS_SOCIAL_IMAGE_WIDTH = 1200;
|
|
19227
|
+
FARM_DOCS_SOCIAL_IMAGE_HEIGHT = 630;
|
|
19228
|
+
FARM_DOCS_SOCIAL_IMAGE_VERSION = 3;
|
|
19229
|
+
__name(normalizeEntry, "normalizeEntry");
|
|
19230
|
+
__name(encodeSlugPath, "encodeSlugPath");
|
|
19231
|
+
__name(getSocialImageConfig, "getSocialImageConfig");
|
|
19232
|
+
__name(getNavTitle, "getNavTitle");
|
|
19233
|
+
__name(isFalse, "isFalse");
|
|
19234
|
+
__name(isExternalOrRootPath, "isExternalOrRootPath");
|
|
19235
|
+
__name(isFarmDocsSocialImageEnabled, "isFarmDocsSocialImageEnabled");
|
|
19236
|
+
__name(getFarmDocsCustomSocialImage, "getFarmDocsCustomSocialImage");
|
|
19237
|
+
__name(resolveIllustration, "resolveIllustration");
|
|
19238
|
+
__name(createHashValue, "createHashValue");
|
|
19239
|
+
__name(resolveBaseUrl, "resolveBaseUrl");
|
|
19240
|
+
__name(createFarmDocsSocialImageDescriptor, "createFarmDocsSocialImageDescriptor");
|
|
19241
|
+
__name(getFarmDocsSocialImageSlug, "getFarmDocsSocialImageSlug");
|
|
19242
|
+
__name(escapeXml, "escapeXml");
|
|
19243
|
+
__name(truncate, "truncate");
|
|
19244
|
+
__name(wrapText, "wrapText");
|
|
19245
|
+
__name(renderTextLines, "renderTextLines");
|
|
19246
|
+
__name(renderEmbeddedFont, "renderEmbeddedFont");
|
|
19247
|
+
__name(renderArrow, "renderArrow");
|
|
19248
|
+
__name(renderPanelHeader, "renderPanelHeader");
|
|
19249
|
+
__name(renderRoutingIllustration, "renderRoutingIllustration");
|
|
19250
|
+
__name(renderAuthIllustration, "renderAuthIllustration");
|
|
19251
|
+
__name(renderCacheIllustration, "renderCacheIllustration");
|
|
19252
|
+
__name(renderIntegrationsIllustration, "renderIntegrationsIllustration");
|
|
19253
|
+
__name(renderCliIllustration, "renderCliIllustration");
|
|
19254
|
+
__name(renderProjectIllustration, "renderProjectIllustration");
|
|
19255
|
+
__name(renderRuntimeIllustration, "renderRuntimeIllustration");
|
|
19256
|
+
__name(renderIllustration, "renderIllustration");
|
|
19257
|
+
__name(renderFarmDocsSocialImageSvg, "renderFarmDocsSocialImageSvg");
|
|
19258
|
+
__name(renderFarmDocsSocialMetadata, "renderFarmDocsSocialMetadata");
|
|
19259
|
+
}
|
|
19260
|
+
});
|
|
19261
|
+
|
|
18131
19262
|
// src/docs/handler.ts
|
|
18132
19263
|
function trimSlashes2(value) {
|
|
18133
19264
|
return value.replace(/^\/+|\/+$/g, "");
|
|
18134
19265
|
}
|
|
18135
|
-
function
|
|
19266
|
+
function normalizeEntry2(entry) {
|
|
18136
19267
|
if (!entry || entry === "/") return "/";
|
|
18137
19268
|
return `/${trimSlashes2(entry)}`;
|
|
18138
19269
|
}
|
|
@@ -18144,10 +19275,10 @@ function resolveFarmDocsFavicon(docs, options) {
|
|
|
18144
19275
|
if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
|
|
18145
19276
|
return configuredFavicon.trim();
|
|
18146
19277
|
}
|
|
18147
|
-
const publicDir =
|
|
19278
|
+
const publicDir = import_node_path13.default.join(import_node_path13.default.resolve(options.root), "public");
|
|
18148
19279
|
for (const fileName of FARM_DOCS_FAVICON_FILES) {
|
|
18149
|
-
const faviconPath =
|
|
18150
|
-
if ((0,
|
|
19280
|
+
const faviconPath = import_node_path13.default.join(publicDir, fileName);
|
|
19281
|
+
if ((0, import_node_fs9.existsSync)(faviconPath) && (0, import_node_fs9.statSync)(faviconPath).isFile()) {
|
|
18151
19282
|
return `/${fileName}`;
|
|
18152
19283
|
}
|
|
18153
19284
|
}
|
|
@@ -18181,10 +19312,10 @@ function isSafeSegment(segment) {
|
|
|
18181
19312
|
return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
|
|
18182
19313
|
}
|
|
18183
19314
|
function resolveInside(root, target) {
|
|
18184
|
-
const resolvedRoot =
|
|
18185
|
-
const resolvedTarget =
|
|
18186
|
-
const relative4 =
|
|
18187
|
-
if (relative4 === "" || !relative4.startsWith("..") && !
|
|
19315
|
+
const resolvedRoot = import_node_path13.default.resolve(root);
|
|
19316
|
+
const resolvedTarget = import_node_path13.default.resolve(target);
|
|
19317
|
+
const relative4 = import_node_path13.default.relative(resolvedRoot, resolvedTarget);
|
|
19318
|
+
if (relative4 === "" || !relative4.startsWith("..") && !import_node_path13.default.isAbsolute(relative4)) {
|
|
18188
19319
|
return resolvedTarget;
|
|
18189
19320
|
}
|
|
18190
19321
|
return null;
|
|
@@ -18193,36 +19324,36 @@ function isFarmDocsRequest(docs, request) {
|
|
|
18193
19324
|
if (!docs?.enabled) return false;
|
|
18194
19325
|
if (request.method !== "GET" && request.method !== "HEAD") return false;
|
|
18195
19326
|
const pathname = new URL(request.url).pathname;
|
|
18196
|
-
const entry =
|
|
19327
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18197
19328
|
if (entry === "/") return true;
|
|
18198
19329
|
return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
|
|
18199
19330
|
}
|
|
18200
19331
|
function resolveFarmDocsContentDir(docs, options) {
|
|
18201
|
-
const root =
|
|
19332
|
+
const root = import_node_path13.default.resolve(options.root);
|
|
18202
19333
|
const srcDir = options.srcDir || "src";
|
|
18203
19334
|
const configuredContentDir = docs.contentDir || docs.config.contentDir;
|
|
18204
19335
|
if (configuredContentDir) {
|
|
18205
|
-
return
|
|
19336
|
+
return import_node_path13.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path13.default.join(root, configuredContentDir);
|
|
18206
19337
|
}
|
|
18207
19338
|
const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
|
|
18208
|
-
const appDocsDir =
|
|
18209
|
-
if ((0,
|
|
18210
|
-
return
|
|
19339
|
+
const appDocsDir = import_node_path13.default.join(root, srcDir, "app", entryDir);
|
|
19340
|
+
if ((0, import_node_fs9.existsSync)(appDocsDir)) return appDocsDir;
|
|
19341
|
+
return import_node_path13.default.join(root, entryDir);
|
|
18211
19342
|
}
|
|
18212
19343
|
function getFarmDocsRouteTypeEntries(docs) {
|
|
18213
19344
|
if (!docs?.enabled) return [];
|
|
18214
|
-
const entry =
|
|
19345
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18215
19346
|
if (entry === "/") return ["/", "/[...docs]"];
|
|
18216
19347
|
return [entry, `${entry}/[...docs]`];
|
|
18217
19348
|
}
|
|
18218
19349
|
function getFarmDocsDocumentNavigationMatchers(docs) {
|
|
18219
19350
|
if (!docs?.enabled) return [];
|
|
18220
|
-
const entry =
|
|
19351
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18221
19352
|
return [entry === "/" ? "/(.*)" : `${entry}(.*)`];
|
|
18222
19353
|
}
|
|
18223
19354
|
function getRequestSlug(docs, request) {
|
|
18224
19355
|
const pathname = new URL(request.url).pathname;
|
|
18225
|
-
const entry =
|
|
19356
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18226
19357
|
if (entry === "/") return normalizeSlug(pathname);
|
|
18227
19358
|
if (pathname === entry || pathname === `${entry}.md`) return "";
|
|
18228
19359
|
return normalizeSlug(pathname.slice(entry.length));
|
|
@@ -18230,14 +19361,14 @@ function getRequestSlug(docs, request) {
|
|
|
18230
19361
|
function findDocsPageFile(contentDir, slug) {
|
|
18231
19362
|
const segments = slug ? slug.split("/").filter(Boolean) : [];
|
|
18232
19363
|
if (!segments.every(isSafeSegment)) return null;
|
|
18233
|
-
const slugDir =
|
|
18234
|
-
const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) =>
|
|
18235
|
-
...DOCS_FILE_NAMES.map((filename) =>
|
|
18236
|
-
...DOCS_FILE_EXTENSIONS2.map((extension) =>
|
|
19364
|
+
const slugDir = import_node_path13.default.join(contentDir, ...segments);
|
|
19365
|
+
const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path13.default.join(contentDir, filename)) : [
|
|
19366
|
+
...DOCS_FILE_NAMES.map((filename) => import_node_path13.default.join(slugDir, filename)),
|
|
19367
|
+
...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path13.default.join(contentDir, `${slug}${extension}`))
|
|
18237
19368
|
];
|
|
18238
19369
|
for (const candidate of candidates) {
|
|
18239
19370
|
const safePath = resolveInside(contentDir, candidate);
|
|
18240
|
-
if (safePath && (0,
|
|
19371
|
+
if (safePath && (0, import_node_fs9.existsSync)(safePath) && (0, import_node_fs9.statSync)(safePath).isFile()) {
|
|
18241
19372
|
return safePath;
|
|
18242
19373
|
}
|
|
18243
19374
|
}
|
|
@@ -18272,7 +19403,7 @@ function titleFromMarkdown2(body, fallback) {
|
|
|
18272
19403
|
function loadFarmDocsPage(contentDir, docs, slug) {
|
|
18273
19404
|
const sourcePath = findDocsPageFile(contentDir, slug);
|
|
18274
19405
|
if (!sourcePath) return null;
|
|
18275
|
-
const source = (0,
|
|
19406
|
+
const source = (0, import_node_fs9.readFileSync)(sourcePath, "utf8");
|
|
18276
19407
|
const { frontmatter, body } = parseFrontmatter(source);
|
|
18277
19408
|
const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
|
|
18278
19409
|
const href = createDocsHref(docs.entry, slug);
|
|
@@ -18280,6 +19411,7 @@ function loadFarmDocsPage(contentDir, docs, slug) {
|
|
|
18280
19411
|
slug,
|
|
18281
19412
|
title,
|
|
18282
19413
|
description: frontmatter.description,
|
|
19414
|
+
section: frontmatter.section,
|
|
18283
19415
|
href,
|
|
18284
19416
|
sourcePath,
|
|
18285
19417
|
lastModified: resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter),
|
|
@@ -18288,15 +19420,15 @@ function loadFarmDocsPage(contentDir, docs, slug) {
|
|
|
18288
19420
|
};
|
|
18289
19421
|
}
|
|
18290
19422
|
function createDocsHref(entry, slug) {
|
|
18291
|
-
const normalizedEntry =
|
|
19423
|
+
const normalizedEntry = normalizeEntry2(entry);
|
|
18292
19424
|
const normalizedSlug = trimSlashes2(slug);
|
|
18293
19425
|
if (normalizedEntry === "/") return normalizedSlug ? `/${normalizedSlug}` : "/";
|
|
18294
19426
|
return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
|
|
18295
19427
|
}
|
|
18296
19428
|
function pathToSlug(contentDir, filePath) {
|
|
18297
|
-
const relative4 =
|
|
19429
|
+
const relative4 = import_node_path13.default.relative(contentDir, filePath).replace(/\\/g, "/");
|
|
18298
19430
|
if (relative4.startsWith("..")) return null;
|
|
18299
|
-
const extension =
|
|
19431
|
+
const extension = import_node_path13.default.extname(relative4);
|
|
18300
19432
|
if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
|
|
18301
19433
|
const withoutExtension = relative4.slice(0, -extension.length);
|
|
18302
19434
|
if (withoutExtension === "page" || withoutExtension === "index") return "";
|
|
@@ -18309,12 +19441,12 @@ function loadPage(contentDir, docs, request) {
|
|
|
18309
19441
|
return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
|
|
18310
19442
|
}
|
|
18311
19443
|
function discoverFarmDocsPages(contentDir, docs) {
|
|
18312
|
-
if (!(0,
|
|
19444
|
+
if (!(0, import_node_fs9.existsSync)(contentDir)) return [];
|
|
18313
19445
|
const pages = [];
|
|
18314
19446
|
const visit = /* @__PURE__ */ __name((dir) => {
|
|
18315
|
-
for (const entry of (0,
|
|
19447
|
+
for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true })) {
|
|
18316
19448
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
18317
|
-
const absolutePath =
|
|
19449
|
+
const absolutePath = import_node_path13.default.join(dir, entry.name);
|
|
18318
19450
|
if (entry.isDirectory()) {
|
|
18319
19451
|
visit(absolutePath);
|
|
18320
19452
|
continue;
|
|
@@ -18322,7 +19454,7 @@ function discoverFarmDocsPages(contentDir, docs) {
|
|
|
18322
19454
|
if (!entry.isFile()) continue;
|
|
18323
19455
|
const slug = pathToSlug(contentDir, absolutePath);
|
|
18324
19456
|
if (slug === null) continue;
|
|
18325
|
-
const source = (0,
|
|
19457
|
+
const source = (0, import_node_fs9.readFileSync)(absolutePath, "utf8");
|
|
18326
19458
|
const { frontmatter, body } = parseFrontmatter(source);
|
|
18327
19459
|
pages.push({
|
|
18328
19460
|
slug,
|
|
@@ -19100,7 +20232,7 @@ function renderPixelBreadcrumb(page2, docs) {
|
|
|
19100
20232
|
const parentSegments = segments.slice(0, -1);
|
|
19101
20233
|
const parentSegment = parentSegments[parentSegments.length - 1];
|
|
19102
20234
|
const currentSegment = segments[segments.length - 1];
|
|
19103
|
-
const entry =
|
|
20235
|
+
const entry = normalizeEntry2(docs.entry);
|
|
19104
20236
|
const parentPath = parentSegments.join("/");
|
|
19105
20237
|
const parentHref = entry === "/" ? `/${parentPath}` : `${entry}/${parentPath}`;
|
|
19106
20238
|
return `<nav class="fd-breadcrumb" aria-label="Breadcrumb">
|
|
@@ -19138,7 +20270,7 @@ ${items.map(
|
|
|
19138
20270
|
</div>`;
|
|
19139
20271
|
}
|
|
19140
20272
|
function renderDocsRuntimeScript(docs) {
|
|
19141
|
-
const docsEntry = JSON.stringify(
|
|
20273
|
+
const docsEntry = JSON.stringify(normalizeEntry2(docs.entry));
|
|
19142
20274
|
return `<script>(()=>{if(window.__farmDocsRuntime)return;window.__farmDocsRuntime=true;document.documentElement.dataset.farmDocsRuntime="true";document.documentElement.dataset.farmDocsRuntimeId=Math.random().toString(36).slice(2);const docsEntry=${docsEntry};let cleanupToc=()=>{};let closeMobileSidebar=()=>{};const normalizePath=(path)=>path.length>1?path.replace(/\\/+$/,""):path;const isDocsPath=(path)=>{const next=normalizePath(path);const entry=normalizePath(docsEntry);if(next.endsWith(".md"))return false;if(entry==="/")return true;return next===entry||next.startsWith(entry+"/")};const initToc=()=>{cleanupToc();const toc=document.getElementById("nd-toc");if(!toc){cleanupToc=()=>{};return}const links=Array.from(toc.querySelectorAll("[data-toc-item]"));const thumb=toc.querySelector("[data-toc-thumb]");const pairs=links.map((link)=>{let id=link.hash.slice(1);try{id=decodeURIComponent(id)}catch{}return{link,heading:document.getElementById(id)}}).filter((item)=>item.heading);const setActive=(active)=>{for(const {link} of pairs)link.dataset.active=link===active.link?"true":"false";if(!thumb)return;const styles=getComputedStyle(active.link);const top=active.link.offsetTop+parseFloat(styles.paddingTop||"0");const bottom=active.link.offsetTop+active.link.clientHeight-parseFloat(styles.paddingBottom||"0");thumb.style.clipPath="polygon(0 "+top+"px,100% "+top+"px,100% "+bottom+"px,0 "+bottom+"px)"};const update=()=>{if(pairs.length===0)return;const offset=Math.min(window.innerHeight*0.3,160);let active=pairs[0];for(const pair of pairs){if(pair.heading.getBoundingClientRect().top<=offset)active=pair;else break}setActive(active)};let frame=0;const schedule=()=>{if(frame)return;frame=requestAnimationFrame(()=>{frame=0;update()})};const onHashChange=()=>setTimeout(schedule,0);window.addEventListener("scroll",schedule,{passive:true});window.addEventListener("resize",schedule);window.addEventListener("hashchange",onHashChange);cleanupToc=()=>{window.removeEventListener("scroll",schedule);window.removeEventListener("resize",schedule);window.removeEventListener("hashchange",onHashChange);if(frame)cancelAnimationFrame(frame);frame=0};update()};const getSidebar=()=>document.getElementById("nd-sidebar");const ensureActiveVisible=()=>{const sidebar=getSidebar();if(!sidebar)return;const active=sidebar.querySelector('a[data-active="true"]');if(!(active instanceof HTMLElement))return;const activeRect=active.getBoundingClientRect();const sidebarRect=sidebar.getBoundingClientRect();if(activeRect.top<sidebarRect.top||activeRect.bottom>sidebarRect.bottom)sidebar.scrollTop+=activeRect.top-sidebarRect.top-(sidebar.clientHeight-activeRect.height)/2};const setSidebarActive=(path)=>{const sidebar=getSidebar();if(!sidebar)return;const current=normalizePath(path);for(const link of Array.from(sidebar.querySelectorAll("a[href]"))){try{link.dataset.active=normalizePath(new URL(link.href,location.href).pathname)===current?"true":"false"}catch{}}ensureActiveVisible()};const initMobileSidebar=()=>{const layout=document.getElementById("nd-docs-layout");const sidebar=getSidebar();const toggle=document.querySelector("[data-sidebar-toggle]");const backdrop=document.querySelector("[data-sidebar-backdrop]");if(!layout||!sidebar||!(toggle instanceof HTMLButtonElement))return;const setOpen=(open)=>{layout.dataset.sidebarOpen=open?"true":"false";document.documentElement.dataset.farmDocsSidebar=open?"open":"closed";toggle.setAttribute("aria-expanded",open?"true":"false");toggle.setAttribute("aria-label",open?"Close menu":"Open menu")};const toggleOpen=()=>setOpen(layout.dataset.sidebarOpen!=="true");closeMobileSidebar=()=>setOpen(false);toggle.addEventListener("click",(event)=>{event.preventDefault();toggleOpen()});backdrop?.addEventListener("click",()=>closeMobileSidebar());document.addEventListener("keydown",(event)=>{if(event.key==="Escape")closeMobileSidebar()});sidebar.addEventListener("click",(event)=>{const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(target)closeMobileSidebar()});closeMobileSidebar()};const initSidebarScroll=()=>{const sidebar=getSidebar();if(!sidebar)return;const key="farmdocs:sidebar-scroll:"+location.origin;const getStorage=()=>{try{return window.sessionStorage}catch{return null}};const readSaved=()=>{try{const raw=getStorage()?.getItem(key);if(!raw)return null;const parsed=JSON.parse(raw);return parsed&&typeof parsed==="object"?parsed:null}catch{return null}};const save=(path=location.pathname)=>{try{getStorage()?.setItem(key,JSON.stringify({path,scrollTop:sidebar.scrollTop}))}catch{}};const saved=readSaved();if(saved?.path===location.pathname&&Number.isFinite(Number(saved.scrollTop)))sidebar.scrollTop=Number(saved.scrollTop);ensureActiveVisible();save();sidebar.addEventListener("scroll",()=>save(),{passive:true});sidebar.addEventListener("click",(event)=>{const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(!target)return;try{save(new URL(target.href,location.href).pathname)}catch{save()}});window.addEventListener("beforeunload",()=>save())};let navigateController=null;const getPageKey=(root)=>{const article=root.getElementById("nd-page");if(!article)return"";return article.querySelector("h1")?.textContent?.trim()||article.textContent?.replace(/\\s+/g," ").trim().slice(0,160)||""};const swapDocsPage=(html,url)=>{const nextDoc=new DOMParser().parseFromString(html,"text/html");const nextArticle=nextDoc.getElementById("nd-page");const currentArticle=document.getElementById("nd-page");if(!nextArticle||!currentArticle)return false;const nextKey=getPageKey(nextDoc);const importedArticle=document.importNode(nextArticle,true);currentArticle.replaceWith(importedArticle);const renderedArticle=document.getElementById("nd-page");if(!renderedArticle||renderedArticle===currentArticle||(nextKey&&getPageKey(document)!==nextKey))return false;const nextToc=nextDoc.getElementById("nd-toc");const currentToc=document.getElementById("nd-toc");if(nextToc&¤tToc)currentToc.replaceWith(document.importNode(nextToc,true));if(nextDoc.title)document.title=nextDoc.title;const nextDescription=nextDoc.querySelector('meta[name="description"]');const currentDescription=document.querySelector('meta[name="description"]');if(nextDescription&¤tDescription)currentDescription.setAttribute("content",nextDescription.getAttribute("content")||"");setSidebarActive(url.pathname);initToc();closeMobileSidebar();return true};const navigateDocs=async(url,{replace=false,scroll=true}={})=>{if(!isDocsPath(url.pathname))return false;if(navigateController)navigateController.abort();const controller=new AbortController();navigateController=controller;document.documentElement.dataset.farmDocsNavigating="true";try{const response=await fetch(url.href,{cache:"no-store",headers:{accept:"text/html","x-farm-docs-navigate":"1"},signal:controller.signal});if(!response.ok||!((response.headers.get("content-type")||"").includes("text/html")))return false;const html=await response.text();if(!swapDocsPage(html,url))return false;if(replace)history.replaceState({farmDocs:true},"",url.href);else history.pushState({farmDocs:true},"",url.href);if(scroll){if(url.hash){let id=url.hash.slice(1);try{id=decodeURIComponent(id)}catch{}document.getElementById(id)?.scrollIntoView({block:"start"})}else window.scrollTo({top:0,left:0})}return true}catch(error){if(error?.name==="AbortError")return true;return false}finally{if(navigateController===controller){delete document.documentElement.dataset.farmDocsNavigating;navigateController=null}}};const initClientNavigation=()=>{document.addEventListener("click",(event)=>{if(event.defaultPrevented||event.button!==0||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)return;const target=event.target instanceof Element?event.target.closest("a[href]"):null;if(!target||target.target||target.hasAttribute("download"))return;let url;try{url=new URL(target.href,location.href)}catch{return}if(url.origin!==location.origin||!isDocsPath(url.pathname))return;if(normalizePath(url.pathname)===normalizePath(location.pathname)&&url.hash)return;event.preventDefault();navigateDocs(url).then((handled)=>{if(!handled)location.href=url.href})});window.addEventListener("popstate",()=>{navigateDocs(new URL(location.href),{replace:true,scroll:false}).then((handled)=>{if(!handled)location.reload()})})};const init=()=>{initToc();initMobileSidebar();initSidebarScroll();initClientNavigation()};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",init,{once:true});else init()})();</script>`;
|
|
19143
20275
|
}
|
|
19144
20276
|
function renderDocsPageActionsRuntimeScript() {
|
|
@@ -19153,13 +20285,13 @@ ${renderDocsHashRuntimeScript()}
|
|
|
19153
20285
|
${renderDocsPageActionsRuntimeScript()}`;
|
|
19154
20286
|
}
|
|
19155
20287
|
function readCssWithImports(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
19156
|
-
const resolved =
|
|
20288
|
+
const resolved = import_node_path13.default.resolve(filePath);
|
|
19157
20289
|
if (seen.has(resolved)) return "";
|
|
19158
20290
|
seen.add(resolved);
|
|
19159
|
-
const source = (0,
|
|
20291
|
+
const source = (0, import_node_fs9.readFileSync)(resolved, "utf8");
|
|
19160
20292
|
return source.replace(/@import\s+["']([^"']+)["'];?/g, (_match, importPath) => {
|
|
19161
20293
|
try {
|
|
19162
|
-
const importedPath = importPath.startsWith(".") ?
|
|
20294
|
+
const importedPath = importPath.startsWith(".") ? import_node_path13.default.resolve(import_node_path13.default.dirname(resolved), importPath) : (0, import_node_module5.createRequire)(resolved).resolve(importPath);
|
|
19163
20295
|
return readCssWithImports(importedPath, seen);
|
|
19164
20296
|
} catch {
|
|
19165
20297
|
return "";
|
|
@@ -19167,11 +20299,11 @@ function readCssWithImports(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
|
19167
20299
|
});
|
|
19168
20300
|
}
|
|
19169
20301
|
function resolvePixelBorderThemeCss(options) {
|
|
19170
|
-
const cacheKey =
|
|
20302
|
+
const cacheKey = import_node_path13.default.resolve(options.root);
|
|
19171
20303
|
const cached = themeCssCache.get(cacheKey);
|
|
19172
20304
|
if (cached !== void 0) return cached;
|
|
19173
20305
|
try {
|
|
19174
|
-
const requireFromApp = (0, import_node_module5.createRequire)(
|
|
20306
|
+
const requireFromApp = (0, import_node_module5.createRequire)(import_node_path13.default.join(cacheKey, "package.json"));
|
|
19175
20307
|
const themeCssPath = requireFromApp.resolve("@farming-labs/theme/pixel-border/css");
|
|
19176
20308
|
const requireFromTheme = (0, import_node_module5.createRequire)(themeCssPath);
|
|
19177
20309
|
const fumadocsCssPath = requireFromTheme.resolve("fumadocs-ui/style.css");
|
|
@@ -19184,17 +20316,28 @@ ${readCssWithImports(themeCssPath)}`;
|
|
|
19184
20316
|
return "";
|
|
19185
20317
|
}
|
|
19186
20318
|
}
|
|
19187
|
-
function renderFarmDocsBridgeCss(docs) {
|
|
20319
|
+
function renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts) {
|
|
19188
20320
|
const sidebarWidth = getThemeLayoutValue(docs, "sidebarWidth", 320);
|
|
19189
20321
|
const contentWidth = getThemeLayoutValue(docs, "contentWidth", 860);
|
|
20322
|
+
const fontFaces = fontAssets.map(
|
|
20323
|
+
({ family, url }) => `@font-face { font-family: "${family}"; src: url("${url}") format("woff2"); font-style: normal; font-weight: 100 900; font-display: block; }`
|
|
20324
|
+
).join("\n");
|
|
20325
|
+
const fontVariables = [
|
|
20326
|
+
fontAssets.some(({ family }) => family === "Geist Sans") ? '--font-geist-sans: "Geist Sans", ui-sans-serif, system-ui, sans-serif;' : "",
|
|
20327
|
+
fontAssets.some(({ family }) => family === "Geist Mono") ? '--font-geist-mono: "Geist Mono", ui-monospace, monospace;' : ""
|
|
20328
|
+
].filter(Boolean).join(" ");
|
|
20329
|
+
const fontCss = fontFaces ? `${fontFaces}
|
|
20330
|
+
:root { ${fontVariables} }` : "";
|
|
20331
|
+
const layoutFontVariables = [
|
|
20332
|
+
renderFarmDocsLayoutFontVariable("--fd-layout-font-body", layoutFonts?.body),
|
|
20333
|
+
renderFarmDocsLayoutFontVariable("--fd-layout-font-code", layoutFonts?.code)
|
|
20334
|
+
].filter(Boolean).join(" ");
|
|
19190
20335
|
return `
|
|
19191
|
-
|
|
19192
|
-
@font-face { font-family: "Geist Mono"; src: local("Geist Mono"), url("${GEIST_MONO_FONT_URL}") format("woff2"), url("/node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2"); font-display: block; font-style: normal; font-weight: 100 900; }
|
|
19193
|
-
:root { color-scheme: dark; --font-geist-sans: "Geist Sans"; --font-geist-mono: "Geist Mono"; --fd-sidebar-width: ${sidebarWidth}px; --fd-content-width: ${contentWidth}px; --fd-toc-width: 240px; --fd-docs-height: 100vh; --fd-docs-row-1: var(--fd-nav-height, 44px); --fd-docs-font-sans: var(--font-geist-sans, "Geist Sans", var(--font-sans, system-ui, -apple-system, sans-serif)); --fd-docs-font-mono: var(--font-geist-mono, "Geist Mono", var(--font-mono, ui-monospace, monospace)); --fd-font-sans: var(--fd-docs-font-sans); --fd-font-mono: var(--fd-docs-font-mono); --fd-pixel-rail-width: 12px; --fd-sidebar-edge: calc(var(--fd-pixel-rail-width) + 18px); --fd-sidebar-guide-x: calc(var(--fd-sidebar-edge) + 16px); --fd-sidebar-link-x: calc(var(--fd-sidebar-guide-x) + 22px); --fd-sidebar-sub-guide-x: calc(var(--fd-sidebar-link-x) + 7px); --fd-sidebar-sub-link-x: calc(var(--fd-sidebar-sub-guide-x) + 28px); --fd-sidebar-branch-gap: 0px; --fd-sidebar-nested-icon-gap: 0px; --fd-sidebar-line-color: color-mix(in srgb, var(--color-fd-border, hsl(0 0% 15%)) 88%, transparent); }
|
|
20336
|
+
:root { color-scheme: dark; --font-geist-sans: ui-sans-serif, system-ui, sans-serif; --font-geist-mono: ui-monospace, monospace; ${layoutFontVariables} --fd-sidebar-width: ${sidebarWidth}px; --fd-content-width: ${contentWidth}px; --fd-toc-width: 240px; --fd-docs-height: 100vh; --fd-docs-row-1: var(--fd-nav-height, 44px); --fd-docs-font-sans: var(--fd-layout-font-body, var(--font-geist-sans, var(--font-sans, system-ui, -apple-system, sans-serif))); --fd-docs-font-mono: var(--fd-layout-font-code, var(--font-geist-mono, var(--font-mono, ui-monospace, monospace))); --fd-font-sans: var(--fd-docs-font-sans); --fd-font-mono: var(--fd-docs-font-mono); --fd-pixel-rail-width: 12px; --fd-sidebar-edge: calc(var(--fd-pixel-rail-width) + 18px); --fd-sidebar-guide-x: calc(var(--fd-sidebar-edge) + 16px); --fd-sidebar-link-x: calc(var(--fd-sidebar-guide-x) + 22px); --fd-sidebar-sub-guide-x: calc(var(--fd-sidebar-link-x) + 7px); --fd-sidebar-sub-link-x: calc(var(--fd-sidebar-sub-guide-x) + 28px); --fd-sidebar-branch-gap: 0px; --fd-sidebar-nested-icon-gap: 0px; --fd-sidebar-line-color: color-mix(in srgb, var(--color-fd-border, hsl(0 0% 15%)) 88%, transparent); }
|
|
19194
20337
|
* { box-sizing: border-box; }
|
|
19195
20338
|
html { background: var(--color-fd-background, hsl(0 0% 2%)); scroll-padding-top: calc(var(--fd-nav-height, 44px) + 24px); }
|
|
19196
20339
|
html[data-farm-docs-sidebar="open"], html[data-farm-docs-sidebar="open"] body { overflow: hidden; }
|
|
19197
|
-
body { margin: 0; min-height: 100vh; background: var(--color-fd-background, hsl(0 0% 2%)); color: var(--color-fd-foreground, oklch(0.985 0.001 106.423)); font-family: var(--fd-docs-font-sans); text-rendering: optimizeLegibility; }
|
|
20340
|
+
body { margin: 0; min-height: 100vh; background: var(--color-fd-background, hsl(0 0% 2%)); color: var(--color-fd-foreground, oklch(0.985 0.001 106.423)); font-family: var(--fd-docs-font-sans); font-synthesis: none; text-rendering: optimizeLegibility; }
|
|
19198
20341
|
::selection { background: var(--color-fd-foreground, #fff); color: var(--color-fd-background, #000); }
|
|
19199
20342
|
a { color: inherit; }
|
|
19200
20343
|
#nd-docs-layout { --fd-sidebar-col: var(--fd-sidebar-width); display: grid; grid-template: "sidebar header header" var(--fd-nav-height, 44px) "sidebar main toc" 1fr / var(--fd-sidebar-width) minmax(0, 1fr) var(--fd-toc-width) !important; min-height: 100vh; border-top: 1px solid var(--color-fd-border, hsl(0 0% 15%)); background: var(--color-fd-background, hsl(0 0% 2%)); }
|
|
@@ -19374,14 +20517,45 @@ function renderFarmDocsBridgeCss(docs) {
|
|
|
19374
20517
|
.sh__line { min-height: 1.6em; }
|
|
19375
20518
|
}
|
|
19376
20519
|
${farmDocsPixelBorderCss}
|
|
20520
|
+
${fontCss}
|
|
19377
20521
|
`;
|
|
19378
20522
|
}
|
|
19379
|
-
function
|
|
20523
|
+
function renderFarmDocsLayoutFontVariable(name, font) {
|
|
20524
|
+
const family = font?.style.fontFamily;
|
|
20525
|
+
if (!family || /[;{}<>]/.test(family)) return "";
|
|
20526
|
+
return `${name}: ${family};`;
|
|
20527
|
+
}
|
|
20528
|
+
function renderFarmDocsFontPreloads(fontAssets) {
|
|
20529
|
+
return fontAssets.map(
|
|
20530
|
+
({ url }) => `<link rel="preload" href="${escapeAttribute2(url)}" as="font" type="font/woff2" crossorigin>`
|
|
20531
|
+
).join("\n ");
|
|
20532
|
+
}
|
|
20533
|
+
function renderFarmDocsFontPreloadHeader(fontAssets) {
|
|
20534
|
+
return fontAssets.map(({ url }) => `<${url}>; rel=preload; as=font; type=font/woff2; crossorigin`).join(", ");
|
|
20535
|
+
}
|
|
20536
|
+
function getFarmLayoutFontPreloads(layoutFonts) {
|
|
20537
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20538
|
+
return [layoutFonts?.body, layoutFonts?.code].flatMap(
|
|
20539
|
+
(font) => (font?.preloads || []).filter(({ href }) => {
|
|
20540
|
+
if (seen.has(href)) return false;
|
|
20541
|
+
seen.add(href);
|
|
20542
|
+
return true;
|
|
20543
|
+
})
|
|
20544
|
+
);
|
|
20545
|
+
}
|
|
20546
|
+
function renderFarmLayoutFontPreloadHeader(layoutFonts) {
|
|
20547
|
+
return getFarmLayoutFontPreloads(layoutFonts).map(({ href, type }) => `<${href}>; rel=preload; as=font; type=${type}; crossorigin`).join(", ");
|
|
20548
|
+
}
|
|
20549
|
+
function renderPixelDocsHtml(page2, pages, docs, themeCss, clientEntry, faviconHref, requestUrl, fontAssets, layoutFonts, fontStylesheetHref) {
|
|
19380
20550
|
const navTitle = typeof docs.config.nav === "object" && docs.config.nav && "title" in docs.config.nav ? String(docs.config.nav.title || "Docs") : "Docs";
|
|
19381
20551
|
const description = page2.description || docs.config.metadata?.description || "";
|
|
19382
20552
|
const tocItems = extractTocItems(page2.body, getThemeTocDepth(docs));
|
|
19383
20553
|
const themeName = getThemeName(docs);
|
|
19384
20554
|
const searchEnabled = isFarmDocsSearchEnabled(docs);
|
|
20555
|
+
const socialMetadata = isFarmDocsSocialImageEnabled(page2, docs) ? renderFarmDocsSocialMetadata(
|
|
20556
|
+
createFarmDocsSocialImageDescriptor(page2, docs, requestUrl),
|
|
20557
|
+
getFarmDocsCustomSocialImage(page2)
|
|
20558
|
+
) : "";
|
|
19385
20559
|
return `<!DOCTYPE html>
|
|
19386
20560
|
<html class="dark" lang="en" data-docs-theme="${escapeAttribute2(themeName)}">
|
|
19387
20561
|
<head>
|
|
@@ -19390,11 +20564,12 @@ function renderPixelDocsHtml(page2, pages, docs, themeCss, clientEntry, faviconH
|
|
|
19390
20564
|
<meta name="generator" content="@farming-labs/docs via Farm.js">
|
|
19391
20565
|
<title>${escapeHtml(page2.title)}</title>
|
|
19392
20566
|
${renderFarmDocsFaviconLink(faviconHref)}
|
|
19393
|
-
|
|
19394
|
-
|
|
20567
|
+
${renderFarmDocsFontPreloads(fontAssets)}
|
|
20568
|
+
${fontStylesheetHref ? `<link rel="stylesheet" href="${escapeAttribute2(fontStylesheetHref)}">` : ""}
|
|
19395
20569
|
${description ? `<meta name="description" content="${escapeHtml(description)}">` : ""}
|
|
20570
|
+
${socialMetadata}
|
|
19396
20571
|
<style>${themeCss}
|
|
19397
|
-
${renderFarmDocsBridgeCss(docs)}</style>
|
|
20572
|
+
${renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts)}</style>
|
|
19398
20573
|
${searchEnabled ? renderDocsSearchBootstrapScript() : ""}
|
|
19399
20574
|
</head>
|
|
19400
20575
|
<body>
|
|
@@ -19446,9 +20621,34 @@ ${renderMarkdownHtmlWithTitleMeta(page2, docs)}
|
|
|
19446
20621
|
}
|
|
19447
20622
|
function createFarmDocsHandler(docs, options) {
|
|
19448
20623
|
const faviconHref = resolveFarmDocsFavicon(docs, options);
|
|
20624
|
+
const fontAssets = options.fontAssets ?? toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(options.root));
|
|
20625
|
+
const fallbackFontPreloadHeader = renderFarmDocsFontPreloadHeader(fontAssets);
|
|
19449
20626
|
return /* @__PURE__ */ __name(async function handleFarmDocsRequest(request) {
|
|
19450
20627
|
if (!docs?.enabled || request.method !== "GET" && request.method !== "HEAD") return null;
|
|
19451
20628
|
const contentDir = resolveFarmDocsContentDir(docs, options);
|
|
20629
|
+
const requestUrl = new URL(request.url);
|
|
20630
|
+
const socialImageSlug = getFarmDocsSocialImageSlug(docs, requestUrl);
|
|
20631
|
+
if (socialImageSlug !== null) {
|
|
20632
|
+
const socialImagePage = loadFarmDocsPage(contentDir, docs, socialImageSlug);
|
|
20633
|
+
if (!socialImagePage || !isFarmDocsSocialImageEnabled(socialImagePage, docs) || getFarmDocsCustomSocialImage(socialImagePage)) {
|
|
20634
|
+
return null;
|
|
20635
|
+
}
|
|
20636
|
+
const descriptor = createFarmDocsSocialImageDescriptor(socialImagePage, docs, requestUrl);
|
|
20637
|
+
if (requestUrl.pathname !== descriptor.imagePath) return null;
|
|
20638
|
+
const etag = `"${descriptor.hash}"`;
|
|
20639
|
+
const immutable = requestUrl.searchParams.get("v") === descriptor.hash;
|
|
20640
|
+
const headers = new Headers({
|
|
20641
|
+
"Content-Type": "image/svg+xml; charset=utf-8",
|
|
20642
|
+
"Cache-Control": immutable ? "public, max-age=31536000, immutable" : "public, max-age=0, must-revalidate",
|
|
20643
|
+
ETag: etag,
|
|
20644
|
+
"X-Content-Type-Options": "nosniff"
|
|
20645
|
+
});
|
|
20646
|
+
if (request.headers.get("if-none-match") === etag) {
|
|
20647
|
+
return new Response(null, { status: 304, headers });
|
|
20648
|
+
}
|
|
20649
|
+
if (request.method === "HEAD") return new Response(null, { status: 200, headers });
|
|
20650
|
+
return new Response(renderFarmDocsSocialImageSvg(descriptor), { status: 200, headers });
|
|
20651
|
+
}
|
|
19452
20652
|
const publicResponse = createFarmDocsPublicResponse(contentDir, docs, request);
|
|
19453
20653
|
if (publicResponse) return publicResponse;
|
|
19454
20654
|
if (!isFarmDocsRequest(docs, request)) return null;
|
|
@@ -19471,6 +20671,11 @@ function createFarmDocsHandler(docs, options) {
|
|
|
19471
20671
|
}
|
|
19472
20672
|
);
|
|
19473
20673
|
}
|
|
20674
|
+
const pathname = new URL(request.url).pathname;
|
|
20675
|
+
const layoutFonts = await options.resolveLayoutFonts?.(pathname);
|
|
20676
|
+
const usesLayoutFonts = Boolean(layoutFonts?.body || layoutFonts?.code);
|
|
20677
|
+
const activeFontAssets = usesLayoutFonts ? [] : fontAssets;
|
|
20678
|
+
const fontPreloadHeader = usesLayoutFonts ? renderFarmLayoutFontPreloadHeader(layoutFonts) : fallbackFontPreloadHeader;
|
|
19474
20679
|
return new Response(
|
|
19475
20680
|
renderPixelDocsHtml(
|
|
19476
20681
|
page2,
|
|
@@ -19478,39 +20683,44 @@ function createFarmDocsHandler(docs, options) {
|
|
|
19478
20683
|
docs,
|
|
19479
20684
|
resolvePixelBorderThemeCss(options),
|
|
19480
20685
|
options.clientEntry || "/farm-client.js",
|
|
19481
|
-
faviconHref
|
|
20686
|
+
faviconHref,
|
|
20687
|
+
requestUrl,
|
|
20688
|
+
activeFontAssets,
|
|
20689
|
+
layoutFonts,
|
|
20690
|
+
usesLayoutFonts ? options.fontStylesheetHref : void 0
|
|
19482
20691
|
),
|
|
19483
20692
|
{
|
|
19484
20693
|
status: 200,
|
|
19485
20694
|
headers: {
|
|
19486
20695
|
"Content-Type": "text/html; charset=utf-8",
|
|
19487
|
-
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=300"
|
|
20696
|
+
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
|
|
20697
|
+
...fontPreloadHeader ? { Link: fontPreloadHeader } : {}
|
|
19488
20698
|
}
|
|
19489
20699
|
}
|
|
19490
20700
|
);
|
|
19491
20701
|
}, "handleFarmDocsRequest");
|
|
19492
20702
|
}
|
|
19493
|
-
var
|
|
20703
|
+
var import_node_fs9, import_node_module5, import_node_path13, import_docs, import_marked, import_sugar_high, DOCS_FILE_NAMES, DOCS_FILE_EXTENSIONS2, FARM_DOCS_FALLBACK_FAVICON, FARM_DOCS_FAVICON_FILES, CODE_LANGUAGE_LABELS, EXTENSIONLESS_CODE_FILENAMES, SIDEBAR_SECTION_ORDER, SIDEBAR_PAGE_ORDER, themeCssCache;
|
|
19494
20704
|
var init_handler = __esm({
|
|
19495
20705
|
"src/docs/handler.ts"() {
|
|
19496
20706
|
"use strict";
|
|
19497
|
-
|
|
20707
|
+
import_node_fs9 = require("fs");
|
|
19498
20708
|
import_node_module5 = require("module");
|
|
19499
|
-
|
|
20709
|
+
import_node_path13 = __toESM(require("path"));
|
|
19500
20710
|
import_docs = require("@farming-labs/docs");
|
|
19501
20711
|
import_marked = require("marked");
|
|
19502
20712
|
import_sugar_high = require("sugar-high");
|
|
20713
|
+
init_fonts();
|
|
19503
20714
|
init_last_modified();
|
|
19504
20715
|
init_pixel_border_css();
|
|
19505
20716
|
init_search_client();
|
|
20717
|
+
init_social_image();
|
|
19506
20718
|
DOCS_FILE_NAMES = ["page.mdx", "page.md", "index.mdx", "index.md"];
|
|
19507
20719
|
DOCS_FILE_EXTENSIONS2 = [".mdx", ".md"];
|
|
19508
20720
|
FARM_DOCS_FALLBACK_FAVICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='black'/%3E%3Cpath d='M7 8h18v3H10v5h12v3H10v5H7z' fill='white'/%3E%3C/svg%3E";
|
|
19509
20721
|
FARM_DOCS_FAVICON_FILES = ["favicon.svg", "favicon.ico", "favicon.png"];
|
|
19510
|
-
GEIST_SANS_FONT_URL = "/assets/Geist-Variable-CrgPqtmy.woff2";
|
|
19511
|
-
GEIST_MONO_FONT_URL = "/assets/GeistMono-Variable-BNLlm6Cd.woff2";
|
|
19512
20722
|
__name(trimSlashes2, "trimSlashes");
|
|
19513
|
-
__name(
|
|
20723
|
+
__name(normalizeEntry2, "normalizeEntry");
|
|
19514
20724
|
__name(normalizeSlug, "normalizeSlug");
|
|
19515
20725
|
__name(resolveFarmDocsFavicon, "resolveFarmDocsFavicon");
|
|
19516
20726
|
__name(renderFarmDocsFaviconLink, "renderFarmDocsFaviconLink");
|
|
@@ -19700,6 +20910,11 @@ var init_handler = __esm({
|
|
|
19700
20910
|
__name(readCssWithImports, "readCssWithImports");
|
|
19701
20911
|
__name(resolvePixelBorderThemeCss, "resolvePixelBorderThemeCss");
|
|
19702
20912
|
__name(renderFarmDocsBridgeCss, "renderFarmDocsBridgeCss");
|
|
20913
|
+
__name(renderFarmDocsLayoutFontVariable, "renderFarmDocsLayoutFontVariable");
|
|
20914
|
+
__name(renderFarmDocsFontPreloads, "renderFarmDocsFontPreloads");
|
|
20915
|
+
__name(renderFarmDocsFontPreloadHeader, "renderFarmDocsFontPreloadHeader");
|
|
20916
|
+
__name(getFarmLayoutFontPreloads, "getFarmLayoutFontPreloads");
|
|
20917
|
+
__name(renderFarmLayoutFontPreloadHeader, "renderFarmLayoutFontPreloadHeader");
|
|
19703
20918
|
__name(renderPixelDocsHtml, "renderPixelDocsHtml");
|
|
19704
20919
|
__name(createFarmDocsHandler, "createFarmDocsHandler");
|
|
19705
20920
|
}
|
|
@@ -20468,8 +21683,8 @@ var init_generator = __esm({
|
|
|
20468
21683
|
}
|
|
20469
21684
|
routeGroups.get(key).push(route);
|
|
20470
21685
|
}
|
|
20471
|
-
for (const [
|
|
20472
|
-
const openAPIPath = this.convertToOpenAPIPath(
|
|
21686
|
+
for (const [path31, routeList] of routeGroups) {
|
|
21687
|
+
const openAPIPath = this.convertToOpenAPIPath(path31);
|
|
20473
21688
|
spec.paths[openAPIPath] = {};
|
|
20474
21689
|
for (const route of routeList) {
|
|
20475
21690
|
for (const method of route.methods) {
|
|
@@ -20483,8 +21698,8 @@ var init_generator = __esm({
|
|
|
20483
21698
|
/**
|
|
20484
21699
|
* Convert Farm.js API path to OpenAPI path format
|
|
20485
21700
|
*/
|
|
20486
|
-
convertToOpenAPIPath(
|
|
20487
|
-
return
|
|
21701
|
+
convertToOpenAPIPath(path31) {
|
|
21702
|
+
return path31.replace(/^\/api/, "");
|
|
20488
21703
|
}
|
|
20489
21704
|
/**
|
|
20490
21705
|
* Extract request body schema from endpoint
|
|
@@ -20646,8 +21861,8 @@ var init_generator = __esm({
|
|
|
20646
21861
|
/**
|
|
20647
21862
|
* Generate operation summary
|
|
20648
21863
|
*/
|
|
20649
|
-
generateSummary(
|
|
20650
|
-
const cleanPath =
|
|
21864
|
+
generateSummary(path31, method) {
|
|
21865
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20651
21866
|
const pathParts = cleanPath.split("/");
|
|
20652
21867
|
const lastPart = pathParts[pathParts.length - 1];
|
|
20653
21868
|
const action = method === "GET" ? "Get" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
|
|
@@ -20656,22 +21871,22 @@ var init_generator = __esm({
|
|
|
20656
21871
|
/**
|
|
20657
21872
|
* Generate operation description
|
|
20658
21873
|
*/
|
|
20659
|
-
generateDescription(
|
|
20660
|
-
const cleanPath =
|
|
21874
|
+
generateDescription(path31, method) {
|
|
21875
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20661
21876
|
return `${method} ${cleanPath} endpoint`;
|
|
20662
21877
|
}
|
|
20663
21878
|
/**
|
|
20664
21879
|
* Generate operation ID
|
|
20665
21880
|
*/
|
|
20666
|
-
generateOperationId(
|
|
20667
|
-
const cleanPath =
|
|
21881
|
+
generateOperationId(path31, method) {
|
|
21882
|
+
const cleanPath = path31.replace(/^\/api\//, "").replace(/\//g, "_");
|
|
20668
21883
|
return `${method.toLowerCase()}_${cleanPath}`;
|
|
20669
21884
|
}
|
|
20670
21885
|
/**
|
|
20671
21886
|
* Generate tags for grouping operations
|
|
20672
21887
|
*/
|
|
20673
|
-
generateTags(
|
|
20674
|
-
const cleanPath =
|
|
21888
|
+
generateTags(path31) {
|
|
21889
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20675
21890
|
const pathParts = cleanPath.split("/");
|
|
20676
21891
|
if (pathParts.length > 1) {
|
|
20677
21892
|
return [pathParts[0]];
|
|
@@ -20684,8 +21899,8 @@ var init_generator = __esm({
|
|
|
20684
21899
|
async generateSpecFile(routes, outputPath) {
|
|
20685
21900
|
const spec = await this.generateSpec(routes);
|
|
20686
21901
|
const fs8 = require("fs");
|
|
20687
|
-
const
|
|
20688
|
-
const dir =
|
|
21902
|
+
const path31 = require("path");
|
|
21903
|
+
const dir = path31.dirname(outputPath);
|
|
20689
21904
|
if (!fs8.existsSync(dir)) {
|
|
20690
21905
|
fs8.mkdirSync(dir, { recursive: true });
|
|
20691
21906
|
}
|
|
@@ -21105,7 +22320,7 @@ async function createFarmDevtoolsSnapshot(input) {
|
|
|
21105
22320
|
generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
|
|
21106
22321
|
health: resolveHealth(diagnostics),
|
|
21107
22322
|
project: {
|
|
21108
|
-
name:
|
|
22323
|
+
name: import_node_path14.default.basename(import_node_path14.default.resolve(input.root)),
|
|
21109
22324
|
root: input.root,
|
|
21110
22325
|
srcDir: input.srcDir,
|
|
21111
22326
|
basePath: config.basePath || "/",
|
|
@@ -21154,11 +22369,11 @@ async function createFarmDevtoolsSnapshot(input) {
|
|
|
21154
22369
|
diagnostics
|
|
21155
22370
|
};
|
|
21156
22371
|
}
|
|
21157
|
-
var
|
|
22372
|
+
var import_node_path14;
|
|
21158
22373
|
var init_devtools = __esm({
|
|
21159
22374
|
"src/devtools.ts"() {
|
|
21160
22375
|
"use strict";
|
|
21161
|
-
|
|
22376
|
+
import_node_path14 = __toESM(require("path"));
|
|
21162
22377
|
init_config2();
|
|
21163
22378
|
init_cron();
|
|
21164
22379
|
init_route_runtime();
|
|
@@ -22982,7 +24197,7 @@ function fileContainsProgrammaticPageRoute(file) {
|
|
|
22982
24197
|
}
|
|
22983
24198
|
function rewriteEarlySsrRelativeImports(options) {
|
|
22984
24199
|
const cleanId = options.id.split("?", 1)[0];
|
|
22985
|
-
if (!
|
|
24200
|
+
if (!path27.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
|
|
22986
24201
|
return null;
|
|
22987
24202
|
}
|
|
22988
24203
|
const replacements = [];
|
|
@@ -23002,7 +24217,7 @@ function rewriteEarlySsrRelativeImports(options) {
|
|
|
23002
24217
|
const suffixIndex = source.value.search(/[?#]/);
|
|
23003
24218
|
const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
|
|
23004
24219
|
const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
|
|
23005
|
-
const resolvedPath =
|
|
24220
|
+
const resolvedPath = path27.resolve(path27.dirname(cleanId), sourcePath);
|
|
23006
24221
|
replacements.push({
|
|
23007
24222
|
start: source.start,
|
|
23008
24223
|
end: source.end,
|
|
@@ -23083,7 +24298,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23083
24298
|
...layerRoots.length ? {
|
|
23084
24299
|
server: {
|
|
23085
24300
|
fs: {
|
|
23086
|
-
allow: [
|
|
24301
|
+
allow: [path27.resolve(options.root || process.cwd()), ...layerRoots]
|
|
23087
24302
|
}
|
|
23088
24303
|
}
|
|
23089
24304
|
} : {}
|
|
@@ -23114,9 +24329,9 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23114
24329
|
},
|
|
23115
24330
|
server
|
|
23116
24331
|
);
|
|
23117
|
-
const globalsCSSPath =
|
|
24332
|
+
const globalsCSSPath = path27.join(server.config.root, "src/app/globals.css");
|
|
23118
24333
|
if (!fs7.existsSync(globalsCSSPath)) {
|
|
23119
|
-
const appDir =
|
|
24334
|
+
const appDir = path27.join(server.config.root, "src/app");
|
|
23120
24335
|
if (!fs7.existsSync(appDir)) {
|
|
23121
24336
|
fs7.mkdirSync(appDir, { recursive: true });
|
|
23122
24337
|
}
|
|
@@ -23138,10 +24353,10 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23138
24353
|
});
|
|
23139
24354
|
}
|
|
23140
24355
|
const sourceRoots = getFarmSourceRoots(farmConfig);
|
|
23141
|
-
server.watcher.add(sourceRoots.map((source) =>
|
|
24356
|
+
server.watcher.add(sourceRoots.map((source) => path27.join(source.root, source.srcDir)));
|
|
23142
24357
|
if (farmConfig.i18n.enabled) {
|
|
23143
24358
|
server.watcher.add(
|
|
23144
|
-
farmConfig.i18n.messages.includes("{locale}") ?
|
|
24359
|
+
farmConfig.i18n.messages.includes("{locale}") ? path27.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
|
|
23145
24360
|
);
|
|
23146
24361
|
}
|
|
23147
24362
|
const workflowConfig = farmConfig.workflows;
|
|
@@ -23151,7 +24366,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23151
24366
|
...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
|
|
23152
24367
|
], "getExtraRouteTypes");
|
|
23153
24368
|
const appDirSlugs = sourceRoots.map(
|
|
23154
|
-
(source) =>
|
|
24369
|
+
(source) => path27.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
|
|
23155
24370
|
);
|
|
23156
24371
|
const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
|
|
23157
24372
|
try {
|
|
@@ -23191,7 +24406,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23191
24406
|
}, "generateTypeArtifacts");
|
|
23192
24407
|
await generateTypeArtifacts("startup");
|
|
23193
24408
|
const srcDirSlugs = sourceRoots.map(
|
|
23194
|
-
(source) =>
|
|
24409
|
+
(source) => path27.join(source.root, source.srcDir).replace(/\\/g, "/")
|
|
23195
24410
|
);
|
|
23196
24411
|
const layerConfigFiles = new Set(
|
|
23197
24412
|
farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
|
|
@@ -23309,7 +24524,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23309
24524
|
await apiRouteManager.discoverRoutes();
|
|
23310
24525
|
let discoveredWorkflows = [];
|
|
23311
24526
|
const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
|
|
23312
|
-
(dir) => fs7.existsSync(
|
|
24527
|
+
(dir) => fs7.existsSync(path27.isAbsolute(dir) ? dir : path27.join(farmConfig.root, dir))
|
|
23313
24528
|
);
|
|
23314
24529
|
if (hasWorkflowDirectory) {
|
|
23315
24530
|
const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
|
|
@@ -23373,10 +24588,20 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23373
24588
|
logger.info(`Refreshed routes: ${reason}`);
|
|
23374
24589
|
}
|
|
23375
24590
|
}, "refreshRouteDiscovery");
|
|
24591
|
+
const farmDocsFontAssetList = farmDocsDevRuntime ? resolveFarmDocsFontAssets(farmConfig.root) : [];
|
|
23376
24592
|
const farmDocsHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsHandler(farmConfig.docs, {
|
|
23377
24593
|
root: farmConfig.root,
|
|
23378
24594
|
srcDir: farmConfig.srcDir,
|
|
23379
|
-
clientEntry: "/@farm/client.js"
|
|
24595
|
+
clientEntry: "/@farm/client.js",
|
|
24596
|
+
fontAssets: toFarmDocsPublicFontAssets(farmDocsFontAssetList),
|
|
24597
|
+
resolveLayoutFonts: /* @__PURE__ */ __name(async (pathname) => {
|
|
24598
|
+
const layouts = routeManager.matchRoute(pathname).layouts;
|
|
24599
|
+
const layoutModules = await Promise.all(
|
|
24600
|
+
layouts.map((layout2) => routeManager.loadLayoutModule(layout2.modulePath))
|
|
24601
|
+
);
|
|
24602
|
+
return resolveFarmLayoutFonts(layoutModules);
|
|
24603
|
+
}, "resolveLayoutFonts"),
|
|
24604
|
+
fontStylesheetHref: "/@farm/fonts.css"
|
|
23380
24605
|
}) : null;
|
|
23381
24606
|
const farmDocsAPIHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsAPIHandler({
|
|
23382
24607
|
rootDir: farmConfig.root,
|
|
@@ -23384,22 +24609,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23384
24609
|
docs: farmConfig.docs
|
|
23385
24610
|
}) : null;
|
|
23386
24611
|
const farmDocsFontAssets = new Map(
|
|
23387
|
-
|
|
23388
|
-
[
|
|
23389
|
-
"/assets/Geist-Variable-CrgPqtmy.woff2",
|
|
23390
|
-
path25.join(
|
|
23391
|
-
farmConfig.root,
|
|
23392
|
-
"node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2"
|
|
23393
|
-
)
|
|
23394
|
-
],
|
|
23395
|
-
[
|
|
23396
|
-
"/assets/GeistMono-Variable-BNLlm6Cd.woff2",
|
|
23397
|
-
path25.join(
|
|
23398
|
-
farmConfig.root,
|
|
23399
|
-
"node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2"
|
|
23400
|
-
)
|
|
23401
|
-
]
|
|
23402
|
-
] : []
|
|
24612
|
+
farmDocsFontAssetList.map(({ url, sourcePath }) => [url, sourcePath])
|
|
23403
24613
|
);
|
|
23404
24614
|
const logRequest = /* @__PURE__ */ __name((method, urlPath, tag) => {
|
|
23405
24615
|
try {
|
|
@@ -23463,11 +24673,12 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23463
24673
|
}
|
|
23464
24674
|
}
|
|
23465
24675
|
const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
|
|
23466
|
-
if (farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
|
|
24676
|
+
if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
|
|
23467
24677
|
res.statusCode = 200;
|
|
23468
24678
|
res.setHeader("Content-Type", "font/woff2");
|
|
23469
24679
|
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
23470
|
-
|
|
24680
|
+
if (requestMethod === "HEAD") res.end();
|
|
24681
|
+
else fs7.createReadStream(farmDocsFontPath).pipe(res);
|
|
23471
24682
|
return;
|
|
23472
24683
|
}
|
|
23473
24684
|
if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
|
|
@@ -24073,6 +25284,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24073
25284
|
modulePath: toUrlPath(route.modulePath),
|
|
24074
25285
|
isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
|
|
24075
25286
|
shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
|
|
25287
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
24076
25288
|
metadata: {
|
|
24077
25289
|
title: mergedMetadata.title,
|
|
24078
25290
|
description: mergedMetadata.description
|
|
@@ -24457,6 +25669,7 @@ export const getManifest = () => ({
|
|
|
24457
25669
|
search: route.search,
|
|
24458
25670
|
isClientComponent: moduleMetadata.isClientComponent,
|
|
24459
25671
|
shouldHydrate: moduleMetadata.shouldHydrate,
|
|
25672
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
24460
25673
|
preloads: [route.modulePath],
|
|
24461
25674
|
// In dev, preload is just the module
|
|
24462
25675
|
assets: []
|
|
@@ -24583,8 +25796,8 @@ if (import.meta.hot) {
|
|
|
24583
25796
|
}
|
|
24584
25797
|
logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
|
|
24585
25798
|
logger.info("Pre-rendering SSG pages...");
|
|
24586
|
-
const outDir =
|
|
24587
|
-
const clientDir =
|
|
25799
|
+
const outDir = path27.join(server?.config.root || process.cwd(), options.outDir || "dist");
|
|
25800
|
+
const clientDir = path27.join(outDir, "client");
|
|
24588
25801
|
for (const page2 of ssgPages) {
|
|
24589
25802
|
try {
|
|
24590
25803
|
const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
|
|
@@ -24595,7 +25808,7 @@ if (import.meta.hot) {
|
|
|
24595
25808
|
const layoutModules = await Promise.all(
|
|
24596
25809
|
layouts.map((l) => routeManager.loadLayoutModule(l.modulePath))
|
|
24597
25810
|
);
|
|
24598
|
-
const
|
|
25811
|
+
const React4 = await import("react");
|
|
24599
25812
|
const { renderToString } = await import("react-dom/server");
|
|
24600
25813
|
const PageComponent = mod.default;
|
|
24601
25814
|
const pageProps = {
|
|
@@ -24603,14 +25816,14 @@ if (import.meta.hot) {
|
|
|
24603
25816
|
searchParams: Promise.resolve({}),
|
|
24604
25817
|
path: page2.urlPath
|
|
24605
25818
|
};
|
|
24606
|
-
let pageElement =
|
|
25819
|
+
let pageElement = React4.createElement(
|
|
24607
25820
|
PageComponent,
|
|
24608
25821
|
pageProps
|
|
24609
25822
|
);
|
|
24610
25823
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
24611
25824
|
const layoutModule = layoutModules[i];
|
|
24612
25825
|
const LayoutComponent = layoutModule.default;
|
|
24613
|
-
pageElement =
|
|
25826
|
+
pageElement = React4.createElement(
|
|
24614
25827
|
LayoutComponent,
|
|
24615
25828
|
{
|
|
24616
25829
|
children: pageElement,
|
|
@@ -24636,8 +25849,8 @@ if (import.meta.hot) {
|
|
|
24636
25849
|
<script type="module" src="/assets/client.js"></script>
|
|
24637
25850
|
</body>
|
|
24638
25851
|
</html>`;
|
|
24639
|
-
const outputPath = page2.urlPath === "/" ?
|
|
24640
|
-
fs7.mkdirSync(
|
|
25852
|
+
const outputPath = page2.urlPath === "/" ? path27.join(clientDir, "index.html") : path27.join(clientDir, page2.urlPath + ".html");
|
|
25853
|
+
fs7.mkdirSync(path27.dirname(outputPath), { recursive: true });
|
|
24641
25854
|
fs7.writeFileSync(outputPath, fullHtml);
|
|
24642
25855
|
const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
|
|
24643
25856
|
logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
|
|
@@ -24646,7 +25859,7 @@ if (import.meta.hot) {
|
|
|
24646
25859
|
logger.error(` \u2717 ${page2.urlPath}: ${error}`);
|
|
24647
25860
|
}
|
|
24648
25861
|
}
|
|
24649
|
-
const manifestPath =
|
|
25862
|
+
const manifestPath = path27.join(outDir, "__ssg_manifest.json");
|
|
24650
25863
|
fs7.writeFileSync(
|
|
24651
25864
|
manifestPath,
|
|
24652
25865
|
JSON.stringify(
|
|
@@ -24682,9 +25895,9 @@ if (import.meta.hot) {
|
|
|
24682
25895
|
}
|
|
24683
25896
|
const currentFarmConfig = farmApp?.getConfig();
|
|
24684
25897
|
const normalizedFile = file.replace(/\\/g, "/");
|
|
24685
|
-
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) =>
|
|
25898
|
+
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path27.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
|
|
24686
25899
|
if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
|
|
24687
|
-
logUpdate("PAGE", `updated ${
|
|
25900
|
+
logUpdate("PAGE", `updated ${path27.basename(file)}`);
|
|
24688
25901
|
for (const mod of modules) {
|
|
24689
25902
|
server2.moduleGraph.invalidateModule(mod);
|
|
24690
25903
|
}
|
|
@@ -25075,6 +26288,7 @@ import React from 'react'
|
|
|
25075
26288
|
import { hydrateRoot, createRoot } from 'react-dom/client'
|
|
25076
26289
|
import { installChunkErrorRecovery, SPARouter } from '@farm.js/core/client'
|
|
25077
26290
|
import { createClientPluginManager } from '@farm.js/core/plugin/client'
|
|
26291
|
+
import { scheduleFarmIslandHydration } from '@farm.js/core/internal/client-runtime'
|
|
25078
26292
|
import { reviveDeferredData } from '@farm.js/core/deferred'
|
|
25079
26293
|
import {
|
|
25080
26294
|
createFarmDeploymentMismatchError,
|
|
@@ -25327,6 +26541,7 @@ class LegacyManifestSPARouter {
|
|
|
25327
26541
|
|
|
25328
26542
|
// Only prefetch routes that will hydrate on the client.
|
|
25329
26543
|
if (!match.route.isClientComponent && !match.route.shouldHydrate) return;
|
|
26544
|
+
if (match.route.islandStrategy && match.route.islandStrategy !== 'load') return;
|
|
25330
26545
|
|
|
25331
26546
|
const modulePath = match.route.modulePath;
|
|
25332
26547
|
if (this.moduleCache.has(modulePath)) return;
|
|
@@ -25471,6 +26686,12 @@ let hasClientTakenOver = false;
|
|
|
25471
26686
|
const routeSlotRoots = new Map();
|
|
25472
26687
|
const routeSlotDefinitions = new Map();
|
|
25473
26688
|
let activeRouteInterception = null;
|
|
26689
|
+
let pendingPageHydrationController = null;
|
|
26690
|
+
|
|
26691
|
+
function cancelPendingPageHydration() {
|
|
26692
|
+
pendingPageHydrationController?.abort();
|
|
26693
|
+
pendingPageHydrationController = null;
|
|
26694
|
+
}
|
|
25474
26695
|
|
|
25475
26696
|
function normalizeServerProps(rawProps) {
|
|
25476
26697
|
const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
|
|
@@ -25539,7 +26760,11 @@ async function hydrateInitialRouteSlots() {
|
|
|
25539
26760
|
routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
|
|
25540
26761
|
if (!slot.isClientComponent && !slot.shouldHydrate) continue;
|
|
25541
26762
|
try {
|
|
25542
|
-
|
|
26763
|
+
const slotHydrated = await renderRouteSlot(slot, 'hydrate');
|
|
26764
|
+
hydrated = slotHydrated || hydrated;
|
|
26765
|
+
if (slotHydrated) {
|
|
26766
|
+
replayPreHydrationClicks(document.getElementById(slot.containerId));
|
|
26767
|
+
}
|
|
25543
26768
|
} catch (error) {
|
|
25544
26769
|
console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
|
|
25545
26770
|
}
|
|
@@ -25610,16 +26835,29 @@ function applyCanonicalPathFromProps(props) {
|
|
|
25610
26835
|
window.history.replaceState({ ...(window.history.state || {}), path: canonicalPath }, '', canonicalPath);
|
|
25611
26836
|
}
|
|
25612
26837
|
|
|
25613
|
-
function replayPreHydrationClicks() {
|
|
25614
|
-
|
|
25615
|
-
|
|
26838
|
+
function replayPreHydrationClicks(container = null) {
|
|
26839
|
+
if (!container) {
|
|
26840
|
+
markFarmHydrated();
|
|
26841
|
+
} else {
|
|
26842
|
+
container.dataset.farmIslandHydrated = 'true';
|
|
26843
|
+
}
|
|
25616
26844
|
|
|
25617
26845
|
const queue = Array.isArray(window.__FARM_PREHYDRATION_CLICK_QUEUE__)
|
|
25618
26846
|
? window.__FARM_PREHYDRATION_CLICK_QUEUE__
|
|
25619
26847
|
: [];
|
|
25620
26848
|
if (queue.length === 0) return;
|
|
25621
26849
|
|
|
25622
|
-
const queuedClicks =
|
|
26850
|
+
const queuedClicks = [];
|
|
26851
|
+
const remainingClicks = [];
|
|
26852
|
+
for (const queuedClick of queue) {
|
|
26853
|
+
const target = queuedClick?.target;
|
|
26854
|
+
if (!container || (target instanceof Node && container.contains(target))) {
|
|
26855
|
+
queuedClicks.push(queuedClick);
|
|
26856
|
+
} else {
|
|
26857
|
+
remainingClicks.push(queuedClick);
|
|
26858
|
+
}
|
|
26859
|
+
}
|
|
26860
|
+
queue.splice(0, queue.length, ...remainingClicks);
|
|
25623
26861
|
for (const queuedClick of queuedClicks) {
|
|
25624
26862
|
const target = queuedClick?.target;
|
|
25625
26863
|
if (!target || typeof target.click !== 'function') continue;
|
|
@@ -25628,6 +26866,11 @@ function replayPreHydrationClicks() {
|
|
|
25628
26866
|
}
|
|
25629
26867
|
}
|
|
25630
26868
|
|
|
26869
|
+
function markFarmHydrated() {
|
|
26870
|
+
window.__FARM_HYDRATED__ = true;
|
|
26871
|
+
document.documentElement.dataset.farmHydrated = 'true';
|
|
26872
|
+
}
|
|
26873
|
+
|
|
25631
26874
|
async function buildClientHydrationElement(PageComponent, pageProps) {
|
|
25632
26875
|
let element = React.createElement(PageComponent, pageProps);
|
|
25633
26876
|
const loadingModulePath = window.__FARM_LOADING_MODULE__;
|
|
@@ -25770,9 +27013,10 @@ async function tryHydrateImportedPage(
|
|
|
25770
27013
|
layouts,
|
|
25771
27014
|
useHydrate = false,
|
|
25772
27015
|
existingProps = null,
|
|
27016
|
+
signal = null,
|
|
25773
27017
|
) {
|
|
25774
27018
|
const modulePath = route?.modulePath;
|
|
25775
|
-
if (!modulePath) {
|
|
27019
|
+
if (!modulePath || signal?.aborted) {
|
|
25776
27020
|
return false;
|
|
25777
27021
|
}
|
|
25778
27022
|
|
|
@@ -25781,6 +27025,7 @@ async function tryHydrateImportedPage(
|
|
|
25781
27025
|
pageModule = await import(/* @vite-ignore */ modulePath);
|
|
25782
27026
|
pageModuleCache.set(modulePath, pageModule);
|
|
25783
27027
|
}
|
|
27028
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25784
27029
|
|
|
25785
27030
|
const PageComponent = pageModule?.default;
|
|
25786
27031
|
if (!PageComponent) {
|
|
@@ -25795,6 +27040,7 @@ async function tryHydrateImportedPage(
|
|
|
25795
27040
|
window.location.pathname,
|
|
25796
27041
|
existingProps,
|
|
25797
27042
|
);
|
|
27043
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25798
27044
|
|
|
25799
27045
|
const wrappedElement = useHydrate && container?.id === '__farm_page__'
|
|
25800
27046
|
? wrapWithIntegrationProviders(
|
|
@@ -25805,6 +27051,7 @@ async function tryHydrateImportedPage(
|
|
|
25805
27051
|
currentPageProps,
|
|
25806
27052
|
layouts,
|
|
25807
27053
|
);
|
|
27054
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25808
27055
|
|
|
25809
27056
|
if (useHydrate) {
|
|
25810
27057
|
try {
|
|
@@ -25835,6 +27082,7 @@ async function tryHydrateImportedPage(
|
|
|
25835
27082
|
async function renderPage(pageData) {
|
|
25836
27083
|
const container = document.getElementById('root');
|
|
25837
27084
|
if (!container) return;
|
|
27085
|
+
cancelPendingPageHydration();
|
|
25838
27086
|
const destination = window.location.pathname + window.location.search;
|
|
25839
27087
|
|
|
25840
27088
|
if (pageData.interception) {
|
|
@@ -25851,6 +27099,7 @@ async function renderPage(pageData) {
|
|
|
25851
27099
|
modulePath: pageData.modulePath,
|
|
25852
27100
|
isClientComponent: pageData.isClientComponent === true,
|
|
25853
27101
|
shouldHydrate: pageData.shouldHydrate === true,
|
|
27102
|
+
islandStrategy: pageData.islandStrategy || 'load',
|
|
25854
27103
|
};
|
|
25855
27104
|
const params = pageData.props?.params || {};
|
|
25856
27105
|
const layouts = (pageData.layoutModules || []).map((modulePath, index) => ({
|
|
@@ -26050,14 +27299,6 @@ async function hydrate() {
|
|
|
26050
27299
|
}
|
|
26051
27300
|
|
|
26052
27301
|
try {
|
|
26053
|
-
// Pre-load layout for SPA navigation
|
|
26054
|
-
try {
|
|
26055
|
-
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
26056
|
-
LayoutComponent = layoutModule.default;
|
|
26057
|
-
} catch (e) {
|
|
26058
|
-
console.warn('[Farm.js] Could not preload layout:', e);
|
|
26059
|
-
}
|
|
26060
|
-
|
|
26061
27302
|
// Check if this is a client component (set by SSR)
|
|
26062
27303
|
const isClientComponent = window.__FARM_IS_CLIENT__ === true;
|
|
26063
27304
|
const modulePath = window.__FARM_PAGE_MODULE__;
|
|
@@ -26105,34 +27346,88 @@ async function hydrate() {
|
|
|
26105
27346
|
return
|
|
26106
27347
|
}
|
|
26107
27348
|
|
|
26108
|
-
const
|
|
26109
|
-
|
|
26110
|
-
|
|
26111
|
-
|
|
27349
|
+
const currentRoute = findRoute(window.location.pathname)?.route;
|
|
27350
|
+
const islandStrategy = window.__FARM_ISLAND_STRATEGY__ || currentRoute?.islandStrategy || 'load';
|
|
27351
|
+
pageContainer.dataset.farmIsland = 'page';
|
|
27352
|
+
pageContainer.dataset.farmIslandStrategy = islandStrategy;
|
|
26112
27353
|
|
|
26113
|
-
|
|
27354
|
+
const hydrationPathname = window.location.pathname;
|
|
27355
|
+
const hydrationController = new AbortController();
|
|
27356
|
+
pendingPageHydrationController = hydrationController;
|
|
26114
27357
|
try {
|
|
26115
|
-
|
|
26116
|
-
pageContainer,
|
|
26117
|
-
|
|
26118
|
-
|
|
26119
|
-
|
|
26120
|
-
|
|
26121
|
-
|
|
26122
|
-
|
|
26123
|
-
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
}
|
|
27358
|
+
await scheduleFarmIslandHydration({
|
|
27359
|
+
container: pageContainer,
|
|
27360
|
+
strategy: islandStrategy,
|
|
27361
|
+
signal: hydrationController.signal,
|
|
27362
|
+
hydrate: async () => {
|
|
27363
|
+
if (
|
|
27364
|
+
hydrationController.signal.aborted ||
|
|
27365
|
+
!pageContainer.isConnected ||
|
|
27366
|
+
window.location.pathname !== hydrationPathname
|
|
27367
|
+
) {
|
|
27368
|
+
return;
|
|
27369
|
+
}
|
|
26128
27370
|
|
|
26129
|
-
|
|
26130
|
-
|
|
26131
|
-
|
|
26132
|
-
|
|
26133
|
-
|
|
27371
|
+
// Layout code is only needed when this route boundary actually hydrates.
|
|
27372
|
+
try {
|
|
27373
|
+
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
27374
|
+
LayoutComponent = layoutModule.default;
|
|
27375
|
+
} catch (e) {
|
|
27376
|
+
console.warn('[Farm.js] Could not preload layout:', e);
|
|
27377
|
+
}
|
|
27378
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) return;
|
|
27379
|
+
|
|
27380
|
+
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
27381
|
+
container: pageContainer,
|
|
27382
|
+
mode: shouldHydrate ? 'hydrate' : 'render',
|
|
27383
|
+
});
|
|
27384
|
+
|
|
27385
|
+
let hydrated = false;
|
|
27386
|
+
try {
|
|
27387
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
27388
|
+
await farmClientRuntime.failHydration(
|
|
27389
|
+
hydrationSession,
|
|
27390
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
27391
|
+
);
|
|
27392
|
+
return;
|
|
27393
|
+
}
|
|
27394
|
+
hydrated = await tryHydrateImportedPage(
|
|
27395
|
+
pageContainer,
|
|
27396
|
+
{ modulePath },
|
|
27397
|
+
currentPageProps.params || {},
|
|
27398
|
+
layouts,
|
|
27399
|
+
shouldHydrate,
|
|
27400
|
+
currentPageProps,
|
|
27401
|
+
hydrationController.signal,
|
|
27402
|
+
);
|
|
27403
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
27404
|
+
await farmClientRuntime.failHydration(
|
|
27405
|
+
hydrationSession,
|
|
27406
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
27407
|
+
);
|
|
27408
|
+
return;
|
|
27409
|
+
}
|
|
27410
|
+
await farmClientRuntime.completeHydration(hydrationSession);
|
|
27411
|
+
} catch (error) {
|
|
27412
|
+
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
27413
|
+
throw error;
|
|
27414
|
+
}
|
|
26134
27415
|
|
|
26135
|
-
|
|
27416
|
+
if (hydrated) {
|
|
27417
|
+
// The scheduler owns queue draining and exactly-once click replay.
|
|
27418
|
+
markFarmHydrated();
|
|
27419
|
+
console.log('[Farm.js] \u2705 Hydrated:', modulePath, '(' + islandStrategy + ')');
|
|
27420
|
+
return;
|
|
27421
|
+
}
|
|
27422
|
+
|
|
27423
|
+
console.log('[Farm.js] Server component - SPA router ready')
|
|
27424
|
+
},
|
|
27425
|
+
});
|
|
27426
|
+
} finally {
|
|
27427
|
+
if (pendingPageHydrationController === hydrationController) {
|
|
27428
|
+
pendingPageHydrationController = null;
|
|
27429
|
+
}
|
|
27430
|
+
}
|
|
26136
27431
|
} catch (error) {
|
|
26137
27432
|
console.error('[Farm.js] Hydration error:', error)
|
|
26138
27433
|
}
|
|
@@ -26235,7 +27530,7 @@ function generateClientManifest(bundle) {
|
|
|
26235
27530
|
}
|
|
26236
27531
|
async function defineConfig2(config = {}) {
|
|
26237
27532
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
26238
|
-
const appRoot =
|
|
27533
|
+
const appRoot = path27.resolve(config.root || process.cwd());
|
|
26239
27534
|
if (config.extends?.length) {
|
|
26240
27535
|
const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
|
|
26241
27536
|
({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
|
|
@@ -26380,13 +27675,16 @@ async function defineConfig2(config = {}) {
|
|
|
26380
27675
|
customLogger: farmLogger,
|
|
26381
27676
|
clearScreen: false,
|
|
26382
27677
|
optimizeDeps: {
|
|
26383
|
-
|
|
26384
|
-
|
|
26385
|
-
|
|
26386
|
-
|
|
26387
|
-
|
|
26388
|
-
|
|
26389
|
-
|
|
27678
|
+
...createFarmClientOptimizeDepsConfig(
|
|
27679
|
+
createFarmClientOptimizeDepsEntries(
|
|
27680
|
+
appRoot,
|
|
27681
|
+
getFarmAppDirectories({ ...config, root: appRoot })
|
|
27682
|
+
)
|
|
27683
|
+
),
|
|
27684
|
+
// Pre-bundle every framework client-runtime entry with React. Without
|
|
27685
|
+
// this, Vite can discover a linked Farm entry after the page has loaded,
|
|
27686
|
+
// regenerate the optimizer browser hash, and leave React DOM holding a
|
|
27687
|
+
// different React module instance from a client component.
|
|
26390
27688
|
// Exclude server-side packages from browser bundling
|
|
26391
27689
|
exclude: [
|
|
26392
27690
|
"@farm.js/core/server",
|
|
@@ -26421,7 +27719,7 @@ async function defineConfig2(config = {}) {
|
|
|
26421
27719
|
// Stub out problematic server-only modules during dev mode
|
|
26422
27720
|
alias: {
|
|
26423
27721
|
...getFarmLayerAliases(config.layers),
|
|
26424
|
-
"@":
|
|
27722
|
+
"@": path27.resolve(appRoot, "src"),
|
|
26425
27723
|
// Nitro internals that should not be resolved in browser
|
|
26426
27724
|
"supports-color": "data:text/javascript,export default false; export const supportsColor = false; export const stdout = false; export const stderr = false;",
|
|
26427
27725
|
"@poppinss/dumper": "data:text/javascript,export default {};",
|
|
@@ -26438,7 +27736,7 @@ async function defineConfig2(config = {}) {
|
|
|
26438
27736
|
}
|
|
26439
27737
|
};
|
|
26440
27738
|
}
|
|
26441
|
-
var fs7,
|
|
27739
|
+
var fs7, path27, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES;
|
|
26442
27740
|
var init_vite = __esm({
|
|
26443
27741
|
"src/vite.ts"() {
|
|
26444
27742
|
"use strict";
|
|
@@ -26459,7 +27757,7 @@ var init_vite = __esm({
|
|
|
26459
27757
|
init_route_context();
|
|
26460
27758
|
init_devtools_config();
|
|
26461
27759
|
fs7 = __toESM(require("fs"));
|
|
26462
|
-
|
|
27760
|
+
path27 = __toESM(require("path"));
|
|
26463
27761
|
init_layers();
|
|
26464
27762
|
init_environment_vite();
|
|
26465
27763
|
init_version();
|
|
@@ -26469,9 +27767,12 @@ var init_vite = __esm({
|
|
|
26469
27767
|
init_image_config();
|
|
26470
27768
|
init_image_vite();
|
|
26471
27769
|
init_font_vite();
|
|
27770
|
+
init_font();
|
|
26472
27771
|
init_image_server();
|
|
26473
27772
|
init_server2();
|
|
26474
27773
|
init_routing();
|
|
27774
|
+
init_vite_config();
|
|
27775
|
+
init_fonts();
|
|
26475
27776
|
ALL_TYPE_ARTIFACTS = {
|
|
26476
27777
|
routes: true,
|
|
26477
27778
|
api: true,
|
|
@@ -27865,6 +29166,7 @@ init_layers();
|
|
|
27865
29166
|
init_environment_vite();
|
|
27866
29167
|
init_last_modified();
|
|
27867
29168
|
init_search_client();
|
|
29169
|
+
init_fonts();
|
|
27868
29170
|
|
|
27869
29171
|
// src/route-runtime-manifest.ts
|
|
27870
29172
|
var import_path8 = __toESM(require("path"));
|
|
@@ -28046,7 +29348,7 @@ function farmRoutePatternToVercelSource(pattern) {
|
|
|
28046
29348
|
} else if (segment === "*" || /^\[.+\]$/.test(segment)) {
|
|
28047
29349
|
source += "/([^/]+)";
|
|
28048
29350
|
} else {
|
|
28049
|
-
source += `/${
|
|
29351
|
+
source += `/${escapeRegExp3(segment)}`;
|
|
28050
29352
|
}
|
|
28051
29353
|
}
|
|
28052
29354
|
return source || "/";
|
|
@@ -28091,10 +29393,35 @@ function normalizePattern(value) {
|
|
|
28091
29393
|
return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
|
|
28092
29394
|
}
|
|
28093
29395
|
__name(normalizePattern, "normalizePattern");
|
|
28094
|
-
function
|
|
29396
|
+
function escapeRegExp3(value) {
|
|
29397
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
29398
|
+
}
|
|
29399
|
+
__name(escapeRegExp3, "escapeRegExp");
|
|
29400
|
+
|
|
29401
|
+
// src/nitro/vercel-assets.ts
|
|
29402
|
+
var FARM_IMMUTABLE_ASSET_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
29403
|
+
function createFarmVercelImmutableAssetRoute(basePath = "/") {
|
|
29404
|
+
const normalizedBasePath = normalizeBasePath3(basePath);
|
|
29405
|
+
const escapedBasePath = escapeRegex(normalizedBasePath);
|
|
29406
|
+
const prefix = escapedBasePath ? `/${escapedBasePath}` : "";
|
|
29407
|
+
return {
|
|
29408
|
+
src: `^${prefix}/(?:assets|chunks)/(?:.+/)*[^/]+-h(?:[a-fA-F0-9]{8}|[a-fA-F0-9]{12}|[a-fA-F0-9]{16})\\.(?!(?:[hH][tT][mM][lL]?)$)[^/]+$`,
|
|
29409
|
+
headers: {
|
|
29410
|
+
"Cache-Control": FARM_IMMUTABLE_ASSET_CACHE_CONTROL
|
|
29411
|
+
},
|
|
29412
|
+
continue: true,
|
|
29413
|
+
caseSensitive: true
|
|
29414
|
+
};
|
|
29415
|
+
}
|
|
29416
|
+
__name(createFarmVercelImmutableAssetRoute, "createFarmVercelImmutableAssetRoute");
|
|
29417
|
+
function normalizeBasePath3(basePath) {
|
|
29418
|
+
return basePath.trim().replace(/^\/+|\/+$/g, "");
|
|
29419
|
+
}
|
|
29420
|
+
__name(normalizeBasePath3, "normalizeBasePath");
|
|
29421
|
+
function escapeRegex(value) {
|
|
28095
29422
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28096
29423
|
}
|
|
28097
|
-
__name(
|
|
29424
|
+
__name(escapeRegex, "escapeRegex");
|
|
28098
29425
|
|
|
28099
29426
|
// src/nitro/universal-build.ts
|
|
28100
29427
|
init_catalog();
|
|
@@ -28303,6 +29630,10 @@ function isCloudflareImagePreset(preset) {
|
|
|
28303
29630
|
return preset === "cloudflare" || preset === "cloudflare-pages" || preset === "cloudflare-module";
|
|
28304
29631
|
}
|
|
28305
29632
|
__name(isCloudflareImagePreset, "isCloudflareImagePreset");
|
|
29633
|
+
function shouldUseExternalMetadataImageRuntime(preset, hasGeneratedMetadataImages) {
|
|
29634
|
+
return hasGeneratedMetadataImages && preset !== "vercel-edge" && !isCloudflareImagePreset(preset);
|
|
29635
|
+
}
|
|
29636
|
+
__name(shouldUseExternalMetadataImageRuntime, "shouldUseExternalMetadataImageRuntime");
|
|
28306
29637
|
function resolveImageRuntime(config, preset) {
|
|
28307
29638
|
if (config.images.provider === "none") return "none";
|
|
28308
29639
|
const cloudflarePreset = isCloudflareImagePreset(preset);
|
|
@@ -28320,6 +29651,31 @@ function isNitroRollupExternal(id) {
|
|
|
28320
29651
|
return NODE_BUILTIN_MODULES.has(id) || NITRO_EXTERNAL_MODULES.has(id) || normalizedId.startsWith(".prisma/") || normalizedId.includes("/node_modules/@prisma/client/") || normalizedId.includes("/node_modules/.prisma/client/");
|
|
28321
29652
|
}
|
|
28322
29653
|
__name(isNitroRollupExternal, "isNitroRollupExternal");
|
|
29654
|
+
var FARM_METADATA_IMAGE_WASM_PREFIX = "\0farm-metadata-image-wasm:";
|
|
29655
|
+
function createMetadataImageWasmPlugin() {
|
|
29656
|
+
return {
|
|
29657
|
+
name: "farm-metadata-image-wasm",
|
|
29658
|
+
resolveId(source, importer) {
|
|
29659
|
+
if (!source.endsWith(".wasm?module") || !importer?.replace(/\\/g, "/").includes("/@vercel/og/")) {
|
|
29660
|
+
return null;
|
|
29661
|
+
}
|
|
29662
|
+
const requestPath = source.slice(0, -"?module".length);
|
|
29663
|
+
const resolvedPath = import_path12.default.isAbsolute(requestPath) ? requestPath : import_path12.default.resolve(import_path12.default.dirname(importer.split("?", 1)[0]), requestPath);
|
|
29664
|
+
return `${FARM_METADATA_IMAGE_WASM_PREFIX}${resolvedPath}`;
|
|
29665
|
+
},
|
|
29666
|
+
load(id) {
|
|
29667
|
+
if (!id.startsWith(FARM_METADATA_IMAGE_WASM_PREFIX)) return null;
|
|
29668
|
+
const wasmPath = id.slice(FARM_METADATA_IMAGE_WASM_PREFIX.length);
|
|
29669
|
+
const encoded = (0, import_fs5.readFileSync)(wasmPath).toString("base64");
|
|
29670
|
+
return `
|
|
29671
|
+
const encoded = ${JSON.stringify(encoded)};
|
|
29672
|
+
const bytes = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));
|
|
29673
|
+
export default new WebAssembly.Module(bytes);
|
|
29674
|
+
`;
|
|
29675
|
+
}
|
|
29676
|
+
};
|
|
29677
|
+
}
|
|
29678
|
+
__name(createMetadataImageWasmPlugin, "createMetadataImageWasmPlugin");
|
|
28323
29679
|
function collectSSRExternalPackages(ssrBundle) {
|
|
28324
29680
|
const emittedFiles = new Set(
|
|
28325
29681
|
Object.keys(ssrBundle).map((fileName) => fileName.replace(/^\.\//, ""))
|
|
@@ -28703,6 +30059,9 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
28703
30059
|
}
|
|
28704
30060
|
const { bundle: ssrBundle, entryFile: ssrEntryFile, configuredHeaderRoutes } = ssrResult;
|
|
28705
30061
|
await writeSSRAssetsToClient(ssrBundle, clientOutputDir);
|
|
30062
|
+
if (config.docs.enabled) {
|
|
30063
|
+
await copyFarmDocsFontAssetsToClient(root, clientOutputDir);
|
|
30064
|
+
}
|
|
28706
30065
|
logger.info(`\u{1F680} Building server with Nitro (preset: ${preset})...`);
|
|
28707
30066
|
await buildNitroUniversal(
|
|
28708
30067
|
config,
|
|
@@ -28757,6 +30116,17 @@ async function writeSSRAssetsToClient(bundle, outputDir) {
|
|
|
28757
30116
|
}
|
|
28758
30117
|
}
|
|
28759
30118
|
__name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
|
|
30119
|
+
async function copyFarmDocsFontAssetsToClient(root, outputDir) {
|
|
30120
|
+
const fs8 = await import("fs/promises");
|
|
30121
|
+
await Promise.all(
|
|
30122
|
+
resolveFarmDocsFontAssets(root).map(async ({ sourcePath, url }) => {
|
|
30123
|
+
const targetPath = import_path12.default.join(outputDir, url.replace(/^\/+/, ""));
|
|
30124
|
+
await fs8.mkdir(import_path12.default.dirname(targetPath), { recursive: true });
|
|
30125
|
+
await fs8.copyFile(sourcePath, targetPath);
|
|
30126
|
+
})
|
|
30127
|
+
);
|
|
30128
|
+
}
|
|
30129
|
+
__name(copyFarmDocsFontAssetsToClient, "copyFarmDocsFontAssetsToClient");
|
|
28760
30130
|
async function mergeBuiltFontCss(outputDir, fontCssSource) {
|
|
28761
30131
|
const fs8 = await import("fs/promises");
|
|
28762
30132
|
const fontCssPath = import_path12.default.join(outputDir, "farm-fonts.css");
|
|
@@ -28775,11 +30145,8 @@ async function mergeBuiltFontCss(outputDir, fontCssSource) {
|
|
|
28775
30145
|
} catch {
|
|
28776
30146
|
}
|
|
28777
30147
|
const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
|
|
30148
|
+
await fs8.writeFile(fontCssPath, normalizedFontCss);
|
|
28778
30149
|
await fs8.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
|
|
28779
|
-
try {
|
|
28780
|
-
await fs8.rm(fontCssPath, { force: true });
|
|
28781
|
-
} catch {
|
|
28782
|
-
}
|
|
28783
30150
|
}
|
|
28784
30151
|
__name(mergeBuiltFontCss, "mergeBuiltFontCss");
|
|
28785
30152
|
var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
|
|
@@ -28844,7 +30211,11 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
28844
30211
|
const metadata = getClientModuleMetadata(route.modulePath, root);
|
|
28845
30212
|
if (metadata.shouldHydrate) {
|
|
28846
30213
|
const relativePath2 = route.modulePath.replace(root, "").replace(/^\//, "");
|
|
28847
|
-
clientPages.push({
|
|
30214
|
+
clientPages.push({
|
|
30215
|
+
...route,
|
|
30216
|
+
relativePath: relativePath2,
|
|
30217
|
+
islandStrategy: metadata.islandStrategy ?? "load"
|
|
30218
|
+
});
|
|
28848
30219
|
logger.info(`\u{1F4F1} Found hydratable route: ${route.pattern} -> ${route.modulePath}`);
|
|
28849
30220
|
}
|
|
28850
30221
|
} catch (error) {
|
|
@@ -28918,13 +30289,14 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
28918
30289
|
},
|
|
28919
30290
|
output: {
|
|
28920
30291
|
entryFileNames: "[name].js",
|
|
28921
|
-
chunkFileNames: "chunks/[name]-[hash].js",
|
|
30292
|
+
chunkFileNames: "chunks/[name]-h[hash].js",
|
|
30293
|
+
hashCharacters: "hex",
|
|
28922
30294
|
// Use predictable name for CSS so we can reference it in SSR HTML
|
|
28923
30295
|
assetFileNames: /* @__PURE__ */ __name((assetInfo) => {
|
|
28924
30296
|
if (assetInfo.name?.endsWith(".css")) {
|
|
28925
30297
|
return "farm-client.css";
|
|
28926
30298
|
}
|
|
28927
|
-
return "assets/[name]-[hash][extname]";
|
|
30299
|
+
return "assets/[name]-h[hash][extname]";
|
|
28928
30300
|
}, "assetFileNames")
|
|
28929
30301
|
},
|
|
28930
30302
|
// Externalize Node.js built-ins and server-side modules for client build
|
|
@@ -29523,10 +30895,13 @@ document.addEventListener("click", function(e) {
|
|
|
29523
30895
|
const imports = [];
|
|
29524
30896
|
const routeEntries = [];
|
|
29525
30897
|
const routeSlotEntries = [];
|
|
29526
|
-
clientPages.forEach((page2
|
|
30898
|
+
clientPages.forEach((page2) => {
|
|
29527
30899
|
const importPath = toImportPath(page2.modulePath);
|
|
29528
|
-
|
|
29529
|
-
|
|
30900
|
+
routeEntries.push(` {
|
|
30901
|
+
pattern: ${JSON.stringify(page2.pattern)},
|
|
30902
|
+
islandStrategy: ${JSON.stringify(page2.islandStrategy)},
|
|
30903
|
+
load: () => import(${JSON.stringify(importPath)}).then((module) => module.default),
|
|
30904
|
+
}`);
|
|
29530
30905
|
});
|
|
29531
30906
|
clientRouteSlots.forEach((slot, index) => {
|
|
29532
30907
|
const importPath = toImportPath(slot.modulePath);
|
|
@@ -29547,7 +30922,7 @@ ${cssImport}
|
|
|
29547
30922
|
${layoutImports}
|
|
29548
30923
|
import React from "react";
|
|
29549
30924
|
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
29550
|
-
import { createClientPluginManager, installChunkErrorRecovery } from "@farm.js/core/internal/client-runtime";
|
|
30925
|
+
import { createClientPluginManager, installChunkErrorRecovery, scheduleFarmIslandHydration } from "@farm.js/core/internal/client-runtime";
|
|
29551
30926
|
import { matchFarmRoute } from "@farm.js/core/router";
|
|
29552
30927
|
${clientPluginEntry.imports}
|
|
29553
30928
|
${i18nClientRuntime}
|
|
@@ -29620,6 +30995,12 @@ function matchRoute(pathname) {
|
|
|
29620
30995
|
return null;
|
|
29621
30996
|
}
|
|
29622
30997
|
|
|
30998
|
+
async function loadRouteComponent(route) {
|
|
30999
|
+
if (route.Component) return route.Component;
|
|
31000
|
+
route.Component = await route.load();
|
|
31001
|
+
return route.Component;
|
|
31002
|
+
}
|
|
31003
|
+
|
|
29623
31004
|
function matchesRoutePrefix(pathname, pattern) {
|
|
29624
31005
|
if (pattern === "/") return true;
|
|
29625
31006
|
const pathSegments = getFarmRoutePathname(pathname).split("/").filter(Boolean);
|
|
@@ -29762,15 +31143,24 @@ function clearRouteInterception(destination) {
|
|
|
29762
31143
|
|
|
29763
31144
|
// State
|
|
29764
31145
|
let reactRoot = null;
|
|
31146
|
+
let reactRootContainer = null;
|
|
29765
31147
|
let currentPathname = null;
|
|
29766
31148
|
let isHydrated = false;
|
|
31149
|
+
let pendingPageHydrationController = null;
|
|
29767
31150
|
|
|
29768
31151
|
${generateUniversalRouterStateRuntime()}
|
|
29769
31152
|
|
|
31153
|
+
function cancelPendingPageHydration() {
|
|
31154
|
+
pendingPageHydrationController?.abort();
|
|
31155
|
+
pendingPageHydrationController = null;
|
|
31156
|
+
}
|
|
31157
|
+
|
|
29770
31158
|
function resetReactRoot() {
|
|
31159
|
+
cancelPendingPageHydration();
|
|
29771
31160
|
if (!reactRoot) return;
|
|
29772
31161
|
reactRoot.unmount();
|
|
29773
31162
|
reactRoot = null;
|
|
31163
|
+
reactRootContainer = null;
|
|
29774
31164
|
isHydrated = false;
|
|
29775
31165
|
}
|
|
29776
31166
|
|
|
@@ -29784,49 +31174,77 @@ async function hydrate() {
|
|
|
29784
31174
|
return;
|
|
29785
31175
|
}
|
|
29786
31176
|
|
|
29787
|
-
const hasRouteSlots =
|
|
29788
|
-
Array.isArray(window.__FARM_ROUTE_SLOTS__) && window.__FARM_ROUTE_SLOTS__.length > 0;
|
|
29789
31177
|
const container =
|
|
29790
|
-
|
|
31178
|
+
document.getElementById("__farm_page__") ||
|
|
29791
31179
|
document.getElementById("root");
|
|
29792
31180
|
if (!container) {
|
|
29793
31181
|
console.error("[Farm.js] No root element found");
|
|
29794
31182
|
return;
|
|
29795
31183
|
}
|
|
29796
31184
|
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
const searchParams = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
29800
|
-
|
|
29801
|
-
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
29802
|
-
|
|
29803
|
-
// Create page element and wrap with layouts
|
|
29804
|
-
const pageElement = React.createElement(Component, props);
|
|
29805
|
-
const wrappedElement = hasRouteSlots
|
|
29806
|
-
? pageElement
|
|
29807
|
-
: wrapWithLayouts(pageElement, pathname, params);
|
|
29808
|
-
|
|
29809
|
-
const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
|
|
29810
|
-
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
29811
|
-
container,
|
|
29812
|
-
mode: shouldHydrate ? "hydrate" : "render",
|
|
29813
|
-
});
|
|
31185
|
+
container.dataset.farmIsland = "page";
|
|
31186
|
+
container.dataset.farmIslandStrategy = matched.route.islandStrategy || "load";
|
|
29814
31187
|
|
|
31188
|
+
const hydrationController = new AbortController();
|
|
31189
|
+
pendingPageHydrationController = hydrationController;
|
|
29815
31190
|
try {
|
|
29816
|
-
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29821
|
-
|
|
29822
|
-
|
|
29823
|
-
|
|
31191
|
+
await scheduleFarmIslandHydration({
|
|
31192
|
+
container,
|
|
31193
|
+
strategy: matched.route.islandStrategy,
|
|
31194
|
+
signal: hydrationController.signal,
|
|
31195
|
+
hydrate: async function() {
|
|
31196
|
+
const Component = await loadRouteComponent(matched.route);
|
|
31197
|
+
if (
|
|
31198
|
+
hydrationController.signal.aborted ||
|
|
31199
|
+
!container.isConnected ||
|
|
31200
|
+
window.location.pathname !== pathname
|
|
31201
|
+
) {
|
|
31202
|
+
return;
|
|
31203
|
+
}
|
|
31204
|
+
const params = matched.params;
|
|
31205
|
+
const searchParams = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
31206
|
+
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
31207
|
+
const pageElement = React.createElement(Component, props);
|
|
31208
|
+
const wrappedElement = container.id === "__farm_page__"
|
|
31209
|
+
? pageElement
|
|
31210
|
+
: wrapWithLayouts(pageElement, pathname, params);
|
|
31211
|
+
const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
|
|
31212
|
+
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
31213
|
+
container,
|
|
31214
|
+
mode: shouldHydrate ? "hydrate" : "render",
|
|
31215
|
+
});
|
|
31216
|
+
|
|
31217
|
+
try {
|
|
31218
|
+
if (hydrationController.signal.aborted || !container.isConnected) {
|
|
31219
|
+
await farmClientRuntime.failHydration(
|
|
31220
|
+
hydrationSession,
|
|
31221
|
+
new DOMException("Route hydration was cancelled", "AbortError"),
|
|
31222
|
+
);
|
|
31223
|
+
return;
|
|
31224
|
+
}
|
|
31225
|
+
if (shouldHydrate) {
|
|
31226
|
+
reactRoot = hydrateRoot(container, wrappedElement);
|
|
31227
|
+
reactRootContainer = container;
|
|
31228
|
+
isHydrated = true;
|
|
31229
|
+
} else {
|
|
31230
|
+
if (!reactRoot) {
|
|
31231
|
+
reactRoot = createRoot(container);
|
|
31232
|
+
reactRootContainer = container;
|
|
31233
|
+
}
|
|
31234
|
+
reactRoot.render(wrappedElement);
|
|
31235
|
+
}
|
|
31236
|
+
currentPathname = pathname;
|
|
31237
|
+
await farmClientRuntime.completeHydration(hydrationSession);
|
|
31238
|
+
} catch (error) {
|
|
31239
|
+
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
31240
|
+
console.error("[Farm.js] Hydration error:", error);
|
|
31241
|
+
}
|
|
31242
|
+
},
|
|
31243
|
+
});
|
|
31244
|
+
} finally {
|
|
31245
|
+
if (pendingPageHydrationController === hydrationController) {
|
|
31246
|
+
pendingPageHydrationController = null;
|
|
29824
31247
|
}
|
|
29825
|
-
currentPathname = pathname;
|
|
29826
|
-
await farmClientRuntime.completeHydration(hydrationSession);
|
|
29827
|
-
} catch (error) {
|
|
29828
|
-
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
29829
|
-
console.error("[Farm.js] Hydration error:", error);
|
|
29830
31248
|
}
|
|
29831
31249
|
}
|
|
29832
31250
|
|
|
@@ -29855,6 +31273,8 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29855
31273
|
const from = this.currentPath;
|
|
29856
31274
|
if (await this.shouldBlockNavigation({ from, to, action })) return;
|
|
29857
31275
|
|
|
31276
|
+
// A route transition invalidates any trigger waiting on the previous DOM boundary.
|
|
31277
|
+
cancelPendingPageHydration();
|
|
29858
31278
|
this.saveScrollPosition(window.location.pathname);
|
|
29859
31279
|
this.startNavigation(from, url, action);
|
|
29860
31280
|
let clientNavigation;
|
|
@@ -29921,7 +31341,9 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29921
31341
|
}
|
|
29922
31342
|
|
|
29923
31343
|
if (matched) {
|
|
29924
|
-
|
|
31344
|
+
// Navigation itself signals intent, so destination routes load eagerly even
|
|
31345
|
+
// when their initial document hydration strategy is deferred.
|
|
31346
|
+
const Component = await loadRouteComponent(matched.route);
|
|
29925
31347
|
const params = matched.params;
|
|
29926
31348
|
const searchParams = Object.fromEntries(url.searchParams);
|
|
29927
31349
|
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
@@ -29947,8 +31369,10 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29947
31369
|
|
|
29948
31370
|
const container = document.getElementById("root");
|
|
29949
31371
|
if (container) {
|
|
31372
|
+
if (reactRoot && reactRootContainer !== container) resetReactRoot();
|
|
29950
31373
|
if (!reactRoot) {
|
|
29951
31374
|
reactRoot = createRoot(container);
|
|
31375
|
+
reactRootContainer = container;
|
|
29952
31376
|
}
|
|
29953
31377
|
reactRoot.render(wrappedElement);
|
|
29954
31378
|
currentPathname = pathname;
|
|
@@ -29958,7 +31382,7 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29958
31382
|
const html = await this.fetchPage(url.pathname + url.search);
|
|
29959
31383
|
await farmClientRuntime.markNavigationLoaded(clientNavigation, html);
|
|
29960
31384
|
await this.runViewTransition(options.viewTransition, async () => {
|
|
29961
|
-
if (!this.swapContent(html, url.pathname + url.search)) {
|
|
31385
|
+
if (!(await this.swapContent(html, url.pathname + url.search))) {
|
|
29962
31386
|
throw new Error("Farm could not swap the target document");
|
|
29963
31387
|
}
|
|
29964
31388
|
const historyState = createHistoryState(
|
|
@@ -30013,7 +31437,7 @@ ${generateUniversalRouterStateProperties()}
|
|
|
30013
31437
|
return html;
|
|
30014
31438
|
},
|
|
30015
31439
|
|
|
30016
|
-
swapContent: function(html, targetPath) {
|
|
31440
|
+
swapContent: async function(html, targetPath) {
|
|
30017
31441
|
const parser = new DOMParser();
|
|
30018
31442
|
const doc = parser.parseFromString(html, "text/html");
|
|
30019
31443
|
if (isFarmLocaleDocumentChange(doc)) return false;
|
|
@@ -30053,18 +31477,18 @@ ${generateUniversalRouterStateProperties()}
|
|
|
30053
31477
|
const matched = matchRoute(newPathname);
|
|
30054
31478
|
if (matched) {
|
|
30055
31479
|
// Re-hydrate the client component
|
|
30056
|
-
const Component = matched.route
|
|
31480
|
+
const Component = await loadRouteComponent(matched.route);
|
|
30057
31481
|
const params = matched.params;
|
|
30058
31482
|
const searchParams = Object.fromEntries(targetUrl.searchParams);
|
|
30059
31483
|
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
30060
31484
|
const pageElement = React.createElement(Component, props);
|
|
30061
|
-
const hasRouteSlots = nextRouteSlots.length > 0;
|
|
30062
31485
|
const pageContainer =
|
|
30063
|
-
|
|
30064
|
-
const wrappedElement =
|
|
31486
|
+
document.getElementById("__farm_page__") || currentRoot;
|
|
31487
|
+
const wrappedElement = pageContainer.id === "__farm_page__"
|
|
30065
31488
|
? pageElement
|
|
30066
31489
|
: wrapWithLayouts(pageElement, newPathname, params);
|
|
30067
31490
|
reactRoot = hydrateRoot(pageContainer, wrappedElement);
|
|
31491
|
+
reactRootContainer = pageContainer;
|
|
30068
31492
|
isHydrated = true;
|
|
30069
31493
|
}
|
|
30070
31494
|
return true;
|
|
@@ -30355,6 +31779,10 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30355
31779
|
i18nCatalogs
|
|
30356
31780
|
);
|
|
30357
31781
|
const virtualEntryId = "\0virtual:farm-ssr-entry";
|
|
31782
|
+
const useExternalMetadataImageRuntime = shouldUseExternalMetadataImageRuntime(
|
|
31783
|
+
preset,
|
|
31784
|
+
metadataImageRoutes.some((image) => image.sourceType === "module")
|
|
31785
|
+
);
|
|
30358
31786
|
try {
|
|
30359
31787
|
await viteBuild({
|
|
30360
31788
|
root,
|
|
@@ -30375,6 +31803,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30375
31803
|
external: [
|
|
30376
31804
|
"fsevents",
|
|
30377
31805
|
"sharp",
|
|
31806
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : [],
|
|
30378
31807
|
"@prisma/client",
|
|
30379
31808
|
"@prisma/client/default",
|
|
30380
31809
|
"@prisma/client/default.js",
|
|
@@ -30403,6 +31832,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30403
31832
|
external: [
|
|
30404
31833
|
"fsevents",
|
|
30405
31834
|
"sharp",
|
|
31835
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : [],
|
|
30406
31836
|
"esbuild",
|
|
30407
31837
|
"lightningcss",
|
|
30408
31838
|
"rollup",
|
|
@@ -30429,7 +31859,12 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30429
31859
|
// React runtime. Leaving a React component package external can make it
|
|
30430
31860
|
// resolve a second React instance at runtime and break hooks during SSR.
|
|
30431
31861
|
// Native and build-only packages above remain explicitly external.
|
|
30432
|
-
noExternal: preset === "cloudflare-module" ? [
|
|
31862
|
+
noExternal: preset === "cloudflare-module" ? [
|
|
31863
|
+
"@farm.js/core",
|
|
31864
|
+
"@farm.js/core/image",
|
|
31865
|
+
"better-call",
|
|
31866
|
+
...metadataImageRoutes.some((image) => image.sourceType === "module") ? ["@vercel/og"] : []
|
|
31867
|
+
] : true
|
|
30433
31868
|
},
|
|
30434
31869
|
define: {
|
|
30435
31870
|
__FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
|
|
@@ -30437,6 +31872,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30437
31872
|
},
|
|
30438
31873
|
plugins: [
|
|
30439
31874
|
...tailwindVitePlugin ? [tailwindVitePlugin] : [],
|
|
31875
|
+
...!useExternalMetadataImageRuntime && metadataImageRoutes.some((image) => image.sourceType === "module") ? [createMetadataImageWasmPlugin()] : [],
|
|
30440
31876
|
{
|
|
30441
31877
|
name: "farm-react-production-mode",
|
|
30442
31878
|
enforce: "pre",
|
|
@@ -30515,8 +31951,12 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30515
31951
|
__name(buildSSRInMemory, "buildSSRInMemory");
|
|
30516
31952
|
function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlots, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
|
|
30517
31953
|
const hasPluginRuntime = hasRuntimeIntegrationConfig || hasConfiguredRuntimePlugins;
|
|
31954
|
+
const hasGeneratedMetadataImages = metadataImageRoutes.some(
|
|
31955
|
+
(image) => image.sourceType === "module"
|
|
31956
|
+
);
|
|
30518
31957
|
const hasMiddlewareRuntime = middlewareRoutes.length > 0 || hasFarmMiddlewareConfig(config.middleware);
|
|
30519
31958
|
const farmDocsBaseConfig = config.docs?.enabled ? { ...config.docs, config: void 0 } : void 0;
|
|
31959
|
+
const farmDocsFontAssets = config.docs?.enabled ? toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(config.root)) : [];
|
|
30520
31960
|
const apiImports = [];
|
|
30521
31961
|
const apiRegistrations = [];
|
|
30522
31962
|
apiRoutes.forEach((route, index) => {
|
|
@@ -30555,12 +31995,13 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
|
|
|
30555
31995
|
return;
|
|
30556
31996
|
}
|
|
30557
31997
|
pageImports.push(`import * as ${varName} from "${route.modulePath}";`);
|
|
30558
|
-
const
|
|
31998
|
+
const clientMetadata = getClientModuleMetadata(route.modulePath, config.root);
|
|
30559
31999
|
pageRegistrations.push(`
|
|
30560
32000
|
{
|
|
30561
32001
|
pattern: ${JSON.stringify(route.pattern)},
|
|
30562
32002
|
module: ${varName},
|
|
30563
|
-
shouldHydrate: ${JSON.stringify(shouldHydrate)},
|
|
32003
|
+
shouldHydrate: ${JSON.stringify(clientMetadata.shouldHydrate)},
|
|
32004
|
+
islandStrategy: ${JSON.stringify(clientMetadata.islandStrategy)},
|
|
30564
32005
|
${route.source !== void 0 ? `markdownSource: {
|
|
30565
32006
|
source: ${JSON.stringify(route.source)},
|
|
30566
32007
|
filePath: ${JSON.stringify(route.markdownSourcePath)},
|
|
@@ -30658,16 +32099,21 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
|
|
|
30658
32099
|
isFarmRedirectError,
|
|
30659
32100
|
localizeFarmHref,
|
|
30660
32101
|
localizeFarmPathname,
|
|
32102
|
+
manageFarmDocumentPreloads,
|
|
32103
|
+
manageFarmLinkHeaderPreloads,
|
|
30661
32104
|
mergeMetadata,
|
|
30662
32105
|
normalizeRevalidatePath,
|
|
32106
|
+
reportFarmPreloadWarnings,
|
|
30663
32107
|
renderMetadataHead,
|
|
30664
32108
|
resolveFarmRouteContext,
|
|
30665
32109
|
stripFarmLocaleFromPathname,
|
|
30666
32110
|
withFarmRouteContext,
|
|
30667
32111
|
} from "@farm.js/core/internal/production-runtime";`;
|
|
32112
|
+
const metadataImageRuntimeImport = hasGeneratedMetadataImages ? `import { createFarmMetadataImageResponse } from "@farm.js/core/internal/metadata-image-runtime";` : "";
|
|
30668
32113
|
const pluginRuntimeImport = hasPluginRuntime ? `import { PluginManager } from "@farm.js/core/plugin";` : "";
|
|
30669
32114
|
const i18nServerImport = config.i18n.enabled ? `import { _runWithFarmI18nRequest, _setDefaultFarmI18nRuntime, createFarmI18nRuntime, getFarmI18nClientSnapshot } from "@farm.js/core/i18n/server";` : "";
|
|
30670
32115
|
const docsHandlerImport = config.docs?.enabled ? `import { createFarmDocsAPIHandler, createFarmDocsHandler, isFarmDocsAPIRequest } from "@farm.js/core/docs";` : "";
|
|
32116
|
+
const docsFontImport = config.docs?.enabled ? `import { resolveFarmLayoutFonts } from "@farm.js/core/font";` : "";
|
|
30671
32117
|
const docsRuntimeImport = config.docs?.enabled ? `import { existsSync as farmDocsExistsSync } from "node:fs";
|
|
30672
32118
|
import { dirname as farmDocsDirname, join as farmDocsJoin } from "node:path";
|
|
30673
32119
|
import { fileURLToPath as farmDocsFileURLToPath } from "node:url";` : "";
|
|
@@ -30755,9 +32201,11 @@ ${middlewareImports.join("\n")}
|
|
|
30755
32201
|
${notFoundImport}
|
|
30756
32202
|
${apiRouteHelpersImport}
|
|
30757
32203
|
${productionRuntimeImport}
|
|
32204
|
+
${metadataImageRuntimeImport}
|
|
30758
32205
|
${pluginRuntimeImport}
|
|
30759
32206
|
${i18nServerImport}
|
|
30760
32207
|
${docsHandlerImport}
|
|
32208
|
+
${docsFontImport}
|
|
30761
32209
|
${docsRuntimeImport}
|
|
30762
32210
|
${markdownHandlerImport}
|
|
30763
32211
|
${appMarkdownImport}
|
|
@@ -30769,6 +32217,8 @@ import { farmFontPreloadHeader } from "virtual:farm-font-runtime";
|
|
|
30769
32217
|
import * as React from "react";
|
|
30770
32218
|
import * as ReactDOMServer from "react-dom/server";
|
|
30771
32219
|
|
|
32220
|
+
const farmPreloadConfig = ${JSON.stringify(config.performance.preload)};
|
|
32221
|
+
|
|
30772
32222
|
// Custom 404 page component (if provided)
|
|
30773
32223
|
const hasCustomNotFound = ${notFoundPath ? "true" : "false"};
|
|
30774
32224
|
const CustomNotFoundComponent = ${notFoundPath ? "CustomNotFound.default || CustomNotFound" : "null"};
|
|
@@ -30860,7 +32310,17 @@ globalThis.__FARM_DOCS_RUNTIME_CONFIG__ = {
|
|
|
30860
32310
|
srcDir: ${JSON.stringify(config.srcDir)},
|
|
30861
32311
|
docs: farmDocsResolvedConfig,
|
|
30862
32312
|
};
|
|
30863
|
-
const farmDocsHandler = ${config.docs?.enabled ? `createFarmDocsHandler(farmDocsResolvedConfig, {
|
|
32313
|
+
const farmDocsHandler = ${config.docs?.enabled ? `createFarmDocsHandler(farmDocsResolvedConfig, {
|
|
32314
|
+
root: farmDocsRuntimeRoot,
|
|
32315
|
+
srcDir: ${JSON.stringify(config.srcDir)},
|
|
32316
|
+
clientEntry: "/farm-client.js",
|
|
32317
|
+
fontAssets: ${JSON.stringify(farmDocsFontAssets)},
|
|
32318
|
+
resolveLayoutFonts: (pathname) =>
|
|
32319
|
+
resolveFarmLayoutFonts(
|
|
32320
|
+
getApplicableLayouts(getFarmRoutePathname(pathname)).map((layout) => layout.module),
|
|
32321
|
+
),
|
|
32322
|
+
fontStylesheetHref: "/farm-fonts.css",
|
|
32323
|
+
})` : "null"};
|
|
30864
32324
|
const farmDocsAPIHandler = ${config.docs?.enabled ? `createFarmDocsAPIHandler({ rootDir: farmDocsRuntimeRoot, srcDir: ${JSON.stringify(config.srcDir)}, docs: farmDocsResolvedConfig })` : "null"};
|
|
30865
32325
|
|
|
30866
32326
|
// API routes bundled at build time
|
|
@@ -31521,30 +32981,10 @@ async function handleMetadataImageRequest(request, routePathname) {
|
|
|
31521
32981
|
? await imageModule.default(props)
|
|
31522
32982
|
: imageModule.default;
|
|
31523
32983
|
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
}
|
|
31529
|
-
|
|
31530
|
-
let body;
|
|
31531
|
-
if (typeof value === "string" || value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
31532
|
-
body = value;
|
|
31533
|
-
} else {
|
|
31534
|
-
if (!React.isValidElement(value)) {
|
|
31535
|
-
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
31536
|
-
}
|
|
31537
|
-
body = ReactDOMServer.renderToStaticMarkup(value);
|
|
31538
|
-
}
|
|
31539
|
-
|
|
31540
|
-
return new Response(method === "HEAD" ? null : body, {
|
|
31541
|
-
status: 200,
|
|
31542
|
-
headers: {
|
|
31543
|
-
"Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
|
|
31544
|
-
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
31545
|
-
"X-Content-Type-Options": "nosniff",
|
|
31546
|
-
},
|
|
31547
|
-
});
|
|
32984
|
+
${hasGeneratedMetadataImages ? `return createFarmMetadataImageResponse(value, imageModule, {
|
|
32985
|
+
method,
|
|
32986
|
+
ifNoneMatch: request.headers.get("if-none-match"),
|
|
32987
|
+
});` : 'throw new Error("Generated metadata image runtime is unavailable");'}
|
|
31548
32988
|
} catch (error) {
|
|
31549
32989
|
console.error("Metadata image render failed:", error);
|
|
31550
32990
|
return new Response("Internal Server Error", {
|
|
@@ -32080,7 +33520,16 @@ async function handleFarmRequestInContext(
|
|
|
32080
33520
|
if (farmDocsHandler) {
|
|
32081
33521
|
const docsResponse = await farmDocsHandler(request.clone());
|
|
32082
33522
|
if (docsResponse) {
|
|
32083
|
-
|
|
33523
|
+
if (!docsResponse.headers.get("content-type")?.toLowerCase().includes("text/html")) {
|
|
33524
|
+
return docsResponse;
|
|
33525
|
+
}
|
|
33526
|
+
const docsHeaders = new Headers(docsResponse.headers);
|
|
33527
|
+
docsHeaders.set("x-farm-preload-buffered", "1");
|
|
33528
|
+
return new Response(docsResponse.body, {
|
|
33529
|
+
status: docsResponse.status,
|
|
33530
|
+
statusText: docsResponse.statusText,
|
|
33531
|
+
headers: docsHeaders,
|
|
33532
|
+
});
|
|
32084
33533
|
}
|
|
32085
33534
|
}
|
|
32086
33535
|
` : ""}
|
|
@@ -32208,6 +33657,7 @@ async function handleFarmRequestInContext(
|
|
|
32208
33657
|
status: 200,
|
|
32209
33658
|
headers: {
|
|
32210
33659
|
"Content-Type": "text/html; charset=utf-8",
|
|
33660
|
+
"x-farm-preload-buffered": "1",
|
|
32211
33661
|
...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
|
|
32212
33662
|
...getPPRHeaders("hit", pprConfig),
|
|
32213
33663
|
},
|
|
@@ -32435,10 +33885,15 @@ async function handleFarmRequestInContext(
|
|
|
32435
33885
|
pageElement = React.createElement(PageComponent, pageProps);
|
|
32436
33886
|
}
|
|
32437
33887
|
|
|
32438
|
-
if (route.shouldHydrate
|
|
33888
|
+
if (route.shouldHydrate) {
|
|
32439
33889
|
pageElement = React.createElement(
|
|
32440
33890
|
"div",
|
|
32441
|
-
{
|
|
33891
|
+
{
|
|
33892
|
+
id: "__farm_page__",
|
|
33893
|
+
"data-farm-client": "true",
|
|
33894
|
+
"data-farm-island": "page",
|
|
33895
|
+
"data-farm-island-strategy": route.islandStrategy || "load",
|
|
33896
|
+
},
|
|
32442
33897
|
pageElement,
|
|
32443
33898
|
);
|
|
32444
33899
|
}
|
|
@@ -32589,7 +34044,7 @@ async function handleFarmRequestInContext(
|
|
|
32589
34044
|
);
|
|
32590
34045
|
return applyProductionMiddlewareHeaders(new Response(streamedDocument, {
|
|
32591
34046
|
status: pageStatus,
|
|
32592
|
-
headers: responseHeaders,
|
|
34047
|
+
headers: { ...responseHeaders, "x-farm-preload-streaming": "1" },
|
|
32593
34048
|
}), middlewareHeaders);
|
|
32594
34049
|
}
|
|
32595
34050
|
|
|
@@ -32690,7 +34145,7 @@ async function handleFarmRequestInContext(
|
|
|
32690
34145
|
fullHtml,
|
|
32691
34146
|
{
|
|
32692
34147
|
status: pageStatus,
|
|
32693
|
-
headers: responseHeaders
|
|
34148
|
+
headers: { ...responseHeaders, "x-farm-preload-buffered": "1" }
|
|
32694
34149
|
}
|
|
32695
34150
|
), middlewareHeaders);
|
|
32696
34151
|
}
|
|
@@ -32794,6 +34249,7 @@ async function handleFarmRequestInContext(
|
|
|
32794
34249
|
headers: {
|
|
32795
34250
|
"Content-Type": "text/html; charset=utf-8",
|
|
32796
34251
|
"Cache-Control": "private, no-store",
|
|
34252
|
+
"x-farm-preload-buffered": "1",
|
|
32797
34253
|
},
|
|
32798
34254
|
}), middlewareHeaders);
|
|
32799
34255
|
} catch (boundaryError) {
|
|
@@ -32816,6 +34272,7 @@ async function handleFarmRequestInContext(
|
|
|
32816
34272
|
headers: {
|
|
32817
34273
|
"Content-Type": "text/html; charset=utf-8",
|
|
32818
34274
|
"Cache-Control": "private, no-store",
|
|
34275
|
+
"x-farm-preload-buffered": "1",
|
|
32819
34276
|
},
|
|
32820
34277
|
}
|
|
32821
34278
|
), middlewareHeaders);
|
|
@@ -32962,13 +34419,19 @@ async function handleFarmRequestInContext(
|
|
|
32962
34419
|
|
|
32963
34420
|
return applyProductionMiddlewareHeaders(new Response(fullHtml, {
|
|
32964
34421
|
status: 404,
|
|
32965
|
-
headers: {
|
|
34422
|
+
headers: {
|
|
34423
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
34424
|
+
"x-farm-preload-buffered": "1",
|
|
34425
|
+
}
|
|
32966
34426
|
}), middlewareHeaders);
|
|
32967
34427
|
} catch (error) {
|
|
32968
34428
|
console.error("404 render error:", error);
|
|
32969
34429
|
return applyProductionMiddlewareHeaders(new Response(
|
|
32970
34430
|
\`<!DOCTYPE html><html><head><title>404</title></head><body><h1>404 - Page Not Found</h1><p>The page \${pathname} doesn't exist.</p><a href="/">Go Home</a></body></html>\`,
|
|
32971
|
-
{
|
|
34431
|
+
{
|
|
34432
|
+
status: 404,
|
|
34433
|
+
headers: { "Content-Type": "text/html", "x-farm-preload-buffered": "1" },
|
|
34434
|
+
}
|
|
32972
34435
|
), middlewareHeaders);
|
|
32973
34436
|
}
|
|
32974
34437
|
${hasMiddlewareRuntime ? `
|
|
@@ -33010,7 +34473,10 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33010
34473
|
await farmPluginRuntime.runHookParallel("beforeRender", renderPayload);
|
|
33011
34474
|
|
|
33012
34475
|
const response = await handleFarmRequest(request);
|
|
33013
|
-
if (
|
|
34476
|
+
if (
|
|
34477
|
+
!hasFarmPluginHTMLTransforms ||
|
|
34478
|
+
!response.headers.get("content-type")?.toLowerCase().includes("text/html")
|
|
34479
|
+
) {
|
|
33014
34480
|
return response;
|
|
33015
34481
|
}
|
|
33016
34482
|
|
|
@@ -33020,6 +34486,8 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33020
34486
|
|
|
33021
34487
|
const headers = new Headers(response.headers);
|
|
33022
34488
|
headers.delete("content-length");
|
|
34489
|
+
headers.delete("x-farm-preload-streaming");
|
|
34490
|
+
headers.set("x-farm-preload-buffered", "1");
|
|
33023
34491
|
return new Response(html, {
|
|
33024
34492
|
status: response.status,
|
|
33025
34493
|
statusText: response.statusText,
|
|
@@ -33027,6 +34495,49 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33027
34495
|
});
|
|
33028
34496
|
}
|
|
33029
34497
|
|
|
34498
|
+
async function applyFarmPreloadBudget(response, pathname) {
|
|
34499
|
+
const headers = new Headers(response.headers);
|
|
34500
|
+
const linkHeader = headers.get("Link") || "";
|
|
34501
|
+
const isHtml = headers.get("Content-Type")?.toLowerCase().includes("text/html");
|
|
34502
|
+
const isStreaming = headers.get("x-farm-preload-streaming") === "1";
|
|
34503
|
+
const isBuffered = headers.get("x-farm-preload-buffered") === "1";
|
|
34504
|
+
headers.delete("x-farm-preload-streaming");
|
|
34505
|
+
headers.delete("x-farm-preload-buffered");
|
|
34506
|
+
|
|
34507
|
+
if (!isHtml) {
|
|
34508
|
+
if (!isStreaming && !isBuffered) return response;
|
|
34509
|
+
return new Response(response.body, {
|
|
34510
|
+
status: response.status,
|
|
34511
|
+
statusText: response.statusText,
|
|
34512
|
+
headers,
|
|
34513
|
+
});
|
|
34514
|
+
}
|
|
34515
|
+
|
|
34516
|
+
if (isStreaming || !isBuffered || response.body === null) {
|
|
34517
|
+
const managed = manageFarmLinkHeaderPreloads(linkHeader, farmPreloadConfig);
|
|
34518
|
+
if (managed.value) headers.set("Link", managed.value);
|
|
34519
|
+
else headers.delete("Link");
|
|
34520
|
+
reportFarmPreloadWarnings(managed.warnings, "route " + pathname);
|
|
34521
|
+
return new Response(response.body, {
|
|
34522
|
+
status: response.status,
|
|
34523
|
+
statusText: response.statusText,
|
|
34524
|
+
headers,
|
|
34525
|
+
});
|
|
34526
|
+
}
|
|
34527
|
+
|
|
34528
|
+
const html = await response.text();
|
|
34529
|
+
const managed = manageFarmDocumentPreloads(html, linkHeader, farmPreloadConfig);
|
|
34530
|
+
if (managed.linkHeader) headers.set("Link", managed.linkHeader);
|
|
34531
|
+
else headers.delete("Link");
|
|
34532
|
+
if (managed.html !== html) headers.delete("Content-Length");
|
|
34533
|
+
reportFarmPreloadWarnings(managed.warnings, "route " + pathname);
|
|
34534
|
+
return new Response(managed.html, {
|
|
34535
|
+
status: response.status,
|
|
34536
|
+
statusText: response.statusText,
|
|
34537
|
+
headers,
|
|
34538
|
+
});
|
|
34539
|
+
}
|
|
34540
|
+
|
|
33030
34541
|
// Export as Web Standard fetch API
|
|
33031
34542
|
export async function fetch(request, context) {
|
|
33032
34543
|
const runtimeOptions = farmPluginRuntime ? getFarmPluginRequestOptions(request) : null;
|
|
@@ -33049,7 +34560,8 @@ export async function fetch(request, context) {
|
|
|
33049
34560
|
const response = await _runWithCurrentRequest(request, () =>
|
|
33050
34561
|
_runWithAfterRequest(request, runRequest, context),
|
|
33051
34562
|
);
|
|
33052
|
-
|
|
34563
|
+
const pathname = new URL(request.url).pathname;
|
|
34564
|
+
return applyFarmPreloadBudget(applyConfiguredResponseHeaders(response, pathname), pathname);
|
|
33053
34565
|
}
|
|
33054
34566
|
export default { fetch };
|
|
33055
34567
|
`.trim();
|
|
@@ -33205,8 +34717,19 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
33205
34717
|
const outputDir = resolveDeployOutputPath(root, config.deploy.outputDir);
|
|
33206
34718
|
const ssrOutputDir = import_path12.default.join(root, distDir, "ssr");
|
|
33207
34719
|
const imageRuntime = resolveImageRuntime(config, preset);
|
|
34720
|
+
const hasGeneratedMetadataImages = Array.from(routeManager.getMetadataImages().values()).some(
|
|
34721
|
+
(image) => image.sourceType === "module"
|
|
34722
|
+
);
|
|
34723
|
+
const useExternalMetadataImageRuntime = shouldUseExternalMetadataImageRuntime(
|
|
34724
|
+
preset,
|
|
34725
|
+
hasGeneratedMetadataImages
|
|
34726
|
+
);
|
|
34727
|
+
const nitroRollupExternal = /* @__PURE__ */ __name((id) => useExternalMetadataImageRuntime && id === "@vercel/og" || isNitroRollupExternal(id), "nitroRollupExternal");
|
|
33208
34728
|
const ssrExternalPackages = collectSSRExternalPackages(ssrBundle);
|
|
33209
|
-
const copiedRuntimePackages = new Set(
|
|
34729
|
+
const copiedRuntimePackages = /* @__PURE__ */ new Set([
|
|
34730
|
+
...imageRuntime === "node" ? ["sharp"] : [],
|
|
34731
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : []
|
|
34732
|
+
]);
|
|
33210
34733
|
const isPrebuiltSSRCandidate = preset === "node-server" && [...ssrExternalPackages].every((packageName) => copiedRuntimePackages.has(packageName));
|
|
33211
34734
|
logger.info(`\u{1F4E6} Nitro output directory: ${outputDir}`);
|
|
33212
34735
|
logger.info(`\u{1F4E6} SSR entry file: ${ssrEntryFile}`);
|
|
@@ -33422,11 +34945,13 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33422
34945
|
".prisma/client",
|
|
33423
34946
|
".prisma/client/default",
|
|
33424
34947
|
"better-sqlite3",
|
|
33425
|
-
"sharp"
|
|
34948
|
+
"sharp",
|
|
34949
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : []
|
|
33426
34950
|
]
|
|
33427
34951
|
},
|
|
33428
34952
|
rollupConfig: {
|
|
33429
|
-
external:
|
|
34953
|
+
external: nitroRollupExternal,
|
|
34954
|
+
plugins: hasGeneratedMetadataImages && !useExternalMetadataImageRuntime ? [createMetadataImageWasmPlugin()] : []
|
|
33430
34955
|
},
|
|
33431
34956
|
// Keep the public Nitro boolean intact for build hooks. It is translated to
|
|
33432
34957
|
// Nitro's existing esbuild pass after hooks run, avoiding a second Terser pass.
|
|
@@ -33454,7 +34979,7 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33454
34979
|
snapshotSSRRebundleOptions(nitroConfig)
|
|
33455
34980
|
);
|
|
33456
34981
|
const requestedBuilder = nitroConfig.builder ?? process.env.NITRO_BUILDER;
|
|
33457
|
-
const canReusePrebuiltSSR = isPrebuiltSSRCandidate && nitroConfig.preset === "node-server" && (requestedBuilder === void 0 || requestedBuilder === "rollup" || requestedBuilder === "rolldown") && nitroConfig.sourceMap === false && !hasUnsupportedEsbuildOverrides && !hasLateBuildMutationConfig && !hasUnsupportedSSRRebundleOverrides && nitroConfig.rollupConfig?.external ===
|
|
34982
|
+
const canReusePrebuiltSSR = isPrebuiltSSRCandidate && nitroConfig.preset === "node-server" && (requestedBuilder === void 0 || requestedBuilder === "rollup" || requestedBuilder === "rolldown") && nitroConfig.sourceMap === false && !hasUnsupportedEsbuildOverrides && !hasLateBuildMutationConfig && !hasUnsupportedSSRRebundleOverrides && nitroConfig.rollupConfig?.external === nitroRollupExternal && !hasRollupPlugins(nitroConfig.rollupConfig?.plugins) && customRollupKeys.length === 0 && import_path12.default.resolve(nitroConfig.output?.serverDir || "") === import_path12.default.resolve(expectedServerDir) && Boolean(
|
|
33458
34983
|
nitroConfig.handlers?.some(
|
|
33459
34984
|
(handler) => import_path12.default.resolve(handler?.handler || "") === nitroEntryPath
|
|
33460
34985
|
)
|
|
@@ -33542,7 +35067,8 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33542
35067
|
effectiveMinify,
|
|
33543
35068
|
fs8
|
|
33544
35069
|
) : Promise.resolve(),
|
|
33545
|
-
imageRuntime === "node" ? copySharpRuntime(config, root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve()
|
|
35070
|
+
imageRuntime === "node" ? copySharpRuntime(config, root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve(),
|
|
35071
|
+
useExternalMetadataImageRuntime ? copyMetadataImageRuntime(root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve()
|
|
33546
35072
|
]);
|
|
33547
35073
|
const failedCopy = copyResults.find(
|
|
33548
35074
|
(result) => result.status === "rejected"
|
|
@@ -33654,6 +35180,9 @@ async function postProcessVercelOutput(root, outputDir, fs8, config, farmWorkflo
|
|
|
33654
35180
|
fs8
|
|
33655
35181
|
);
|
|
33656
35182
|
vercelConfig.routes = [
|
|
35183
|
+
// Apply the header before the filesystem handler. `continue` lets Vercel
|
|
35184
|
+
// serve the matching file while preserving the immutable cache policy.
|
|
35185
|
+
createFarmVercelImmutableAssetRoute(config.basePath),
|
|
33657
35186
|
// Serve static files first
|
|
33658
35187
|
{
|
|
33659
35188
|
handle: "filesystem"
|
|
@@ -33771,6 +35300,42 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs8) {
|
|
|
33771
35300
|
logger.info(`\u{1F5BC}\uFE0F Bundled Sharp image runtime (${copiedPackages.size} packages)`);
|
|
33772
35301
|
}
|
|
33773
35302
|
__name(copySharpRuntime, "copySharpRuntime");
|
|
35303
|
+
async function copyMetadataImageRuntime(root, nitroFuncDir, fs8) {
|
|
35304
|
+
const projectRequire = (0, import_module2.createRequire)(import_path12.default.join(root, "package.json"));
|
|
35305
|
+
let runtimeRequire = projectRequire;
|
|
35306
|
+
let packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
|
|
35307
|
+
if (!packageJsonPath) {
|
|
35308
|
+
try {
|
|
35309
|
+
runtimeRequire = (0, import_module2.createRequire)(projectRequire.resolve("@farm.js/core"));
|
|
35310
|
+
packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
|
|
35311
|
+
} catch {
|
|
35312
|
+
}
|
|
35313
|
+
}
|
|
35314
|
+
if (!packageJsonPath) {
|
|
35315
|
+
throw new Error(
|
|
35316
|
+
"Generated metadata images require @vercel/og. Reinstall @farm.js/core with production dependencies."
|
|
35317
|
+
);
|
|
35318
|
+
}
|
|
35319
|
+
const packageJson = JSON.parse(await fs8.readFile(packageJsonPath, "utf8"));
|
|
35320
|
+
const packageDir = import_path12.default.dirname(packageJsonPath);
|
|
35321
|
+
const targetDir = import_path12.default.join(nitroFuncDir, "node_modules", "@vercel", "og");
|
|
35322
|
+
await fs8.mkdir(import_path12.default.dirname(targetDir), { recursive: true });
|
|
35323
|
+
await fs8.cp(packageDir, targetDir, {
|
|
35324
|
+
recursive: true,
|
|
35325
|
+
force: true,
|
|
35326
|
+
dereference: true,
|
|
35327
|
+
mode: import_fs5.constants.COPYFILE_FICLONE
|
|
35328
|
+
});
|
|
35329
|
+
const functionPackagePath = import_path12.default.join(nitroFuncDir, "package.json");
|
|
35330
|
+
const functionPackage = JSON.parse(await fs8.readFile(functionPackagePath, "utf8"));
|
|
35331
|
+
functionPackage.dependencies = {
|
|
35332
|
+
...functionPackage.dependencies,
|
|
35333
|
+
"@vercel/og": String(packageJson.version || "0.11.1")
|
|
35334
|
+
};
|
|
35335
|
+
await fs8.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
|
|
35336
|
+
logger.info("\u{1F5BC}\uFE0F Bundled generated metadata image runtime");
|
|
35337
|
+
}
|
|
35338
|
+
__name(copyMetadataImageRuntime, "copyMetadataImageRuntime");
|
|
33774
35339
|
function resolvePackageJson(parentRequire, packageName) {
|
|
33775
35340
|
for (const request of [`${packageName}/package.json`, `${packageName}/package`]) {
|
|
33776
35341
|
try {
|
|
@@ -33830,54 +35395,7 @@ init_type_artifacts();
|
|
|
33830
35395
|
init_plugin();
|
|
33831
35396
|
init_environment_vite();
|
|
33832
35397
|
init_font_vite();
|
|
33833
|
-
|
|
33834
|
-
// src/server/vite-config.ts
|
|
33835
|
-
function mergeNoExternal(farmValue, userValue) {
|
|
33836
|
-
if (farmValue === true || userValue === true) return true;
|
|
33837
|
-
const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
|
|
33838
|
-
return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
|
|
33839
|
-
}
|
|
33840
|
-
__name(mergeNoExternal, "mergeNoExternal");
|
|
33841
|
-
function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
33842
|
-
return {
|
|
33843
|
-
...farmConfig,
|
|
33844
|
-
...userConfig,
|
|
33845
|
-
plugins: [...farmConfig.plugins || [], ...userConfig.plugins || []],
|
|
33846
|
-
server: {
|
|
33847
|
-
...farmConfig.server,
|
|
33848
|
-
...userConfig.server
|
|
33849
|
-
},
|
|
33850
|
-
resolve: {
|
|
33851
|
-
...farmConfig.resolve,
|
|
33852
|
-
...userConfig.resolve,
|
|
33853
|
-
dedupe: Array.from(
|
|
33854
|
-
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
33855
|
-
)
|
|
33856
|
-
},
|
|
33857
|
-
optimizeDeps: {
|
|
33858
|
-
...farmConfig.optimizeDeps,
|
|
33859
|
-
...userConfig.optimizeDeps,
|
|
33860
|
-
include: Array.from(
|
|
33861
|
-
/* @__PURE__ */ new Set([
|
|
33862
|
-
...farmConfig.optimizeDeps?.include || [],
|
|
33863
|
-
...userConfig.optimizeDeps?.include || []
|
|
33864
|
-
])
|
|
33865
|
-
),
|
|
33866
|
-
exclude: Array.from(
|
|
33867
|
-
/* @__PURE__ */ new Set([
|
|
33868
|
-
...farmConfig.optimizeDeps?.exclude || [],
|
|
33869
|
-
...userConfig.optimizeDeps?.exclude || []
|
|
33870
|
-
])
|
|
33871
|
-
)
|
|
33872
|
-
},
|
|
33873
|
-
ssr: {
|
|
33874
|
-
...farmConfig.ssr,
|
|
33875
|
-
...userConfig.ssr,
|
|
33876
|
-
noExternal: mergeNoExternal(farmConfig.ssr?.noExternal, userConfig.ssr?.noExternal)
|
|
33877
|
-
}
|
|
33878
|
-
};
|
|
33879
|
-
}
|
|
33880
|
-
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
35398
|
+
init_vite_config();
|
|
33881
35399
|
|
|
33882
35400
|
// src/build/production-node-env.ts
|
|
33883
35401
|
var productionNodeEnvStateKey = /* @__PURE__ */ Symbol.for("@farm.js/core/production-node-env-state");
|