@farm.js/core 0.1.0-beta.11 → 0.1.0-beta.14
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-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-5EVQFRL2.mjs → chunk-ARCGE2VT.mjs} +2 -2
- package/dist/chunk-ARCGE2VT.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-77BOAQHI.mjs → chunk-PNFQQSRA.mjs} +754 -156
- package/dist/chunk-PNFQQSRA.mjs.map +1 -0
- package/dist/chunk-USLFXFFH.mjs +46 -0
- package/dist/chunk-USLFXFFH.mjs.map +1 -0
- package/dist/{chunk-4677KXB7.mjs → chunk-VUL55IAX.mjs} +368 -103
- package/dist/chunk-VUL55IAX.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 +2235 -689
- 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 +2062 -525
- 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 +1550 -348
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +9 -5
- package/dist/server.cjs +1663 -419
- 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 +1604 -358
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +9 -5
- package/package.json +10 -1
- package/types/client.d.ts +115 -4
- package/dist/after.d.mts +0 -25
- package/dist/after.d.ts +0 -25
- package/dist/agent-runtime.d.mts +0 -94
- package/dist/agent-runtime.d.ts +0 -94
- package/dist/api/route-manager.d.mts +0 -66
- package/dist/api/route-manager.d.ts +0 -66
- package/dist/api/runtime.d.mts +0 -3
- package/dist/api/runtime.d.ts +0 -3
- package/dist/api.d.mts +0 -48
- package/dist/api.d.ts +0 -48
- package/dist/app-BNE2FoZ4.d.mts +0 -302
- package/dist/app-DRGUmJ3s.d.ts +0 -302
- package/dist/app-markdown.d.mts +0 -22
- package/dist/app-markdown.d.ts +0 -22
- package/dist/cache.d.mts +0 -192
- package/dist/cache.d.ts +0 -192
- package/dist/chunk-4677KXB7.mjs.map +0 -1
- package/dist/chunk-4LND3PXF.mjs.map +0 -1
- package/dist/chunk-5EVQFRL2.mjs.map +0 -1
- package/dist/chunk-77BOAQHI.mjs.map +0 -1
- package/dist/chunk-AW6I64AP.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/client-BT1mFQas.d.mts +0 -447
- package/dist/client-Nn0q4eO4.d.ts +0 -447
- package/dist/client-cache-CIlyBlmx.d.ts +0 -6
- package/dist/client-cache-D-EZ7XVW.d.mts +0 -6
- package/dist/client-plugins-Bc5jHcNr.d.ts +0 -1927
- package/dist/client-plugins-jsk-ZLzJ.d.mts +0 -1927
- package/dist/client-plugins.d.mts +0 -22
- package/dist/client-plugins.d.ts +0 -22
- package/dist/client.d.mts +0 -447
- package/dist/client.d.ts +0 -447
- package/dist/config.d.mts +0 -29
- package/dist/config.d.ts +0 -29
- package/dist/cron.d.mts +0 -78
- package/dist/cron.d.ts +0 -78
- package/dist/deferred.d.mts +0 -42
- package/dist/deferred.d.ts +0 -42
- package/dist/deployment.d.mts +0 -34
- package/dist/deployment.d.ts +0 -34
- package/dist/docs.d.mts +0 -69
- package/dist/docs.d.ts +0 -69
- package/dist/env-types.d.mts +0 -12
- package/dist/env-types.d.ts +0 -12
- package/dist/env.d.mts +0 -45
- package/dist/env.d.ts +0 -45
- package/dist/environment/vite.d.mts +0 -22
- package/dist/environment/vite.d.ts +0 -22
- package/dist/environment.d.mts +0 -18
- package/dist/environment.d.ts +0 -18
- package/dist/font.d.mts +0 -70
- package/dist/font.d.ts +0 -70
- package/dist/headers.d.mts +0 -22
- package/dist/headers.d.ts +0 -22
- package/dist/i18n/client.d.mts +0 -32
- package/dist/i18n/client.d.ts +0 -32
- package/dist/i18n/index.d.mts +0 -20
- package/dist/i18n/index.d.ts +0 -20
- package/dist/i18n/server.d.mts +0 -30
- package/dist/i18n/server.d.ts +0 -30
- package/dist/image/server.d.mts +0 -37
- package/dist/image/server.d.ts +0 -37
- package/dist/image/sharp.d.mts +0 -7
- package/dist/image/sharp.d.ts +0 -7
- package/dist/image-config-Duob7wER.d.mts +0 -50
- package/dist/image-config-Duob7wER.d.ts +0 -50
- package/dist/image.d.mts +0 -39
- package/dist/image.d.ts +0 -39
- package/dist/index.d.mts +0 -455
- package/dist/index.d.ts +0 -455
- package/dist/integration-api-CHT2OKAf.d.mts +0 -93
- package/dist/integration-api-CHT2OKAf.d.ts +0 -93
- package/dist/integrations.d.mts +0 -22
- package/dist/integrations.d.ts +0 -22
- package/dist/internal/build-runtime.d.mts +0 -39
- package/dist/internal/build-runtime.d.ts +0 -39
- package/dist/internal/client-runtime.d.mts +0 -2
- package/dist/internal/client-runtime.d.ts +0 -2
- package/dist/internal/config-runtime.d.mts +0 -39
- package/dist/internal/config-runtime.d.ts +0 -39
- package/dist/internal/production-node-env.d.mts +0 -12
- package/dist/internal/production-node-env.d.ts +0 -12
- package/dist/internal/production-runtime.d.mts +0 -41
- package/dist/internal/production-runtime.d.ts +0 -41
- package/dist/markdown.d.mts +0 -60
- package/dist/markdown.d.ts +0 -60
- package/dist/metadata-7ffpT3jr.d.mts +0 -22
- package/dist/metadata-JHn-8eht.d.ts +0 -22
- package/dist/middleware.d.mts +0 -164
- package/dist/middleware.d.ts +0 -164
- package/dist/navigation-errors-Dvwpzaer.d.mts +0 -13
- package/dist/navigation-errors-Dvwpzaer.d.ts +0 -13
- package/dist/navigation.d.mts +0 -14
- package/dist/navigation.d.ts +0 -14
- package/dist/observability.d.mts +0 -335
- package/dist/observability.d.ts +0 -335
- package/dist/params-BALtrRim.d.ts +0 -15
- package/dist/params-ry-lxqmy.d.mts +0 -15
- package/dist/plugin-BJDf43dc.d.mts +0 -165
- package/dist/plugin-BJDf43dc.d.ts +0 -165
- package/dist/plugin.d.mts +0 -22
- package/dist/plugin.d.ts +0 -22
- package/dist/production-runtime-9KG7GuvW.d.ts +0 -79
- package/dist/production-runtime-B-fweKts.d.mts +0 -79
- package/dist/production-runtime-C_B79w2P.d.mts +0 -28
- package/dist/production-runtime-DDEM1D2q.d.ts +0 -28
- package/dist/query/client.d.mts +0 -61
- package/dist/query/client.d.ts +0 -61
- package/dist/query/index.d.mts +0 -90
- package/dist/query/index.d.ts +0 -90
- package/dist/query/parsers.d.mts +0 -25
- package/dist/query/parsers.d.ts +0 -25
- package/dist/query/server.d.mts +0 -55
- package/dist/query/server.d.ts +0 -55
- package/dist/request-Dsq4kGW0.d.mts +0 -6
- package/dist/request-udtobOLv.d.ts +0 -6
- package/dist/request.d.mts +0 -2
- package/dist/request.d.ts +0 -2
- package/dist/resolver-DJqjLMg_.d.mts +0 -14
- package/dist/resolver-IH4RmPEl.d.ts +0 -14
- package/dist/route-runtime-DoOHzCAD.d.mts +0 -38
- package/dist/route-runtime-DoOHzCAD.d.ts +0 -38
- package/dist/router.d.mts +0 -36
- package/dist/router.d.ts +0 -36
- package/dist/routes.d.mts +0 -224
- package/dist/routes.d.ts +0 -224
- package/dist/runtime-9nQjVM7X.d.mts +0 -206
- package/dist/runtime-Cxpq6xZN.d.mts +0 -27
- package/dist/runtime-DgeS2skB.d.ts +0 -206
- package/dist/runtime-bv63eUiO.d.ts +0 -27
- package/dist/server-action-security.d.mts +0 -43
- package/dist/server-action-security.d.ts +0 -43
- package/dist/server-fn-client.d.mts +0 -32
- package/dist/server-fn-client.d.ts +0 -32
- package/dist/server-fn.d.mts +0 -93
- package/dist/server-fn.d.ts +0 -93
- package/dist/server-plugins.d.mts +0 -55
- package/dist/server-plugins.d.ts +0 -55
- package/dist/server-query-client.d.mts +0 -50
- package/dist/server-query-client.d.ts +0 -50
- package/dist/server-query.d.mts +0 -36
- package/dist/server-query.d.ts +0 -36
- package/dist/server.d.mts +0 -48
- package/dist/server.d.ts +0 -48
- package/dist/storage.d.mts +0 -52
- package/dist/storage.d.ts +0 -52
- package/dist/testing.d.mts +0 -101
- package/dist/testing.d.ts +0 -101
- package/dist/transport-BmbGTXA5.d.mts +0 -49
- package/dist/transport-BmbGTXA5.d.ts +0 -49
- package/dist/types-BMxWr97v.d.mts +0 -81
- package/dist/types-BMxWr97v.d.ts +0 -81
- package/dist/types-C9N-nk5R.d.mts +0 -53
- package/dist/types-C9N-nk5R.d.ts +0 -53
- package/dist/types-D1A6-XvH.d.mts +0 -73
- package/dist/types-D1A6-XvH.d.ts +0 -73
- package/dist/utils-CA0z0c-2.d.ts +0 -23
- package/dist/utils-mYVkSOt2.d.mts +0 -23
- package/dist/version.d.mts +0 -3
- package/dist/version.d.ts +0 -3
- package/dist/vite.d.mts +0 -22
- package/dist/vite.d.ts +0 -22
- package/dist/workflows.d.mts +0 -110
- package/dist/workflows.d.ts +0 -110
- /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
|
}
|
|
@@ -10667,7 +11094,8 @@ function serializeFontResult(font) {
|
|
|
10667
11094
|
fontFamily: stack,
|
|
10668
11095
|
...font.style ? { fontStyle: font.style } : {},
|
|
10669
11096
|
...font.weight !== void 0 && !String(font.weight).includes(" ") ? { fontWeight: font.weight } : {}
|
|
10670
|
-
}
|
|
11097
|
+
},
|
|
11098
|
+
preloads: font.preloadResources
|
|
10671
11099
|
});
|
|
10672
11100
|
}
|
|
10673
11101
|
function renderFontDefinitionCss(font, production, basePath) {
|
|
@@ -11180,6 +11608,10 @@ ${FONT_SECTION_END}
|
|
|
11180
11608
|
fallback,
|
|
11181
11609
|
display,
|
|
11182
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
|
+
})),
|
|
11183
11615
|
weight: defaultWeight,
|
|
11184
11616
|
style: raw.style === void 0 ? void 0 : defaultStyle,
|
|
11185
11617
|
sources: normalizedSources
|
|
@@ -11276,7 +11708,7 @@ ${FONT_SECTION_END}
|
|
|
11276
11708
|
const normalizedExtension = extension.toLowerCase();
|
|
11277
11709
|
const hash = (0, import_node_crypto2.createHash)("sha256").update(bytes).digest("hex").slice(0, 12);
|
|
11278
11710
|
const baseName = sanitizeFileName(import_node_path5.default.basename(fileName, extension)) || "font";
|
|
11279
|
-
const outputFileName = `assets/fonts/${baseName}
|
|
11711
|
+
const outputFileName = `assets/fonts/${baseName}-h${hash}${normalizedExtension}`;
|
|
11280
11712
|
const key = `${hash}${normalizedExtension}`;
|
|
11281
11713
|
const existing = this.resources.get(key);
|
|
11282
11714
|
if (existing) return existing;
|
|
@@ -11348,6 +11780,172 @@ ${FONT_SECTION_END}
|
|
|
11348
11780
|
}
|
|
11349
11781
|
});
|
|
11350
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
|
+
|
|
11351
11949
|
// src/server/renderer.ts
|
|
11352
11950
|
function hasRequestHeader(req, name) {
|
|
11353
11951
|
const value = req.headers[name.toLowerCase()];
|
|
@@ -11411,7 +12009,7 @@ function createPPRRefreshScript() {
|
|
|
11411
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>`;
|
|
11412
12010
|
}
|
|
11413
12011
|
function createPreHydrationClickQueueScript() {
|
|
11414
|
-
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>`;
|
|
11415
12013
|
}
|
|
11416
12014
|
function searchParamsToObject(searchParams) {
|
|
11417
12015
|
const output = {};
|
|
@@ -11503,12 +12101,12 @@ function createRouteStateProps(input) {
|
|
|
11503
12101
|
context: input.pluginExposedContext.size > 0 ? { data: input.pluginExposedContext } : void 0
|
|
11504
12102
|
};
|
|
11505
12103
|
}
|
|
11506
|
-
var
|
|
12104
|
+
var import_react5, import_server2, fs2, path11, import_stream, cachedClerkProvider, importRuntimeModule, _FarmRouteErrorBoundary, FarmRouteErrorBoundary, _ServerRenderer, ServerRenderer;
|
|
11507
12105
|
var init_renderer = __esm({
|
|
11508
12106
|
"src/server/renderer.ts"() {
|
|
11509
12107
|
"use strict";
|
|
11510
|
-
|
|
11511
|
-
|
|
12108
|
+
import_react5 = __toESM(require("react"));
|
|
12109
|
+
import_server2 = require("react-dom/server");
|
|
11512
12110
|
fs2 = __toESM(require("fs"));
|
|
11513
12111
|
path11 = __toESM(require("path"));
|
|
11514
12112
|
init_utils();
|
|
@@ -11531,6 +12129,7 @@ var init_renderer = __esm({
|
|
|
11531
12129
|
init_routing();
|
|
11532
12130
|
init_response();
|
|
11533
12131
|
init_font_vite();
|
|
12132
|
+
init_metadata_image();
|
|
11534
12133
|
cachedClerkProvider = null;
|
|
11535
12134
|
importRuntimeModule = new Function("specifier", "return import(specifier);");
|
|
11536
12135
|
__name(hasRequestHeader, "hasRequestHeader");
|
|
@@ -11547,7 +12146,7 @@ var init_renderer = __esm({
|
|
|
11547
12146
|
__name(createDeferredHydrationScript, "createDeferredHydrationScript");
|
|
11548
12147
|
__name(toMiddlewareMap2, "toMiddlewareMap");
|
|
11549
12148
|
__name(isWebResponse, "isWebResponse");
|
|
11550
|
-
_FarmRouteErrorBoundary = class _FarmRouteErrorBoundary extends
|
|
12149
|
+
_FarmRouteErrorBoundary = class _FarmRouteErrorBoundary extends import_react5.default.Component {
|
|
11551
12150
|
constructor(props) {
|
|
11552
12151
|
super(props);
|
|
11553
12152
|
this.state = { hasError: false, error: null };
|
|
@@ -11558,7 +12157,7 @@ var init_renderer = __esm({
|
|
|
11558
12157
|
render() {
|
|
11559
12158
|
if (this.state.hasError) {
|
|
11560
12159
|
const Fallback = this.props.Fallback;
|
|
11561
|
-
return
|
|
12160
|
+
return import_react5.default.createElement(Fallback, {
|
|
11562
12161
|
...this.props.fallbackProps,
|
|
11563
12162
|
error: this.state.error,
|
|
11564
12163
|
reset: /* @__PURE__ */ __name(() => this.setState({ hasError: false, error: null }), "reset")
|
|
@@ -11727,14 +12326,14 @@ var init_renderer = __esm({
|
|
|
11727
12326
|
searchParams: Promise.resolve({}),
|
|
11728
12327
|
path: page2.urlPath
|
|
11729
12328
|
};
|
|
11730
|
-
let pageElement =
|
|
12329
|
+
let pageElement = import_react5.default.createElement(
|
|
11731
12330
|
PageComponent,
|
|
11732
12331
|
pageProps
|
|
11733
12332
|
);
|
|
11734
12333
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
11735
12334
|
const layoutModule = layoutModules[i];
|
|
11736
12335
|
const LayoutComponent = layoutModule.default;
|
|
11737
|
-
pageElement =
|
|
12336
|
+
pageElement = import_react5.default.createElement(
|
|
11738
12337
|
LayoutComponent,
|
|
11739
12338
|
{
|
|
11740
12339
|
children: pageElement,
|
|
@@ -12060,6 +12659,7 @@ var init_renderer = __esm({
|
|
|
12060
12659
|
req.__FARM_ROUTE__ = pathname;
|
|
12061
12660
|
req.__FARM_IS_CLIENT_COMPONENT__ = isClientComponent;
|
|
12062
12661
|
req.__FARM_SHOULD_HYDRATE__ = shouldHydrate;
|
|
12662
|
+
req.__FARM_ISLAND_STRATEGY__ = moduleMetadata.islandStrategy;
|
|
12063
12663
|
req.__FARM_HAS_HYDRATABLE_ROUTE_SLOTS__ = hasHydratableRouteSlots;
|
|
12064
12664
|
req.__FARM_LOADING_MODULE_PATH__ = loadingBoundaryEntry?.modulePath ? loadingBoundaryEntry.modulePath.substring(
|
|
12065
12665
|
loadingBoundaryEntry.modulePath.indexOf("/src/app/")
|
|
@@ -12112,12 +12712,12 @@ var init_renderer = __esm({
|
|
|
12112
12712
|
await _runWithMiddlewareData(middlewareDataForContext, async () => {
|
|
12113
12713
|
await _runWithMiddlewareContext(middlewareContext, async () => {
|
|
12114
12714
|
await _runWithCurrentRequest(currentRequest, async () => {
|
|
12115
|
-
let pageElement =
|
|
12715
|
+
let pageElement = import_react5.default.createElement(
|
|
12116
12716
|
PageComponent,
|
|
12117
12717
|
pageProps
|
|
12118
12718
|
);
|
|
12119
12719
|
if (LoadingFallbackComponent) {
|
|
12120
|
-
const loadingFallback =
|
|
12720
|
+
const loadingFallback = import_react5.default.createElement(LoadingFallbackComponent, {
|
|
12121
12721
|
...createRouteStateProps({
|
|
12122
12722
|
params,
|
|
12123
12723
|
searchParamsObject,
|
|
@@ -12126,16 +12726,21 @@ var init_renderer = __esm({
|
|
|
12126
12726
|
pluginExposedContext
|
|
12127
12727
|
})
|
|
12128
12728
|
});
|
|
12129
|
-
pageElement =
|
|
12130
|
-
|
|
12729
|
+
pageElement = import_react5.default.createElement(
|
|
12730
|
+
import_react5.default.Suspense,
|
|
12131
12731
|
{ fallback: loadingFallback },
|
|
12132
12732
|
pageElement
|
|
12133
12733
|
);
|
|
12134
12734
|
}
|
|
12135
12735
|
if (isClientComponent || shouldHydrate) {
|
|
12136
|
-
pageElement =
|
|
12736
|
+
pageElement = import_react5.default.createElement(
|
|
12137
12737
|
"div",
|
|
12138
|
-
{
|
|
12738
|
+
{
|
|
12739
|
+
id: "__farm_page__",
|
|
12740
|
+
"data-farm-client": "true",
|
|
12741
|
+
"data-farm-island": "page",
|
|
12742
|
+
"data-farm-island-strategy": moduleMetadata.islandStrategy ?? "load"
|
|
12743
|
+
},
|
|
12139
12744
|
pageElement
|
|
12140
12745
|
);
|
|
12141
12746
|
}
|
|
@@ -12147,11 +12752,11 @@ var init_renderer = __esm({
|
|
|
12147
12752
|
const slotProps = {};
|
|
12148
12753
|
for (const slot of renderedRouteSlots) {
|
|
12149
12754
|
if (slot.ownerPattern !== layoutEntry.pattern) continue;
|
|
12150
|
-
let slotElement =
|
|
12755
|
+
let slotElement = import_react5.default.createElement(
|
|
12151
12756
|
slot.module.default,
|
|
12152
12757
|
slot.props
|
|
12153
12758
|
);
|
|
12154
|
-
slotElement =
|
|
12759
|
+
slotElement = import_react5.default.createElement(
|
|
12155
12760
|
"div",
|
|
12156
12761
|
{
|
|
12157
12762
|
id: slot.containerId,
|
|
@@ -12162,7 +12767,7 @@ var init_renderer = __esm({
|
|
|
12162
12767
|
);
|
|
12163
12768
|
slotProps[slot.name] = slotElement;
|
|
12164
12769
|
}
|
|
12165
|
-
wrappedElement =
|
|
12770
|
+
wrappedElement = import_react5.default.createElement(
|
|
12166
12771
|
LayoutComponent,
|
|
12167
12772
|
{
|
|
12168
12773
|
children: wrappedElement,
|
|
@@ -12172,7 +12777,7 @@ var init_renderer = __esm({
|
|
|
12172
12777
|
);
|
|
12173
12778
|
}
|
|
12174
12779
|
if (ErrorFallbackComponent) {
|
|
12175
|
-
wrappedElement =
|
|
12780
|
+
wrappedElement = import_react5.default.createElement(
|
|
12176
12781
|
FarmRouteErrorBoundary,
|
|
12177
12782
|
{
|
|
12178
12783
|
Fallback: ErrorFallbackComponent,
|
|
@@ -12305,7 +12910,7 @@ var init_renderer = __esm({
|
|
|
12305
12910
|
if (!cachedClerkProvider) {
|
|
12306
12911
|
cachedClerkProvider = await importRuntimeModule("@clerk/react");
|
|
12307
12912
|
}
|
|
12308
|
-
wrapped =
|
|
12913
|
+
wrapped = import_react5.default.createElement(
|
|
12309
12914
|
cachedClerkProvider.ClerkProvider,
|
|
12310
12915
|
provider.props || {},
|
|
12311
12916
|
wrapped
|
|
@@ -12380,6 +12985,13 @@ var init_renderer = __esm({
|
|
|
12380
12985
|
return reference;
|
|
12381
12986
|
}
|
|
12382
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
|
+
}
|
|
12383
12995
|
if (options.image.sourceType === "static") {
|
|
12384
12996
|
if (!options.image.staticInfo) {
|
|
12385
12997
|
throw new Error(`Static metadata image ${options.image.modulePath} is missing file info`);
|
|
@@ -12405,42 +13017,12 @@ var init_renderer = __esm({
|
|
|
12405
13017
|
await this.writeMetadataImageResponse(req, res, handlerResult, imageModule);
|
|
12406
13018
|
}
|
|
12407
13019
|
async writeMetadataImageResponse(req, res, value, imageModule) {
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
res.end();
|
|
12415
|
-
return;
|
|
12416
|
-
}
|
|
12417
|
-
const body2 = Buffer.from(await value.arrayBuffer());
|
|
12418
|
-
res.write(body2);
|
|
12419
|
-
res.end();
|
|
12420
|
-
return;
|
|
12421
|
-
}
|
|
12422
|
-
const contentType = imageModule.contentType || "image/svg+xml; charset=utf-8";
|
|
12423
|
-
let body;
|
|
12424
|
-
if (typeof value === "string") {
|
|
12425
|
-
body = value;
|
|
12426
|
-
} else if (value instanceof ArrayBuffer) {
|
|
12427
|
-
body = Buffer.from(value);
|
|
12428
|
-
} else if (ArrayBuffer.isView(value)) {
|
|
12429
|
-
body = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
12430
|
-
} else if (import_react4.default.isValidElement(value)) {
|
|
12431
|
-
body = (0, import_server.renderToStaticMarkup)(value);
|
|
12432
|
-
} else {
|
|
12433
|
-
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
12434
|
-
}
|
|
12435
|
-
res.statusCode = res.statusCode || 200;
|
|
12436
|
-
res.setHeader("Content-Type", contentType);
|
|
12437
|
-
res.setHeader("Cache-Control", "public, max-age=0, must-revalidate");
|
|
12438
|
-
if (req.method === "HEAD") {
|
|
12439
|
-
res.end();
|
|
12440
|
-
return;
|
|
12441
|
-
}
|
|
12442
|
-
res.write(body);
|
|
12443
|
-
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);
|
|
12444
13026
|
}
|
|
12445
13027
|
async writeStaticMetadataImageResponse(req, res, image) {
|
|
12446
13028
|
const method = (req.method || "GET").toUpperCase();
|
|
@@ -12487,7 +13069,7 @@ var init_renderer = __esm({
|
|
|
12487
13069
|
return false;
|
|
12488
13070
|
}
|
|
12489
13071
|
const ErrorComponent = errorModule.default;
|
|
12490
|
-
const errorElement =
|
|
13072
|
+
const errorElement = import_react5.default.createElement(ErrorComponent, {
|
|
12491
13073
|
...createRouteStateProps({
|
|
12492
13074
|
params: options.params,
|
|
12493
13075
|
searchParamsObject: options.searchParamsObject,
|
|
@@ -12505,7 +13087,7 @@ var init_renderer = __esm({
|
|
|
12505
13087
|
);
|
|
12506
13088
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
12507
13089
|
const LayoutComponent = layoutModules[i].default;
|
|
12508
|
-
wrapped =
|
|
13090
|
+
wrapped = import_react5.default.createElement(
|
|
12509
13091
|
LayoutComponent,
|
|
12510
13092
|
{
|
|
12511
13093
|
children: wrapped,
|
|
@@ -12570,6 +13152,7 @@ var init_renderer = __esm({
|
|
|
12570
13152
|
search: routeEntry.search,
|
|
12571
13153
|
isClientComponent: routeEntry.isClientComponent,
|
|
12572
13154
|
shouldHydrate: routeEntry.shouldHydrate,
|
|
13155
|
+
islandStrategy: routeEntry.islandStrategy,
|
|
12573
13156
|
preloads: [routeEntry.modulePath],
|
|
12574
13157
|
assets: []
|
|
12575
13158
|
};
|
|
@@ -12606,6 +13189,7 @@ window.__FARM_DEPLOYMENT_ID__ = ${serializeInlineValue(deploymentId)};
|
|
|
12606
13189
|
window.__FARM_PATH__ = ${JSON.stringify(req.__FARM_ROUTE__ || req.url || "/")};
|
|
12607
13190
|
window.__FARM_IS_CLIENT__ = ${JSON.stringify(isClientComponent)};
|
|
12608
13191
|
window.__FARM_SHOULD_HYDRATE__ = ${JSON.stringify(req.__FARM_SHOULD_HYDRATE__ === true)};
|
|
13192
|
+
window.__FARM_ISLAND_STRATEGY__ = ${JSON.stringify(req.__FARM_ISLAND_STRATEGY__ || "load")};
|
|
12609
13193
|
window.__FARM_PAGE_MODULE__ = ${JSON.stringify(relativePath2)};
|
|
12610
13194
|
window.__FARM_LOADING_MODULE__ = ${JSON.stringify(
|
|
12611
13195
|
req.__FARM_LOADING_MODULE_PATH__ || null
|
|
@@ -12623,8 +13207,8 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12623
13207
|
const i18nSnapshot = getFarmI18nClientSnapshot();
|
|
12624
13208
|
const i18nAlternateTags = i18nSnapshot ? renderI18nAlternateLinks(req.__FARM_ROUTE__ || req.url || "/", i18nSnapshot) : "";
|
|
12625
13209
|
const fontHead = renderFarmFontDevHead(this.config.root || process.cwd());
|
|
12626
|
-
const streamRoot =
|
|
12627
|
-
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, {
|
|
12628
13212
|
onShellReady() {
|
|
12629
13213
|
const shellReadyMs = Date.now() - streamStartTime;
|
|
12630
13214
|
emitFarmEvent({
|
|
@@ -12782,12 +13366,12 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
|
|
|
12782
13366
|
break;
|
|
12783
13367
|
}
|
|
12784
13368
|
}
|
|
12785
|
-
let element =
|
|
13369
|
+
let element = import_react5.default.createElement(
|
|
12786
13370
|
NotFoundComponent,
|
|
12787
13371
|
{ pathname }
|
|
12788
13372
|
);
|
|
12789
13373
|
if (LayoutComponent) {
|
|
12790
|
-
element =
|
|
13374
|
+
element = import_react5.default.createElement(
|
|
12791
13375
|
LayoutComponent,
|
|
12792
13376
|
{ children: element }
|
|
12793
13377
|
);
|
|
@@ -12937,6 +13521,7 @@ var init_app = __esm({
|
|
|
12937
13521
|
init_server2();
|
|
12938
13522
|
init_cache();
|
|
12939
13523
|
init_auth_config();
|
|
13524
|
+
init_preload();
|
|
12940
13525
|
defaultDocsConfig = {
|
|
12941
13526
|
enabled: false,
|
|
12942
13527
|
entry: "/docs",
|
|
@@ -13002,6 +13587,7 @@ var init_app = __esm({
|
|
|
13002
13587
|
context: config.context || (() => void 0),
|
|
13003
13588
|
serverActions: resolveServerActionsConfig(config.serverActions),
|
|
13004
13589
|
images: resolveFarmImageConfig(config.images),
|
|
13590
|
+
performance: resolveFarmPerformanceConfig(config.performance),
|
|
13005
13591
|
i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
|
|
13006
13592
|
root,
|
|
13007
13593
|
mode: process.env.NODE_ENV === "production" ? "production" : "development"
|
|
@@ -14595,6 +15181,49 @@ var init_search_client = __esm({
|
|
|
14595
15181
|
}
|
|
14596
15182
|
});
|
|
14597
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
|
+
|
|
14598
15227
|
// src/default-styles.ts
|
|
14599
15228
|
var defaultGlobalCSS;
|
|
14600
15229
|
var init_default_styles = __esm({
|
|
@@ -15002,12 +15631,12 @@ var init_module = __esm({
|
|
|
15002
15631
|
function isMiddlewareResponse(value) {
|
|
15003
15632
|
return value instanceof Response;
|
|
15004
15633
|
}
|
|
15005
|
-
var fs4,
|
|
15634
|
+
var fs4, path19, _MiddlewareManager, MiddlewareManager;
|
|
15006
15635
|
var init_manager = __esm({
|
|
15007
15636
|
"src/middleware/manager.ts"() {
|
|
15008
15637
|
"use strict";
|
|
15009
15638
|
fs4 = __toESM(require("fs"));
|
|
15010
|
-
|
|
15639
|
+
path19 = __toESM(require("path"));
|
|
15011
15640
|
init_context();
|
|
15012
15641
|
init_module();
|
|
15013
15642
|
init_utils();
|
|
@@ -15087,8 +15716,8 @@ var init_manager = __esm({
|
|
|
15087
15716
|
const entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
15088
15717
|
for (const entry of entries) {
|
|
15089
15718
|
if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
|
|
15090
|
-
const subPath =
|
|
15091
|
-
const subRoutePath =
|
|
15719
|
+
const subPath = path19.join(dir, entry.name);
|
|
15720
|
+
const subRoutePath = path19.posix.join(routePath, entry.name);
|
|
15092
15721
|
await this.discoverInDirectory(subPath, subRoutePath, discovered);
|
|
15093
15722
|
}
|
|
15094
15723
|
}
|
|
@@ -15099,7 +15728,7 @@ var init_manager = __esm({
|
|
|
15099
15728
|
findMiddlewareFile(dir) {
|
|
15100
15729
|
const extensions = [".ts", ".tsx", ".js", ".jsx"];
|
|
15101
15730
|
for (const ext of extensions) {
|
|
15102
|
-
const filePath =
|
|
15731
|
+
const filePath = path19.join(dir, `middleware${ext}`);
|
|
15103
15732
|
if (fs4.existsSync(filePath)) {
|
|
15104
15733
|
return filePath;
|
|
15105
15734
|
}
|
|
@@ -15450,7 +16079,7 @@ var init_manager = __esm({
|
|
|
15450
16079
|
// src/write-file-if-changed.ts
|
|
15451
16080
|
function writeFileIfChanged(filePath, content) {
|
|
15452
16081
|
try {
|
|
15453
|
-
if ((0,
|
|
16082
|
+
if ((0, import_node_fs6.readFileSync)(filePath, "utf8") === content) {
|
|
15454
16083
|
return false;
|
|
15455
16084
|
}
|
|
15456
16085
|
} catch (error) {
|
|
@@ -15458,14 +16087,14 @@ function writeFileIfChanged(filePath, content) {
|
|
|
15458
16087
|
throw error;
|
|
15459
16088
|
}
|
|
15460
16089
|
}
|
|
15461
|
-
(0,
|
|
16090
|
+
(0, import_node_fs6.writeFileSync)(filePath, content, "utf8");
|
|
15462
16091
|
return true;
|
|
15463
16092
|
}
|
|
15464
|
-
var
|
|
16093
|
+
var import_node_fs6;
|
|
15465
16094
|
var init_write_file_if_changed = __esm({
|
|
15466
16095
|
"src/write-file-if-changed.ts"() {
|
|
15467
16096
|
"use strict";
|
|
15468
|
-
|
|
16097
|
+
import_node_fs6 = require("fs");
|
|
15469
16098
|
__name(writeFileIfChanged, "writeFileIfChanged");
|
|
15470
16099
|
}
|
|
15471
16100
|
});
|
|
@@ -15566,11 +16195,11 @@ var init_type_generator = __esm({
|
|
|
15566
16195
|
routeGroups.get(key).push(route);
|
|
15567
16196
|
}
|
|
15568
16197
|
const nestedStructure = {};
|
|
15569
|
-
for (const [
|
|
16198
|
+
for (const [path31, routeList] of routeGroups) {
|
|
15570
16199
|
const route = routeList[0];
|
|
15571
16200
|
const importPath = this.getRouteImportPath(route, options.outFile);
|
|
15572
16201
|
const routeName = this.pathToRouteName(route.path);
|
|
15573
|
-
const cleanPath =
|
|
16202
|
+
const cleanPath = path31 === "/api" ? "" : path31.replace(/^\/api\//, "");
|
|
15574
16203
|
const parts = cleanPath ? cleanPath.split("/") : [];
|
|
15575
16204
|
const allMethods = routeList.flatMap((r) => r.methods);
|
|
15576
16205
|
for (const method of allMethods) {
|
|
@@ -15629,8 +16258,8 @@ ${typeExports}
|
|
|
15629
16258
|
const relativeImport = (0, import_path10.relative)((0, import_path10.dirname)(outFile), route.filePath).replace(/\\/g, "/").replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
15630
16259
|
return relativeImport.startsWith(".") ? relativeImport : `./${relativeImport}`;
|
|
15631
16260
|
}
|
|
15632
|
-
pathToRouteName(
|
|
15633
|
-
return (
|
|
16261
|
+
pathToRouteName(path31) {
|
|
16262
|
+
return (path31 === "/api" ? "root" : path31.replace(/^\/api\//, "")).replace(/\//g, "_").replace(/[^a-zA-Z0-9_]/g, "");
|
|
15634
16263
|
}
|
|
15635
16264
|
structureToTypeString(obj, indent) {
|
|
15636
16265
|
const spaces = " ".repeat(indent);
|
|
@@ -15650,15 +16279,15 @@ ${typeExports}
|
|
|
15650
16279
|
toTypePropertyKey(key) {
|
|
15651
16280
|
return /^[$A-Z_][0-9A-Z_$]*$/i.test(key) ? key : JSON.stringify(key);
|
|
15652
16281
|
}
|
|
15653
|
-
getBaseExportName(
|
|
15654
|
-
const cleanPath =
|
|
16282
|
+
getBaseExportName(path31) {
|
|
16283
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
15655
16284
|
if (cleanPath === "") {
|
|
15656
16285
|
return "api";
|
|
15657
16286
|
}
|
|
15658
16287
|
return cleanPath;
|
|
15659
16288
|
}
|
|
15660
|
-
getExportName(
|
|
15661
|
-
const cleanPath =
|
|
16289
|
+
getExportName(path31, method) {
|
|
16290
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
15662
16291
|
if (cleanPath === "") {
|
|
15663
16292
|
return method.toLowerCase();
|
|
15664
16293
|
}
|
|
@@ -15720,12 +16349,12 @@ function createRoutePattern(route) {
|
|
|
15720
16349
|
}).join("/");
|
|
15721
16350
|
}
|
|
15722
16351
|
async function generateRouteTypes(options) {
|
|
15723
|
-
const root =
|
|
16352
|
+
const root = path20.resolve(options.root);
|
|
15724
16353
|
const srcDir = options.srcDir || "src";
|
|
15725
16354
|
const outFile = options.outFile || DEFAULT_OUT_FILE;
|
|
15726
|
-
const outPath =
|
|
16355
|
+
const outPath = path20.isAbsolute(outFile) ? outFile : path20.join(root, srcDir, outFile);
|
|
15727
16356
|
const content = await createRouteTypeDeclarations(options, outPath);
|
|
15728
|
-
fs5.mkdirSync(
|
|
16357
|
+
fs5.mkdirSync(path20.dirname(outPath), { recursive: true });
|
|
15729
16358
|
writeFileIfChanged(outPath, content);
|
|
15730
16359
|
return outPath;
|
|
15731
16360
|
}
|
|
@@ -15733,39 +16362,48 @@ async function createRouteTypeDeclarations(options, outPath) {
|
|
|
15733
16362
|
const { root, srcDir = "src", extraRoutes = [], suppressLintOnLink = false } = options;
|
|
15734
16363
|
const sourceRoots = options.sourceRoots ?? [{ name: "project", root, srcDir, layer: false }];
|
|
15735
16364
|
const patterns = /* @__PURE__ */ new Set();
|
|
16365
|
+
const routeModulePatterns = /* @__PURE__ */ new Set();
|
|
15736
16366
|
const glob = await import("fast-glob");
|
|
15737
16367
|
for (const source of sourceRoots) {
|
|
15738
|
-
const appDir =
|
|
16368
|
+
const appDir = path20.join(source.root, source.srcDir, "app");
|
|
15739
16369
|
if (fs5.existsSync(appDir)) {
|
|
15740
|
-
const
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
|
|
16370
|
+
const routeModuleFiles = await glob.default(
|
|
16371
|
+
"**/{page,layout,loading,error}.{ts,tsx,js,jsx,md,mdx}",
|
|
16372
|
+
{
|
|
16373
|
+
cwd: appDir,
|
|
16374
|
+
absolute: false
|
|
16375
|
+
}
|
|
16376
|
+
);
|
|
16377
|
+
for (const file of routeModuleFiles) {
|
|
15745
16378
|
if (parseRouteSlotFile(file)) continue;
|
|
15746
16379
|
const route = parseRoutePath(file);
|
|
16380
|
+
const pattern = createRoutePattern(route);
|
|
16381
|
+
routeModulePatterns.add(pattern);
|
|
15747
16382
|
if (route.type === "page") {
|
|
15748
|
-
const pattern = createRoutePattern(route);
|
|
15749
16383
|
patterns.add(pattern);
|
|
15750
16384
|
}
|
|
15751
16385
|
}
|
|
15752
16386
|
}
|
|
15753
16387
|
for (const route of await discoverProgrammaticRoutePaths(source.root, source.srcDir)) {
|
|
15754
16388
|
patterns.add(route);
|
|
16389
|
+
routeModulePatterns.add(route);
|
|
15755
16390
|
}
|
|
15756
16391
|
}
|
|
15757
16392
|
for (const route of extraRoutes) {
|
|
15758
16393
|
if (route.startsWith("/")) {
|
|
15759
16394
|
patterns.add(route);
|
|
16395
|
+
routeModulePatterns.add(route);
|
|
15760
16396
|
}
|
|
15761
16397
|
}
|
|
15762
16398
|
const sortedPatterns = Array.from(patterns).sort();
|
|
15763
16399
|
const typeLiterals = Array.from(new Set(sortedPatterns.flatMap(routePatternToTsTypeLiterals)));
|
|
15764
16400
|
const patternLiterals = sortedPatterns.map(routePatternToRouteLiteral);
|
|
16401
|
+
const routeModulePatternLiterals = Array.from(routeModulePatterns).sort().map(routePatternToRouteLiteral);
|
|
15765
16402
|
const routePathType = suppressLintOnLink ? "string" : typeLiterals.length ? typeLiterals.join(" | ") : "never";
|
|
15766
16403
|
const routePatternType = suppressLintOnLink ? "string" : patternLiterals.length ? patternLiterals.join(" | ") : "never";
|
|
15767
|
-
const
|
|
15768
|
-
const
|
|
16404
|
+
const routeModulePatternType = routeModulePatternLiterals.length ? routeModulePatternLiterals.join(" | ") : "never";
|
|
16405
|
+
const routeTypesImportPath = `./${path20.basename(outPath).replace(/\.d\.ts$/, "")}`;
|
|
16406
|
+
const linkAugmentationBlock = suppressLintOnLink ? "" : `
|
|
15769
16407
|
declare module "@farm.js/core/client" {
|
|
15770
16408
|
interface LinkDefaultRoute {
|
|
15771
16409
|
_: import(${JSON.stringify(routeTypesImportPath)}).RoutePath;
|
|
@@ -15789,22 +16427,33 @@ declare module "@farm.js/core/dist/client.js" {
|
|
|
15789
16427
|
pattern: import(${JSON.stringify(routeTypesImportPath)}).RoutePattern;
|
|
15790
16428
|
}
|
|
15791
16429
|
}
|
|
16430
|
+
`;
|
|
16431
|
+
const routeModuleAugmentationBlock = `
|
|
16432
|
+
declare global {
|
|
16433
|
+
namespace FarmJS {
|
|
16434
|
+
interface RouteRegistry {
|
|
16435
|
+
pattern: import(${JSON.stringify(routeTypesImportPath)}).RouteModulePattern;
|
|
16436
|
+
}
|
|
16437
|
+
}
|
|
16438
|
+
}
|
|
15792
16439
|
`;
|
|
15793
16440
|
const content = `/**
|
|
15794
16441
|
* Auto-generated route types from src/app.
|
|
15795
|
-
* Link href
|
|
16442
|
+
* Link href and route component props are typed automatically from generated declarations.
|
|
16443
|
+
* Regenerated on dev start and when routes change.
|
|
15796
16444
|
* Set suppressLintOnLink: true in farm.config.ts to accept any string on Link href.
|
|
15797
16445
|
*/
|
|
15798
16446
|
export type RoutePath = ${routePathType};
|
|
15799
|
-
export type RoutePattern = ${routePatternType}
|
|
16447
|
+
export type RoutePattern = ${routePatternType};
|
|
16448
|
+
export type RouteModulePattern = ${routeModulePatternType};${linkAugmentationBlock}${routeModuleAugmentationBlock}
|
|
15800
16449
|
`;
|
|
15801
16450
|
return content;
|
|
15802
16451
|
}
|
|
15803
|
-
var
|
|
16452
|
+
var path20, fs5, DEFAULT_OUT_FILE;
|
|
15804
16453
|
var init_generate_route_types = __esm({
|
|
15805
16454
|
"src/routing/generate-route-types.ts"() {
|
|
15806
16455
|
"use strict";
|
|
15807
|
-
|
|
16456
|
+
path20 = __toESM(require("path"));
|
|
15808
16457
|
fs5 = __toESM(require("fs"));
|
|
15809
16458
|
init_utils();
|
|
15810
16459
|
init_route_slots();
|
|
@@ -15822,17 +16471,17 @@ var init_generate_route_types = __esm({
|
|
|
15822
16471
|
|
|
15823
16472
|
// src/env-types.ts
|
|
15824
16473
|
async function generateEnvTypes(options) {
|
|
15825
|
-
const root =
|
|
16474
|
+
const root = path21.resolve(options.root);
|
|
15826
16475
|
const srcDir = options.srcDir || "src";
|
|
15827
16476
|
const outFile = options.outFile || DEFAULT_OUT_FILE2;
|
|
15828
|
-
const outPath =
|
|
16477
|
+
const outPath = path21.isAbsolute(outFile) ? outFile : path21.join(root, srcDir, outFile);
|
|
15829
16478
|
const content = createEnvTypeDeclarations(options, outPath);
|
|
15830
|
-
fs6.mkdirSync(
|
|
16479
|
+
fs6.mkdirSync(path21.dirname(outPath), { recursive: true });
|
|
15831
16480
|
writeFileIfChanged(outPath, content);
|
|
15832
16481
|
return outPath;
|
|
15833
16482
|
}
|
|
15834
16483
|
function createEnvTypeDeclarations(options, outPath) {
|
|
15835
|
-
const root =
|
|
16484
|
+
const root = path21.resolve(options.root);
|
|
15836
16485
|
const configPath = findConfigPath(root, options.configPath);
|
|
15837
16486
|
const configPaths = [
|
|
15838
16487
|
...(options.layerConfigPaths ?? []).filter((value) => fs6.existsSync(value)),
|
|
@@ -15895,11 +16544,11 @@ export {};
|
|
|
15895
16544
|
}
|
|
15896
16545
|
function findConfigPath(root, configPath) {
|
|
15897
16546
|
if (configPath) {
|
|
15898
|
-
const resolvedPath =
|
|
16547
|
+
const resolvedPath = path21.isAbsolute(configPath) ? configPath : path21.join(root, configPath);
|
|
15899
16548
|
return fs6.existsSync(resolvedPath) ? resolvedPath : null;
|
|
15900
16549
|
}
|
|
15901
16550
|
for (const filename of CONFIG_FILENAMES2) {
|
|
15902
|
-
const resolvedPath =
|
|
16551
|
+
const resolvedPath = path21.join(root, filename);
|
|
15903
16552
|
if (fs6.existsSync(resolvedPath)) {
|
|
15904
16553
|
return resolvedPath;
|
|
15905
16554
|
}
|
|
@@ -15960,15 +16609,15 @@ export {};
|
|
|
15960
16609
|
`;
|
|
15961
16610
|
}
|
|
15962
16611
|
function toTypeImportPath(outPath, targetPath) {
|
|
15963
|
-
const relativePath2 =
|
|
16612
|
+
const relativePath2 = path21.relative(path21.dirname(outPath), targetPath).replace(/\\/g, "/").replace(/\.(tsx?|jsx?|mjs|cjs|mts|cts)$/, "");
|
|
15964
16613
|
return relativePath2.startsWith(".") ? relativePath2 : `./${relativePath2}`;
|
|
15965
16614
|
}
|
|
15966
|
-
var fs6,
|
|
16615
|
+
var fs6, path21, DEFAULT_OUT_FILE2, CONFIG_FILENAMES2;
|
|
15967
16616
|
var init_env_types = __esm({
|
|
15968
16617
|
"src/env-types.ts"() {
|
|
15969
16618
|
"use strict";
|
|
15970
16619
|
fs6 = __toESM(require("fs"));
|
|
15971
|
-
|
|
16620
|
+
path21 = __toESM(require("path"));
|
|
15972
16621
|
init_write_file_if_changed();
|
|
15973
16622
|
DEFAULT_OUT_FILE2 = "farm-env.d.ts";
|
|
15974
16623
|
CONFIG_FILENAMES2 = [
|
|
@@ -16001,8 +16650,8 @@ var init_env_types = __esm({
|
|
|
16001
16650
|
|
|
16002
16651
|
// src/image-types.ts
|
|
16003
16652
|
function generateFarmImageTypes(options) {
|
|
16004
|
-
const outputPath = options.outFile ?
|
|
16005
|
-
(0,
|
|
16653
|
+
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");
|
|
16654
|
+
(0, import_node_fs7.mkdirSync)(import_node_path9.default.dirname(outputPath), { recursive: true });
|
|
16006
16655
|
writeFileIfChanged(outputPath, createFarmImageTypeDeclarations());
|
|
16007
16656
|
return outputPath;
|
|
16008
16657
|
}
|
|
@@ -16026,12 +16675,12 @@ declare module "*?url" {
|
|
|
16026
16675
|
}
|
|
16027
16676
|
`;
|
|
16028
16677
|
}
|
|
16029
|
-
var
|
|
16678
|
+
var import_node_fs7, import_node_path9, FARM_STATIC_IMAGE_EXTENSIONS;
|
|
16030
16679
|
var init_image_types = __esm({
|
|
16031
16680
|
"src/image-types.ts"() {
|
|
16032
16681
|
"use strict";
|
|
16033
|
-
|
|
16034
|
-
|
|
16682
|
+
import_node_fs7 = require("fs");
|
|
16683
|
+
import_node_path9 = __toESM(require("path"));
|
|
16035
16684
|
init_write_file_if_changed();
|
|
16036
16685
|
FARM_STATIC_IMAGE_EXTENSIONS = ["avif", "gif", "jpeg", "jpg", "png", "webp"];
|
|
16037
16686
|
__name(generateFarmImageTypes, "generateFarmImageTypes");
|
|
@@ -16043,9 +16692,9 @@ var init_image_types = __esm({
|
|
|
16043
16692
|
async function generateFarmI18nTypes(options) {
|
|
16044
16693
|
if (!options.config.enabled) return void 0;
|
|
16045
16694
|
const { signatures } = await readFarmI18nCatalogs(options.config);
|
|
16046
|
-
const outFile = options.outFile ? (0,
|
|
16695
|
+
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");
|
|
16047
16696
|
const content = renderFarmI18nTypes(options.config.locales, signatures);
|
|
16048
|
-
(0,
|
|
16697
|
+
(0, import_node_fs8.mkdirSync)((0, import_node_path10.dirname)(outFile), { recursive: true });
|
|
16049
16698
|
writeFileIfChanged(outFile, content);
|
|
16050
16699
|
return outFile;
|
|
16051
16700
|
}
|
|
@@ -16086,12 +16735,12 @@ function argumentType(kind) {
|
|
|
16086
16735
|
return "string";
|
|
16087
16736
|
}
|
|
16088
16737
|
}
|
|
16089
|
-
var
|
|
16738
|
+
var import_node_fs8, import_node_path10;
|
|
16090
16739
|
var init_type_generator2 = __esm({
|
|
16091
16740
|
"src/i18n/type-generator.ts"() {
|
|
16092
16741
|
"use strict";
|
|
16093
|
-
|
|
16094
|
-
|
|
16742
|
+
import_node_fs8 = require("fs");
|
|
16743
|
+
import_node_path10 = require("path");
|
|
16095
16744
|
init_catalog();
|
|
16096
16745
|
init_write_file_if_changed();
|
|
16097
16746
|
__name(generateFarmI18nTypes, "generateFarmI18nTypes");
|
|
@@ -16246,7 +16895,7 @@ var init_type_artifacts = __esm({
|
|
|
16246
16895
|
var version;
|
|
16247
16896
|
var init_package = __esm({
|
|
16248
16897
|
"package.json"() {
|
|
16249
|
-
version = "0.1.0-beta.
|
|
16898
|
+
version = "0.1.0-beta.14";
|
|
16250
16899
|
}
|
|
16251
16900
|
});
|
|
16252
16901
|
|
|
@@ -16426,12 +17075,12 @@ async function createBlurDataURL(bytes) {
|
|
|
16426
17075
|
return void 0;
|
|
16427
17076
|
}
|
|
16428
17077
|
}
|
|
16429
|
-
var import_promises7,
|
|
17078
|
+
var import_promises7, import_node_path11, import_image_size2, FARM_IMAGE_ID_PREFIX, STATIC_IMAGE_RE, SCRIPT_IMPORTER_RE;
|
|
16430
17079
|
var init_image_vite = __esm({
|
|
16431
17080
|
"src/image-vite.ts"() {
|
|
16432
17081
|
"use strict";
|
|
16433
17082
|
import_promises7 = require("fs/promises");
|
|
16434
|
-
|
|
17083
|
+
import_node_path11 = __toESM(require("path"));
|
|
16435
17084
|
import_image_size2 = require("image-size");
|
|
16436
17085
|
FARM_IMAGE_ID_PREFIX = "\0farm:image:";
|
|
16437
17086
|
STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
|
|
@@ -16442,6 +17091,22 @@ var init_image_vite = __esm({
|
|
|
16442
17091
|
}
|
|
16443
17092
|
});
|
|
16444
17093
|
|
|
17094
|
+
// src/font.ts
|
|
17095
|
+
function resolveFarmLayoutFonts(layouts) {
|
|
17096
|
+
let resolved;
|
|
17097
|
+
for (const layout2 of layouts) {
|
|
17098
|
+
if (!layout2.fonts) continue;
|
|
17099
|
+
resolved = { ...resolved, ...layout2.fonts };
|
|
17100
|
+
}
|
|
17101
|
+
return resolved;
|
|
17102
|
+
}
|
|
17103
|
+
var init_font = __esm({
|
|
17104
|
+
"src/font.ts"() {
|
|
17105
|
+
"use strict";
|
|
17106
|
+
__name(resolveFarmLayoutFonts, "resolveFarmLayoutFonts");
|
|
17107
|
+
}
|
|
17108
|
+
});
|
|
17109
|
+
|
|
16445
17110
|
// src/image-server.ts
|
|
16446
17111
|
function createFarmImageHandler(config, options) {
|
|
16447
17112
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
@@ -16858,6 +17523,106 @@ var init_image_server = __esm({
|
|
|
16858
17523
|
}
|
|
16859
17524
|
});
|
|
16860
17525
|
|
|
17526
|
+
// src/server/vite-config.ts
|
|
17527
|
+
function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
|
|
17528
|
+
const resolvedProjectRoot = import_node_path12.default.resolve(projectRoot);
|
|
17529
|
+
return appDirectories.map((appDirectory) => {
|
|
17530
|
+
const relativeAppDirectory = import_node_path12.default.relative(resolvedProjectRoot, import_node_path12.default.resolve(appDirectory)).replace(/\\/g, "/");
|
|
17531
|
+
const prefix = relativeAppDirectory || ".";
|
|
17532
|
+
return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
|
|
17533
|
+
});
|
|
17534
|
+
}
|
|
17535
|
+
function createFarmClientOptimizeDepsConfig(entries) {
|
|
17536
|
+
return {
|
|
17537
|
+
// Keep normal application dependency discovery for CJS-only packages, but
|
|
17538
|
+
// seed every Farm browser runtime so React is present in the first crawl.
|
|
17539
|
+
noDiscovery: false,
|
|
17540
|
+
// Waiting for the crawl avoids serving a partial optimizer generation and
|
|
17541
|
+
// then changing browser hashes while hydration is already in progress.
|
|
17542
|
+
holdUntilCrawlEnd: true,
|
|
17543
|
+
include: [...FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE],
|
|
17544
|
+
// Farm's HTML boots through a virtual module and imports route UI lazily.
|
|
17545
|
+
// Explicit entries let Vite finish that crawl before a navigation can
|
|
17546
|
+
// rotate the optimizer hash underneath a hydrated React runtime.
|
|
17547
|
+
...entries?.length ? { entries: [...entries] } : {}
|
|
17548
|
+
};
|
|
17549
|
+
}
|
|
17550
|
+
function mergeNoExternal(farmValue, userValue) {
|
|
17551
|
+
if (farmValue === true || userValue === true) return true;
|
|
17552
|
+
const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
|
|
17553
|
+
return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
|
|
17554
|
+
}
|
|
17555
|
+
function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
17556
|
+
const noDiscovery = userConfig.optimizeDeps?.noDiscovery ?? farmConfig.optimizeDeps?.noDiscovery;
|
|
17557
|
+
const holdUntilCrawlEnd = userConfig.optimizeDeps?.holdUntilCrawlEnd ?? (userConfig.optimizeDeps?.noDiscovery === true ? false : farmConfig.optimizeDeps?.holdUntilCrawlEnd);
|
|
17558
|
+
return {
|
|
17559
|
+
...farmConfig,
|
|
17560
|
+
...userConfig,
|
|
17561
|
+
plugins: [...farmConfig.plugins || [], ...userConfig.plugins || []],
|
|
17562
|
+
server: {
|
|
17563
|
+
...farmConfig.server,
|
|
17564
|
+
...userConfig.server
|
|
17565
|
+
},
|
|
17566
|
+
resolve: {
|
|
17567
|
+
...farmConfig.resolve,
|
|
17568
|
+
...userConfig.resolve,
|
|
17569
|
+
dedupe: Array.from(
|
|
17570
|
+
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
17571
|
+
)
|
|
17572
|
+
},
|
|
17573
|
+
optimizeDeps: {
|
|
17574
|
+
...farmConfig.optimizeDeps,
|
|
17575
|
+
...userConfig.optimizeDeps,
|
|
17576
|
+
noDiscovery,
|
|
17577
|
+
holdUntilCrawlEnd,
|
|
17578
|
+
include: Array.from(
|
|
17579
|
+
/* @__PURE__ */ new Set([
|
|
17580
|
+
...farmConfig.optimizeDeps?.include || [],
|
|
17581
|
+
...userConfig.optimizeDeps?.include || []
|
|
17582
|
+
])
|
|
17583
|
+
),
|
|
17584
|
+
exclude: Array.from(
|
|
17585
|
+
/* @__PURE__ */ new Set([
|
|
17586
|
+
...farmConfig.optimizeDeps?.exclude || [],
|
|
17587
|
+
...userConfig.optimizeDeps?.exclude || []
|
|
17588
|
+
])
|
|
17589
|
+
)
|
|
17590
|
+
},
|
|
17591
|
+
ssr: {
|
|
17592
|
+
...farmConfig.ssr,
|
|
17593
|
+
...userConfig.ssr,
|
|
17594
|
+
noExternal: mergeNoExternal(farmConfig.ssr?.noExternal, userConfig.ssr?.noExternal)
|
|
17595
|
+
}
|
|
17596
|
+
};
|
|
17597
|
+
}
|
|
17598
|
+
var import_node_path12, FARM_CLIENT_ENTRY_PATTERN, FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE;
|
|
17599
|
+
var init_vite_config = __esm({
|
|
17600
|
+
"src/server/vite-config.ts"() {
|
|
17601
|
+
"use strict";
|
|
17602
|
+
import_node_path12 = __toESM(require("path"));
|
|
17603
|
+
FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
|
|
17604
|
+
FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
|
|
17605
|
+
"react",
|
|
17606
|
+
"react-dom",
|
|
17607
|
+
"react-dom/client",
|
|
17608
|
+
"react/jsx-runtime",
|
|
17609
|
+
"react/jsx-dev-runtime",
|
|
17610
|
+
"@farm.js/core/client",
|
|
17611
|
+
"@farm.js/core/plugin/client",
|
|
17612
|
+
"@farm.js/core/deferred",
|
|
17613
|
+
"@farm.js/core/deployment",
|
|
17614
|
+
"@farm.js/core/i18n/client",
|
|
17615
|
+
"@farm.js/core/query/client",
|
|
17616
|
+
"@farm.js/core/server-fn/client",
|
|
17617
|
+
"@farm.js/core/server-query/client"
|
|
17618
|
+
];
|
|
17619
|
+
__name(createFarmClientOptimizeDepsEntries, "createFarmClientOptimizeDepsEntries");
|
|
17620
|
+
__name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
|
|
17621
|
+
__name(mergeNoExternal, "mergeNoExternal");
|
|
17622
|
+
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
17623
|
+
}
|
|
17624
|
+
});
|
|
17625
|
+
|
|
16861
17626
|
// src/docs/pixel-border-css.ts
|
|
16862
17627
|
var farmDocsPixelBorderCss;
|
|
16863
17628
|
var init_pixel_border_css = __esm({
|
|
@@ -16903,8 +17668,8 @@ var init_pixel_border_css = __esm({
|
|
|
16903
17668
|
--scrollbar-thumb-hover: var(--color-fd-ring);
|
|
16904
17669
|
--scrollbar-track: transparent;
|
|
16905
17670
|
--radius: 0px;
|
|
16906
|
-
--font-geist-sans:
|
|
16907
|
-
--font-geist-mono:
|
|
17671
|
+
--font-geist-sans: ui-sans-serif, system-ui, sans-serif;
|
|
17672
|
+
--font-geist-mono: ui-monospace, monospace;
|
|
16908
17673
|
}
|
|
16909
17674
|
|
|
16910
17675
|
.dark {
|
|
@@ -16917,28 +17682,6 @@ body,
|
|
|
16917
17682
|
background-color: var(--color-fd-background) !important;
|
|
16918
17683
|
}
|
|
16919
17684
|
|
|
16920
|
-
@font-face {
|
|
16921
|
-
font-family: "Geist Sans";
|
|
16922
|
-
font-display: block;
|
|
16923
|
-
font-style: normal;
|
|
16924
|
-
font-weight: 100 900;
|
|
16925
|
-
src:
|
|
16926
|
-
local("Geist Sans"),
|
|
16927
|
-
url("/assets/Geist-Variable-CrgPqtmy.woff2") format("woff2"),
|
|
16928
|
-
url("/node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2") format("woff2");
|
|
16929
|
-
}
|
|
16930
|
-
|
|
16931
|
-
@font-face {
|
|
16932
|
-
font-family: "Geist Mono";
|
|
16933
|
-
font-display: block;
|
|
16934
|
-
font-style: normal;
|
|
16935
|
-
font-weight: 100 900;
|
|
16936
|
-
src:
|
|
16937
|
-
local("Geist Mono"),
|
|
16938
|
-
url("/assets/GeistMono-Variable-BNLlm6Cd.woff2") format("woff2"),
|
|
16939
|
-
url("/node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2");
|
|
16940
|
-
}
|
|
16941
|
-
|
|
16942
17685
|
* {
|
|
16943
17686
|
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
|
|
16944
17687
|
scrollbar-width: thin;
|
|
@@ -18129,11 +18872,418 @@ code:not(pre code) {
|
|
|
18129
18872
|
}
|
|
18130
18873
|
});
|
|
18131
18874
|
|
|
18875
|
+
// src/docs/social-image.ts
|
|
18876
|
+
function normalizeEntry(entry) {
|
|
18877
|
+
if (!entry || entry === "/") return "";
|
|
18878
|
+
return `/${entry.replace(/^\/+|\/+$/g, "")}`;
|
|
18879
|
+
}
|
|
18880
|
+
function encodeSlugPath(slug) {
|
|
18881
|
+
return slug.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
|
|
18882
|
+
}
|
|
18883
|
+
function getSocialImageConfig(docs) {
|
|
18884
|
+
return typeof docs.config.socialImage === "object" && docs.config.socialImage ? docs.config.socialImage : void 0;
|
|
18885
|
+
}
|
|
18886
|
+
function getNavTitle(docs) {
|
|
18887
|
+
if (typeof docs.config.nav !== "object" || !docs.config.nav || !("title" in docs.config.nav)) {
|
|
18888
|
+
return "Farm.js";
|
|
18889
|
+
}
|
|
18890
|
+
return String(docs.config.nav.title || "Farm.js");
|
|
18891
|
+
}
|
|
18892
|
+
function isFalse(value) {
|
|
18893
|
+
return value ? /^(false|no|none|off|disabled)$/i.test(value.trim()) : false;
|
|
18894
|
+
}
|
|
18895
|
+
function isExternalOrRootPath(value) {
|
|
18896
|
+
return /^(https?:)?\/\//i.test(value) || value.startsWith("/");
|
|
18897
|
+
}
|
|
18898
|
+
function isFarmDocsSocialImageEnabled(page2, docs) {
|
|
18899
|
+
if (docs.config.socialImage === false || getSocialImageConfig(docs)?.enabled === false) {
|
|
18900
|
+
return false;
|
|
18901
|
+
}
|
|
18902
|
+
return !isFalse(page2.frontmatter.socialImage);
|
|
18903
|
+
}
|
|
18904
|
+
function getFarmDocsCustomSocialImage(page2) {
|
|
18905
|
+
const value = page2.frontmatter.socialImage || page2.frontmatter.openGraphImage || page2.frontmatter.ogImage;
|
|
18906
|
+
return value && !isFalse(value) && isExternalOrRootPath(value) ? value : void 0;
|
|
18907
|
+
}
|
|
18908
|
+
function resolveIllustration(page2) {
|
|
18909
|
+
const explicit = page2.frontmatter.socialIllustration?.toLowerCase();
|
|
18910
|
+
if (explicit === "auth" || explicit === "cache" || explicit === "cli" || explicit === "integrations" || explicit === "project" || explicit === "routing" || explicit === "runtime") {
|
|
18911
|
+
return explicit;
|
|
18912
|
+
}
|
|
18913
|
+
const source = `${page2.slug} ${page2.title} ${page2.section || ""}`.toLowerCase();
|
|
18914
|
+
if (/auth|session|security|csrf/.test(source)) return "auth";
|
|
18915
|
+
if (/cache|ppr|render|static|revalid|stream/.test(source)) return "cache";
|
|
18916
|
+
if (/integration|stripe|prisma|better.auth|email|job|workflow/.test(source)) {
|
|
18917
|
+
return "integrations";
|
|
18918
|
+
}
|
|
18919
|
+
if (/cli|test|deploy|preview|upgrade|migration|install/.test(source)) return "cli";
|
|
18920
|
+
if (/project|structure|config|environment|markdown|docs.engine/.test(source)) {
|
|
18921
|
+
return "project";
|
|
18922
|
+
}
|
|
18923
|
+
if (/rout|endpoint|middleware|navigation|server.function|server.action|api/.test(source)) {
|
|
18924
|
+
return "routing";
|
|
18925
|
+
}
|
|
18926
|
+
return "runtime";
|
|
18927
|
+
}
|
|
18928
|
+
function createHashValue(value) {
|
|
18929
|
+
return (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 16);
|
|
18930
|
+
}
|
|
18931
|
+
function resolveBaseUrl(requestUrl, config) {
|
|
18932
|
+
return config?.baseUrl ? new URL(config.baseUrl) : new URL(requestUrl.origin);
|
|
18933
|
+
}
|
|
18934
|
+
function createFarmDocsSocialImageDescriptor(page2, docs, requestUrl) {
|
|
18935
|
+
const config = getSocialImageConfig(docs);
|
|
18936
|
+
const siteName = config?.siteName || getNavTitle(docs);
|
|
18937
|
+
const brand = config?.brand || siteName;
|
|
18938
|
+
const title = page2.frontmatter.socialTitle || page2.title;
|
|
18939
|
+
const description = page2.frontmatter.socialDescription || page2.description || docs.config.metadata?.description || `Documentation for ${siteName}`;
|
|
18940
|
+
const section = page2.frontmatter.section || page2.section || "Documentation";
|
|
18941
|
+
const illustration = resolveIllustration(page2);
|
|
18942
|
+
const entry = normalizeEntry(docs.entry);
|
|
18943
|
+
const slugPath = encodeSlugPath(page2.slug) || "index";
|
|
18944
|
+
const imagePath = `${entry}/_social/${slugPath}/opengraph-image.svg`;
|
|
18945
|
+
const baseUrl = resolveBaseUrl(requestUrl, config);
|
|
18946
|
+
const pageUrl = new URL(page2.href, baseUrl).href;
|
|
18947
|
+
const imageAlt = `${title} \u2014 ${siteName} documentation`;
|
|
18948
|
+
const hash = createHashValue({
|
|
18949
|
+
version: FARM_DOCS_SOCIAL_IMAGE_VERSION,
|
|
18950
|
+
title,
|
|
18951
|
+
description,
|
|
18952
|
+
section,
|
|
18953
|
+
siteName,
|
|
18954
|
+
brand,
|
|
18955
|
+
pageHref: page2.href,
|
|
18956
|
+
illustration,
|
|
18957
|
+
fonts: config?.fonts
|
|
18958
|
+
});
|
|
18959
|
+
return {
|
|
18960
|
+
title,
|
|
18961
|
+
description,
|
|
18962
|
+
section,
|
|
18963
|
+
siteName,
|
|
18964
|
+
brand,
|
|
18965
|
+
pageHref: page2.href,
|
|
18966
|
+
pageUrl,
|
|
18967
|
+
imagePath,
|
|
18968
|
+
imageUrl: new URL(`${imagePath}?v=${hash}`, baseUrl).href,
|
|
18969
|
+
imageAlt,
|
|
18970
|
+
illustration,
|
|
18971
|
+
fonts: config?.fonts,
|
|
18972
|
+
hash
|
|
18973
|
+
};
|
|
18974
|
+
}
|
|
18975
|
+
function getFarmDocsSocialImageSlug(docs, requestUrl) {
|
|
18976
|
+
const entry = normalizeEntry(docs.entry);
|
|
18977
|
+
const prefix = `${entry}/_social/`;
|
|
18978
|
+
const suffix = "/opengraph-image.svg";
|
|
18979
|
+
if (!requestUrl.pathname.startsWith(prefix) || !requestUrl.pathname.endsWith(suffix)) {
|
|
18980
|
+
return null;
|
|
18981
|
+
}
|
|
18982
|
+
const rawSlug = requestUrl.pathname.slice(prefix.length, -suffix.length);
|
|
18983
|
+
if (!rawSlug) return null;
|
|
18984
|
+
try {
|
|
18985
|
+
const slug = rawSlug.split("/").map((segment) => decodeURIComponent(segment)).join("/");
|
|
18986
|
+
if (slug.split("/").some((segment) => !segment || segment === ".." || segment === ".")) {
|
|
18987
|
+
return null;
|
|
18988
|
+
}
|
|
18989
|
+
return slug === "index" ? "" : slug;
|
|
18990
|
+
} catch {
|
|
18991
|
+
return null;
|
|
18992
|
+
}
|
|
18993
|
+
}
|
|
18994
|
+
function escapeXml(value) {
|
|
18995
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
18996
|
+
}
|
|
18997
|
+
function truncate(value, length) {
|
|
18998
|
+
if (value.length <= length) return value;
|
|
18999
|
+
return `${value.slice(0, Math.max(0, length - 1)).trimEnd()}\u2026`;
|
|
19000
|
+
}
|
|
19001
|
+
function wrapText(value, maxCharacters, maxLines) {
|
|
19002
|
+
const words = value.trim().split(/\s+/).filter(Boolean);
|
|
19003
|
+
const lines = [];
|
|
19004
|
+
let current = "";
|
|
19005
|
+
let consumedWords = 0;
|
|
19006
|
+
for (const word of words) {
|
|
19007
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
19008
|
+
if (candidate.length <= maxCharacters || !current) {
|
|
19009
|
+
current = candidate;
|
|
19010
|
+
consumedWords += 1;
|
|
19011
|
+
continue;
|
|
19012
|
+
}
|
|
19013
|
+
lines.push(current);
|
|
19014
|
+
if (lines.length === maxLines) break;
|
|
19015
|
+
current = word;
|
|
19016
|
+
consumedWords += 1;
|
|
19017
|
+
}
|
|
19018
|
+
if (current && lines.length < maxLines) lines.push(current);
|
|
19019
|
+
if (consumedWords < words.length && lines.length) {
|
|
19020
|
+
lines[lines.length - 1] = truncate(`${lines[lines.length - 1]}\u2026`, maxCharacters);
|
|
19021
|
+
}
|
|
19022
|
+
return lines;
|
|
19023
|
+
}
|
|
19024
|
+
function renderTextLines(lines, x, y, lineHeight, attributes) {
|
|
19025
|
+
return lines.map(
|
|
19026
|
+
(line, index) => `<text x="${x}" y="${y + index * lineHeight}" ${attributes}>${escapeXml(line)}</text>`
|
|
19027
|
+
).join("");
|
|
19028
|
+
}
|
|
19029
|
+
function renderEmbeddedFont(name, source, weight) {
|
|
19030
|
+
if (!source) return "";
|
|
19031
|
+
return `@font-face{font-family:"${name}";src:url("${escapeXml(source)}") format("woff2");font-style:normal;font-weight:${weight};font-display:block;}`;
|
|
19032
|
+
}
|
|
19033
|
+
function renderArrow(x1, y, x2, color = "#8b8b8b") {
|
|
19034
|
+
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}"/>`;
|
|
19035
|
+
}
|
|
19036
|
+
function renderPanelHeader(label, status) {
|
|
19037
|
+
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>`;
|
|
19038
|
+
}
|
|
19039
|
+
function renderRoutingIllustration() {
|
|
19040
|
+
return `${renderPanelHeader("ROUTE BLUEPRINT", "TYPED")}
|
|
19041
|
+
<rect x="819" y="296" width="92" height="54" fill="#a3a3a3"/>
|
|
19042
|
+
<text x="832" y="327" class="diagram-title ink">src/app</text>
|
|
19043
|
+
<path d="M911 323h41M952 232v181M952 232h44M952 323h44M952 413h44" fill="none" stroke="#696969"/>
|
|
19044
|
+
<rect x="996" y="205" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
|
|
19045
|
+
<text x="1010" y="228" class="diagram-title">/</text><text x="1010" y="246" class="micro">STATIC</text>
|
|
19046
|
+
<rect x="996" y="296" width="138" height="54" fill="#0a0a0a" stroke="#414141"/>
|
|
19047
|
+
<text x="1010" y="319" class="diagram-title">/blog/:slug</text><text x="1010" y="337" class="micro">DYNAMIC</text>
|
|
19048
|
+
<rect x="996" y="386" width="138" height="55" fill="#f0f0f0"/>
|
|
19049
|
+
<text x="1010" y="410" class="diagram-title ink">/docs/:path*</text><text x="1010" y="428" class="micro ink-muted">CATCH-ALL</text>
|
|
19050
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19051
|
+
<text x="819" y="475" class="label bright">FILE ROUTES</text><text x="1134" y="475" class="label" text-anchor="end">TYPES INCLUDED</text>`;
|
|
19052
|
+
}
|
|
19053
|
+
function renderAuthIllustration() {
|
|
19054
|
+
return `${renderPanelHeader("REQUEST GUARD", "SERVER VERIFIED")}
|
|
19055
|
+
<rect x="819" y="269" width="86" height="54" fill="#0a0a0a" stroke="#454545"/>
|
|
19056
|
+
<text x="837" y="292" class="micro bright">REQUEST</text><text x="837" y="310" class="diagram-title">GET /app</text>
|
|
19057
|
+
${renderArrow(905, 296, 943)}
|
|
19058
|
+
<rect x="943" y="224" width="104" height="118" fill="#f0f0f0"/>
|
|
19059
|
+
<path d="M974 271v-12a21 21 0 0 1 42 0v12M968 271h54v45h-54z" fill="#050505"/>
|
|
19060
|
+
<circle cx="995" cy="292" r="4" fill="#f0f0f0"/><path d="M995 296v8" stroke="#f0f0f0" stroke-width="3"/>
|
|
19061
|
+
<text x="995" y="332" class="micro ink" text-anchor="middle">auth()</text>
|
|
19062
|
+
${renderArrow(1047, 296, 1071)}
|
|
19063
|
+
<rect x="1071" y="269" width="63" height="54" fill="#0a0a0a" stroke="#454545"/>
|
|
19064
|
+
<text x="1082" y="292" class="micro bright">ALLOW</text><text x="1082" y="310" class="micro">/app</text>
|
|
19065
|
+
<rect x="819" y="372" width="315" height="38" fill="#090909" stroke="#3d3d3d"/>
|
|
19066
|
+
<rect x="832" y="385" width="11" height="11" fill="#a3a3a3"/>
|
|
19067
|
+
<text x="856" y="395" class="code">session.user / verified</text>
|
|
19068
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19069
|
+
<text x="819" y="475" class="label bright">SESSION TYPED</text><text x="1134" y="475" class="label" text-anchor="end">CSRF PROTECTED</text>`;
|
|
19070
|
+
}
|
|
19071
|
+
function renderCacheIllustration() {
|
|
19072
|
+
return `${renderPanelHeader("PAGE / PRODUCT", "CACHE + PPR")}
|
|
19073
|
+
<rect x="819" y="204" width="315" height="54" fill="#f0f0f0"/>
|
|
19074
|
+
<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>
|
|
19075
|
+
<rect x="819" y="271" width="198" height="76" fill="#a3a3a3"/>
|
|
19076
|
+
<text x="836" y="301" class="diagram-title ink">CACHED DATA</text><text x="836" y="326" class="micro ink-muted">tag: products</text>
|
|
19077
|
+
<rect x="1029" y="271" width="105" height="76" fill="#0a0a0a" stroke="#555"/>
|
|
19078
|
+
<text x="1045" y="301" class="diagram-title">LIVE</text><text x="1045" y="326" class="micro">stream</text>
|
|
19079
|
+
<path d="M1081 347v43m-8-9 8 9 8-9" fill="none" stroke="#d4d4d4"/>
|
|
19080
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19081
|
+
<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>`;
|
|
19082
|
+
}
|
|
19083
|
+
function renderIntegrationsIllustration() {
|
|
19084
|
+
return `${renderPanelHeader("INTEGRATION GRAPH", "ONE PRODUCT")}
|
|
19085
|
+
<path d="M976 309H879V247M976 309H879v87M1030 309h93V247M1030 309h93v87" fill="none" stroke="#4a4a4a"/>
|
|
19086
|
+
<rect x="819" y="214" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="839" y="247" class="diagram-title">BETTER AUTH</text>
|
|
19087
|
+
<rect x="819" y="368" width="120" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="851" y="401" class="diagram-title">PRISMA</text>
|
|
19088
|
+
<rect x="1061" y="214" width="73" height="57" fill="#0a0a0a" stroke="#4b4b4b"/><text x="1077" y="247" class="diagram-title">STRIPE</text>
|
|
19089
|
+
<rect x="1061" y="368" width="73" height="57" fill="#a3a3a3"/><text x="1075" y="401" class="diagram-title ink">VERCEL</text>
|
|
19090
|
+
<rect x="976" y="277" width="94" height="64" fill="#f0f0f0"/>
|
|
19091
|
+
<text x="994" y="304" class="diagram-title ink">FARM.JS</text><text x="994" y="324" class="micro ink-muted">CORE</text>
|
|
19092
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19093
|
+
<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>`;
|
|
19094
|
+
}
|
|
19095
|
+
function renderCliIllustration() {
|
|
19096
|
+
return `${renderPanelHeader("TERMINAL", "PRODUCTION OUTPUT")}
|
|
19097
|
+
<rect x="819" y="203" width="315" height="213" fill="#050505" stroke="#555"/>
|
|
19098
|
+
<line x1="819" y1="236" x2="1134" y2="236" stroke="#555"/>
|
|
19099
|
+
<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"/>
|
|
19100
|
+
<text x="837" y="273" class="code bright"><tspan fill="#7a7a7a">$</tspan> farm build</text>
|
|
19101
|
+
<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"/>
|
|
19102
|
+
<text x="861" y="303" class="code">64 routes discovered</text>
|
|
19103
|
+
<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"/>
|
|
19104
|
+
<text x="861" y="330" class="code">client + server bundles</text>
|
|
19105
|
+
<rect x="837" y="355" width="126" height="30" fill="#f0f0f0"/><text x="853" y="374" class="micro ink">BUILD COMPLETE</text>
|
|
19106
|
+
<text x="1115" y="374" class="micro" text-anchor="end">/dist</text>
|
|
19107
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19108
|
+
<text x="819" y="475" class="label bright">REAL COMMANDS</text><text x="1134" y="475" class="label" text-anchor="end">842MS</text>`;
|
|
19109
|
+
}
|
|
19110
|
+
function renderProjectIllustration() {
|
|
19111
|
+
return `${renderPanelHeader("PROJECT MAP", "CONVENTION TYPED")}
|
|
19112
|
+
<rect x="819" y="202" width="315" height="216" fill="#050505" stroke="#555"/>
|
|
19113
|
+
<text x="837" y="227" class="diagram-title bright">my-app/</text>
|
|
19114
|
+
<path d="M847 243v143M847 259h23M847 293h23M847 327h23M847 361h23" fill="none" stroke="#666"/>
|
|
19115
|
+
<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>
|
|
19116
|
+
<rect x="870" y="277" width="246" height="33" fill="#f0f0f0"/><text x="886" y="298" class="code ink">src/app/page.tsx</text>
|
|
19117
|
+
<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>
|
|
19118
|
+
<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>
|
|
19119
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19120
|
+
<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>`;
|
|
19121
|
+
}
|
|
19122
|
+
function renderRuntimeIllustration() {
|
|
19123
|
+
return `${renderPanelHeader("PRODUCT ARCHITECTURE", "FULL STACK")}
|
|
19124
|
+
<rect x="819" y="211" width="315" height="55" fill="#f0f0f0"/>
|
|
19125
|
+
<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>
|
|
19126
|
+
<path d="M976 266v20m0 61v20" stroke="#727272"/>
|
|
19127
|
+
<rect x="855" y="286" width="242" height="61" fill="#a3a3a3"/>
|
|
19128
|
+
<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>
|
|
19129
|
+
<rect x="819" y="367" width="315" height="55" fill="#4c4c4c"/>
|
|
19130
|
+
<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>
|
|
19131
|
+
<line x1="819" y1="450" x2="1134" y2="450" stroke="#343434"/>
|
|
19132
|
+
<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>`;
|
|
19133
|
+
}
|
|
19134
|
+
function renderIllustration(type) {
|
|
19135
|
+
switch (type) {
|
|
19136
|
+
case "auth":
|
|
19137
|
+
return renderAuthIllustration();
|
|
19138
|
+
case "cache":
|
|
19139
|
+
return renderCacheIllustration();
|
|
19140
|
+
case "cli":
|
|
19141
|
+
return renderCliIllustration();
|
|
19142
|
+
case "integrations":
|
|
19143
|
+
return renderIntegrationsIllustration();
|
|
19144
|
+
case "project":
|
|
19145
|
+
return renderProjectIllustration();
|
|
19146
|
+
case "routing":
|
|
19147
|
+
return renderRoutingIllustration();
|
|
19148
|
+
default:
|
|
19149
|
+
return renderRuntimeIllustration();
|
|
19150
|
+
}
|
|
19151
|
+
}
|
|
19152
|
+
function renderFarmDocsSocialImageSvg(descriptor) {
|
|
19153
|
+
const titleLines = wrapText(descriptor.title, 22, 2);
|
|
19154
|
+
const longestTitleLine = Math.max(...titleLines.map((line) => line.length));
|
|
19155
|
+
const titleSize = titleLines.length === 1 ? longestTitleLine > 17 ? 62 : 74 : 56;
|
|
19156
|
+
const titleLineHeight = Math.round(titleSize * 0.98);
|
|
19157
|
+
const titleY = titleLines.length === 1 ? 294 : 266;
|
|
19158
|
+
const descriptionY = titleY + (titleLines.length - 1) * titleLineHeight + 59;
|
|
19159
|
+
const descriptionLines = wrapText(descriptor.description, 68, 2);
|
|
19160
|
+
const routeY = Math.max(418, descriptionY + descriptionLines.length * 29 + 24);
|
|
19161
|
+
const section = truncate(descriptor.section.toUpperCase(), 27);
|
|
19162
|
+
const route = truncate(descriptor.pageHref, 42);
|
|
19163
|
+
const footerUrl = truncate(descriptor.pageUrl.replace(/^https?:\/\//, ""), 70);
|
|
19164
|
+
const brand = truncate(descriptor.brand.toUpperCase(), 25);
|
|
19165
|
+
const titleId = `farm-docs-og-${descriptor.hash}`;
|
|
19166
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
19167
|
+
<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">
|
|
19168
|
+
<title id="${titleId}-title">${escapeXml(descriptor.imageAlt)}</title>
|
|
19169
|
+
<desc id="${titleId}-description">${escapeXml(descriptor.description)}</desc>
|
|
19170
|
+
<metadata>${escapeXml(JSON.stringify({ generator: "Farm.js docs", page: descriptor.pageUrl, illustration: descriptor.illustration }))}</metadata>
|
|
19171
|
+
<style type="text/css">
|
|
19172
|
+
${renderEmbeddedFont("Farm Sans", descriptor.fonts?.sans, "100 900")}
|
|
19173
|
+
${renderEmbeddedFont("Farm Mono", descriptor.fonts?.mono, "100 900")}
|
|
19174
|
+
${renderEmbeddedFont("Farm Pixel", descriptor.fonts?.display, "400 700")}
|
|
19175
|
+
.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}
|
|
19176
|
+
</style>
|
|
19177
|
+
<defs>
|
|
19178
|
+
<pattern id="canvas-grid" width="40" height="40" patternUnits="userSpaceOnUse"><path d="M40 0H0V40" fill="none" stroke="#151515"/></pattern>
|
|
19179
|
+
<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>
|
|
19180
|
+
<clipPath id="frame-clip"><rect x="28" y="28" width="1144" height="574"/></clipPath>
|
|
19181
|
+
</defs>
|
|
19182
|
+
<rect width="1200" height="630" fill="#050505"/>
|
|
19183
|
+
<rect width="1200" height="630" fill="url(#canvas-grid)"/>
|
|
19184
|
+
<g clip-path="url(#frame-clip)">
|
|
19185
|
+
<rect x="28" y="28" width="1144" height="574" fill="#020202"/>
|
|
19186
|
+
<rect x="782" y="114" width="390" height="411" fill="url(#diagonal)"/>
|
|
19187
|
+
</g>
|
|
19188
|
+
<rect x="28.5" y="28.5" width="1143" height="573" fill="none" stroke="#323232"/>
|
|
19189
|
+
<path d="M28 114.5h1144M28 525.5h1144M781.5 114v411" fill="none" stroke="#303030"/>
|
|
19190
|
+
|
|
19191
|
+
<g transform="translate(71 51)">
|
|
19192
|
+
<rect width="11" height="11" rx="1" fill="#f5f5f4"/><rect x="15" width="28" height="11" rx="1" fill="#f5f5f4"/>
|
|
19193
|
+
<rect y="15" width="11" height="11" rx="1" fill="#9b9b9b"/><rect x="15" y="15" width="28" height="11" rx="1" fill="#9b9b9b"/>
|
|
19194
|
+
<rect y="30" width="11" height="11" rx="1" fill="#5f5f5f"/><rect x="15" y="30" width="20" height="11" rx="1" fill="#5f5f5f"/>
|
|
19195
|
+
<text x="61" y="24" class="mono bright" font-size="24" font-weight="550">FARM<tspan fill="#777">.JS</tspan></text>
|
|
19196
|
+
<text x="61" y="43" class="label">BY FARMING LABS</text>
|
|
19197
|
+
</g>
|
|
19198
|
+
<text x="1134" y="72" class="label" text-anchor="end">${escapeXml(brand)} \xB7 DOCUMENTATION</text>
|
|
19199
|
+
|
|
19200
|
+
<text x="71" y="198" class="mono bright" font-size="13" font-weight="650">DOCS</text>
|
|
19201
|
+
<line x1="117" y1="193" x2="155" y2="193" stroke="#696969"/>
|
|
19202
|
+
<text x="166" y="198" class="mono" fill="#9b9b9b" font-size="13">${escapeXml(section)}</text>
|
|
19203
|
+
${renderTextLines(titleLines, 71, titleY, titleLineHeight, `class="pixel bright" font-size="${titleSize}" font-weight="500" letter-spacing="-2.4"`)}
|
|
19204
|
+
${renderTextLines(descriptionLines, 71, descriptionY, 29, 'class="sans" fill="#a3a3a3" font-size="20" font-weight="430" letter-spacing="-.3"')}
|
|
19205
|
+
<rect x="71" y="${routeY}" width="${Math.min(390, 56 + route.length * 8)}" height="36" fill="#050505" stroke="#3c3c3c"/>
|
|
19206
|
+
<text x="85" y="${routeY + 23}" class="mono bright" font-size="11" font-weight="600">GET</text>
|
|
19207
|
+
<text x="119" y="${routeY + 23}" class="mono" fill="#898989" font-size="11">${escapeXml(route)}</text>
|
|
19208
|
+
|
|
19209
|
+
${renderIllustration(descriptor.illustration)}
|
|
19210
|
+
|
|
19211
|
+
<text x="71" y="570" class="mono bright" font-size="13" font-weight="550">${escapeXml(footerUrl)}</text>
|
|
19212
|
+
<text x="1134" y="570" class="mono" fill="#9b9b9b" font-size="12" text-anchor="end">FARM.JS DOCUMENTATION</text>
|
|
19213
|
+
<path d="M20 20h10M20 20v10M1180 20h-10M1180 20v10M20 610h10M20 610v-10M1180 610h-10M1180 610v-10" fill="none" stroke="#9b9b9b"/>
|
|
19214
|
+
</svg>`;
|
|
19215
|
+
}
|
|
19216
|
+
function renderFarmDocsSocialMetadata(descriptor, customImage) {
|
|
19217
|
+
const imageUrl = customImage ? new URL(customImage, descriptor.pageUrl).href : descriptor.imageUrl;
|
|
19218
|
+
const customExtension = customImage?.toLowerCase().split(/[?#]/, 1)[0];
|
|
19219
|
+
const imageType = customExtension?.endsWith(".webp") ? "image/webp" : customExtension?.endsWith(".png") ? "image/png" : customExtension?.match(/\.jpe?g$/) ? "image/jpeg" : "image/svg+xml";
|
|
19220
|
+
const tag = /* @__PURE__ */ __name((property, content, name = false) => `<meta ${name ? "name" : "property"}="${property}" content="${escapeXml(content)}">`, "tag");
|
|
19221
|
+
return [
|
|
19222
|
+
tag("og:type", "article"),
|
|
19223
|
+
tag("og:site_name", descriptor.siteName),
|
|
19224
|
+
tag("og:title", descriptor.title),
|
|
19225
|
+
tag("og:description", descriptor.description),
|
|
19226
|
+
tag("og:url", descriptor.pageUrl),
|
|
19227
|
+
tag("og:image", imageUrl),
|
|
19228
|
+
tag("og:image:type", imageType),
|
|
19229
|
+
...customImage ? [] : [
|
|
19230
|
+
tag("og:image:width", String(FARM_DOCS_SOCIAL_IMAGE_WIDTH)),
|
|
19231
|
+
tag("og:image:height", String(FARM_DOCS_SOCIAL_IMAGE_HEIGHT))
|
|
19232
|
+
],
|
|
19233
|
+
tag("og:image:alt", descriptor.imageAlt),
|
|
19234
|
+
tag("twitter:card", "summary_large_image", true),
|
|
19235
|
+
tag("twitter:title", descriptor.title, true),
|
|
19236
|
+
tag("twitter:description", descriptor.description, true),
|
|
19237
|
+
tag("twitter:image", imageUrl, true),
|
|
19238
|
+
tag("twitter:image:alt", descriptor.imageAlt, true)
|
|
19239
|
+
].join("\n ");
|
|
19240
|
+
}
|
|
19241
|
+
var import_node_crypto4, FARM_DOCS_SOCIAL_IMAGE_WIDTH, FARM_DOCS_SOCIAL_IMAGE_HEIGHT, FARM_DOCS_SOCIAL_IMAGE_VERSION;
|
|
19242
|
+
var init_social_image = __esm({
|
|
19243
|
+
"src/docs/social-image.ts"() {
|
|
19244
|
+
"use strict";
|
|
19245
|
+
import_node_crypto4 = require("crypto");
|
|
19246
|
+
FARM_DOCS_SOCIAL_IMAGE_WIDTH = 1200;
|
|
19247
|
+
FARM_DOCS_SOCIAL_IMAGE_HEIGHT = 630;
|
|
19248
|
+
FARM_DOCS_SOCIAL_IMAGE_VERSION = 3;
|
|
19249
|
+
__name(normalizeEntry, "normalizeEntry");
|
|
19250
|
+
__name(encodeSlugPath, "encodeSlugPath");
|
|
19251
|
+
__name(getSocialImageConfig, "getSocialImageConfig");
|
|
19252
|
+
__name(getNavTitle, "getNavTitle");
|
|
19253
|
+
__name(isFalse, "isFalse");
|
|
19254
|
+
__name(isExternalOrRootPath, "isExternalOrRootPath");
|
|
19255
|
+
__name(isFarmDocsSocialImageEnabled, "isFarmDocsSocialImageEnabled");
|
|
19256
|
+
__name(getFarmDocsCustomSocialImage, "getFarmDocsCustomSocialImage");
|
|
19257
|
+
__name(resolveIllustration, "resolveIllustration");
|
|
19258
|
+
__name(createHashValue, "createHashValue");
|
|
19259
|
+
__name(resolveBaseUrl, "resolveBaseUrl");
|
|
19260
|
+
__name(createFarmDocsSocialImageDescriptor, "createFarmDocsSocialImageDescriptor");
|
|
19261
|
+
__name(getFarmDocsSocialImageSlug, "getFarmDocsSocialImageSlug");
|
|
19262
|
+
__name(escapeXml, "escapeXml");
|
|
19263
|
+
__name(truncate, "truncate");
|
|
19264
|
+
__name(wrapText, "wrapText");
|
|
19265
|
+
__name(renderTextLines, "renderTextLines");
|
|
19266
|
+
__name(renderEmbeddedFont, "renderEmbeddedFont");
|
|
19267
|
+
__name(renderArrow, "renderArrow");
|
|
19268
|
+
__name(renderPanelHeader, "renderPanelHeader");
|
|
19269
|
+
__name(renderRoutingIllustration, "renderRoutingIllustration");
|
|
19270
|
+
__name(renderAuthIllustration, "renderAuthIllustration");
|
|
19271
|
+
__name(renderCacheIllustration, "renderCacheIllustration");
|
|
19272
|
+
__name(renderIntegrationsIllustration, "renderIntegrationsIllustration");
|
|
19273
|
+
__name(renderCliIllustration, "renderCliIllustration");
|
|
19274
|
+
__name(renderProjectIllustration, "renderProjectIllustration");
|
|
19275
|
+
__name(renderRuntimeIllustration, "renderRuntimeIllustration");
|
|
19276
|
+
__name(renderIllustration, "renderIllustration");
|
|
19277
|
+
__name(renderFarmDocsSocialImageSvg, "renderFarmDocsSocialImageSvg");
|
|
19278
|
+
__name(renderFarmDocsSocialMetadata, "renderFarmDocsSocialMetadata");
|
|
19279
|
+
}
|
|
19280
|
+
});
|
|
19281
|
+
|
|
18132
19282
|
// src/docs/handler.ts
|
|
18133
19283
|
function trimSlashes2(value) {
|
|
18134
19284
|
return value.replace(/^\/+|\/+$/g, "");
|
|
18135
19285
|
}
|
|
18136
|
-
function
|
|
19286
|
+
function normalizeEntry2(entry) {
|
|
18137
19287
|
if (!entry || entry === "/") return "/";
|
|
18138
19288
|
return `/${trimSlashes2(entry)}`;
|
|
18139
19289
|
}
|
|
@@ -18145,10 +19295,10 @@ function resolveFarmDocsFavicon(docs, options) {
|
|
|
18145
19295
|
if (typeof configuredFavicon === "string" && configuredFavicon.trim()) {
|
|
18146
19296
|
return configuredFavicon.trim();
|
|
18147
19297
|
}
|
|
18148
|
-
const publicDir =
|
|
19298
|
+
const publicDir = import_node_path13.default.join(import_node_path13.default.resolve(options.root), "public");
|
|
18149
19299
|
for (const fileName of FARM_DOCS_FAVICON_FILES) {
|
|
18150
|
-
const faviconPath =
|
|
18151
|
-
if ((0,
|
|
19300
|
+
const faviconPath = import_node_path13.default.join(publicDir, fileName);
|
|
19301
|
+
if ((0, import_node_fs9.existsSync)(faviconPath) && (0, import_node_fs9.statSync)(faviconPath).isFile()) {
|
|
18152
19302
|
return `/${fileName}`;
|
|
18153
19303
|
}
|
|
18154
19304
|
}
|
|
@@ -18182,10 +19332,10 @@ function isSafeSegment(segment) {
|
|
|
18182
19332
|
return segment !== ".." && !segment.includes("/") && !segment.includes("\\");
|
|
18183
19333
|
}
|
|
18184
19334
|
function resolveInside(root, target) {
|
|
18185
|
-
const resolvedRoot =
|
|
18186
|
-
const resolvedTarget =
|
|
18187
|
-
const relative4 =
|
|
18188
|
-
if (relative4 === "" || !relative4.startsWith("..") && !
|
|
19335
|
+
const resolvedRoot = import_node_path13.default.resolve(root);
|
|
19336
|
+
const resolvedTarget = import_node_path13.default.resolve(target);
|
|
19337
|
+
const relative4 = import_node_path13.default.relative(resolvedRoot, resolvedTarget);
|
|
19338
|
+
if (relative4 === "" || !relative4.startsWith("..") && !import_node_path13.default.isAbsolute(relative4)) {
|
|
18189
19339
|
return resolvedTarget;
|
|
18190
19340
|
}
|
|
18191
19341
|
return null;
|
|
@@ -18194,36 +19344,36 @@ function isFarmDocsRequest(docs, request) {
|
|
|
18194
19344
|
if (!docs?.enabled) return false;
|
|
18195
19345
|
if (request.method !== "GET" && request.method !== "HEAD") return false;
|
|
18196
19346
|
const pathname = new URL(request.url).pathname;
|
|
18197
|
-
const entry =
|
|
19347
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18198
19348
|
if (entry === "/") return true;
|
|
18199
19349
|
return pathname === entry || pathname === `${entry}.md` || pathname.startsWith(`${entry}/`);
|
|
18200
19350
|
}
|
|
18201
19351
|
function resolveFarmDocsContentDir(docs, options) {
|
|
18202
|
-
const root =
|
|
19352
|
+
const root = import_node_path13.default.resolve(options.root);
|
|
18203
19353
|
const srcDir = options.srcDir || "src";
|
|
18204
19354
|
const configuredContentDir = docs.contentDir || docs.config.contentDir;
|
|
18205
19355
|
if (configuredContentDir) {
|
|
18206
|
-
return
|
|
19356
|
+
return import_node_path13.default.isAbsolute(configuredContentDir) ? configuredContentDir : import_node_path13.default.join(root, configuredContentDir);
|
|
18207
19357
|
}
|
|
18208
19358
|
const entryDir = docs.config.entry || trimSlashes2(docs.entry) || "docs";
|
|
18209
|
-
const appDocsDir =
|
|
18210
|
-
if ((0,
|
|
18211
|
-
return
|
|
19359
|
+
const appDocsDir = import_node_path13.default.join(root, srcDir, "app", entryDir);
|
|
19360
|
+
if ((0, import_node_fs9.existsSync)(appDocsDir)) return appDocsDir;
|
|
19361
|
+
return import_node_path13.default.join(root, entryDir);
|
|
18212
19362
|
}
|
|
18213
19363
|
function getFarmDocsRouteTypeEntries(docs) {
|
|
18214
19364
|
if (!docs?.enabled) return [];
|
|
18215
|
-
const entry =
|
|
19365
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18216
19366
|
if (entry === "/") return ["/", "/[...docs]"];
|
|
18217
19367
|
return [entry, `${entry}/[...docs]`];
|
|
18218
19368
|
}
|
|
18219
19369
|
function getFarmDocsDocumentNavigationMatchers(docs) {
|
|
18220
19370
|
if (!docs?.enabled) return [];
|
|
18221
|
-
const entry =
|
|
19371
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18222
19372
|
return [entry === "/" ? "/(.*)" : `${entry}(.*)`];
|
|
18223
19373
|
}
|
|
18224
19374
|
function getRequestSlug(docs, request) {
|
|
18225
19375
|
const pathname = new URL(request.url).pathname;
|
|
18226
|
-
const entry =
|
|
19376
|
+
const entry = normalizeEntry2(docs.entry);
|
|
18227
19377
|
if (entry === "/") return normalizeSlug(pathname);
|
|
18228
19378
|
if (pathname === entry || pathname === `${entry}.md`) return "";
|
|
18229
19379
|
return normalizeSlug(pathname.slice(entry.length));
|
|
@@ -18231,14 +19381,14 @@ function getRequestSlug(docs, request) {
|
|
|
18231
19381
|
function findDocsPageFile(contentDir, slug) {
|
|
18232
19382
|
const segments = slug ? slug.split("/").filter(Boolean) : [];
|
|
18233
19383
|
if (!segments.every(isSafeSegment)) return null;
|
|
18234
|
-
const slugDir =
|
|
18235
|
-
const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) =>
|
|
18236
|
-
...DOCS_FILE_NAMES.map((filename) =>
|
|
18237
|
-
...DOCS_FILE_EXTENSIONS2.map((extension) =>
|
|
19384
|
+
const slugDir = import_node_path13.default.join(contentDir, ...segments);
|
|
19385
|
+
const candidates = segments.length === 0 ? DOCS_FILE_NAMES.map((filename) => import_node_path13.default.join(contentDir, filename)) : [
|
|
19386
|
+
...DOCS_FILE_NAMES.map((filename) => import_node_path13.default.join(slugDir, filename)),
|
|
19387
|
+
...DOCS_FILE_EXTENSIONS2.map((extension) => import_node_path13.default.join(contentDir, `${slug}${extension}`))
|
|
18238
19388
|
];
|
|
18239
19389
|
for (const candidate of candidates) {
|
|
18240
19390
|
const safePath = resolveInside(contentDir, candidate);
|
|
18241
|
-
if (safePath && (0,
|
|
19391
|
+
if (safePath && (0, import_node_fs9.existsSync)(safePath) && (0, import_node_fs9.statSync)(safePath).isFile()) {
|
|
18242
19392
|
return safePath;
|
|
18243
19393
|
}
|
|
18244
19394
|
}
|
|
@@ -18273,7 +19423,7 @@ function titleFromMarkdown2(body, fallback) {
|
|
|
18273
19423
|
function loadFarmDocsPage(contentDir, docs, slug) {
|
|
18274
19424
|
const sourcePath = findDocsPageFile(contentDir, slug);
|
|
18275
19425
|
if (!sourcePath) return null;
|
|
18276
|
-
const source = (0,
|
|
19426
|
+
const source = (0, import_node_fs9.readFileSync)(sourcePath, "utf8");
|
|
18277
19427
|
const { frontmatter, body } = parseFrontmatter(source);
|
|
18278
19428
|
const title = frontmatter.title || titleFromMarkdown2(body, titleFromSlug(slug));
|
|
18279
19429
|
const href = createDocsHref(docs.entry, slug);
|
|
@@ -18281,6 +19431,7 @@ function loadFarmDocsPage(contentDir, docs, slug) {
|
|
|
18281
19431
|
slug,
|
|
18282
19432
|
title,
|
|
18283
19433
|
description: frontmatter.description,
|
|
19434
|
+
section: frontmatter.section,
|
|
18284
19435
|
href,
|
|
18285
19436
|
sourcePath,
|
|
18286
19437
|
lastModified: resolveFarmDocsPageLastModified(contentDir, sourcePath, frontmatter),
|
|
@@ -18289,15 +19440,15 @@ function loadFarmDocsPage(contentDir, docs, slug) {
|
|
|
18289
19440
|
};
|
|
18290
19441
|
}
|
|
18291
19442
|
function createDocsHref(entry, slug) {
|
|
18292
|
-
const normalizedEntry =
|
|
19443
|
+
const normalizedEntry = normalizeEntry2(entry);
|
|
18293
19444
|
const normalizedSlug = trimSlashes2(slug);
|
|
18294
19445
|
if (normalizedEntry === "/") return normalizedSlug ? `/${normalizedSlug}` : "/";
|
|
18295
19446
|
return normalizedSlug ? `${normalizedEntry}/${normalizedSlug}` : normalizedEntry;
|
|
18296
19447
|
}
|
|
18297
19448
|
function pathToSlug(contentDir, filePath) {
|
|
18298
|
-
const relative4 =
|
|
19449
|
+
const relative4 = import_node_path13.default.relative(contentDir, filePath).replace(/\\/g, "/");
|
|
18299
19450
|
if (relative4.startsWith("..")) return null;
|
|
18300
|
-
const extension =
|
|
19451
|
+
const extension = import_node_path13.default.extname(relative4);
|
|
18301
19452
|
if (!DOCS_FILE_EXTENSIONS2.includes(extension)) return null;
|
|
18302
19453
|
const withoutExtension = relative4.slice(0, -extension.length);
|
|
18303
19454
|
if (withoutExtension === "page" || withoutExtension === "index") return "";
|
|
@@ -18310,12 +19461,12 @@ function loadPage(contentDir, docs, request) {
|
|
|
18310
19461
|
return loadFarmDocsPage(contentDir, docs, getRequestSlug(docs, request));
|
|
18311
19462
|
}
|
|
18312
19463
|
function discoverFarmDocsPages(contentDir, docs) {
|
|
18313
|
-
if (!(0,
|
|
19464
|
+
if (!(0, import_node_fs9.existsSync)(contentDir)) return [];
|
|
18314
19465
|
const pages = [];
|
|
18315
19466
|
const visit = /* @__PURE__ */ __name((dir) => {
|
|
18316
|
-
for (const entry of (0,
|
|
19467
|
+
for (const entry of (0, import_node_fs9.readdirSync)(dir, { withFileTypes: true })) {
|
|
18317
19468
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
18318
|
-
const absolutePath =
|
|
19469
|
+
const absolutePath = import_node_path13.default.join(dir, entry.name);
|
|
18319
19470
|
if (entry.isDirectory()) {
|
|
18320
19471
|
visit(absolutePath);
|
|
18321
19472
|
continue;
|
|
@@ -18323,7 +19474,7 @@ function discoverFarmDocsPages(contentDir, docs) {
|
|
|
18323
19474
|
if (!entry.isFile()) continue;
|
|
18324
19475
|
const slug = pathToSlug(contentDir, absolutePath);
|
|
18325
19476
|
if (slug === null) continue;
|
|
18326
|
-
const source = (0,
|
|
19477
|
+
const source = (0, import_node_fs9.readFileSync)(absolutePath, "utf8");
|
|
18327
19478
|
const { frontmatter, body } = parseFrontmatter(source);
|
|
18328
19479
|
pages.push({
|
|
18329
19480
|
slug,
|
|
@@ -19101,7 +20252,7 @@ function renderPixelBreadcrumb(page2, docs) {
|
|
|
19101
20252
|
const parentSegments = segments.slice(0, -1);
|
|
19102
20253
|
const parentSegment = parentSegments[parentSegments.length - 1];
|
|
19103
20254
|
const currentSegment = segments[segments.length - 1];
|
|
19104
|
-
const entry =
|
|
20255
|
+
const entry = normalizeEntry2(docs.entry);
|
|
19105
20256
|
const parentPath = parentSegments.join("/");
|
|
19106
20257
|
const parentHref = entry === "/" ? `/${parentPath}` : `${entry}/${parentPath}`;
|
|
19107
20258
|
return `<nav class="fd-breadcrumb" aria-label="Breadcrumb">
|
|
@@ -19139,7 +20290,7 @@ ${items.map(
|
|
|
19139
20290
|
</div>`;
|
|
19140
20291
|
}
|
|
19141
20292
|
function renderDocsRuntimeScript(docs) {
|
|
19142
|
-
const docsEntry = JSON.stringify(
|
|
20293
|
+
const docsEntry = JSON.stringify(normalizeEntry2(docs.entry));
|
|
19143
20294
|
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>`;
|
|
19144
20295
|
}
|
|
19145
20296
|
function renderDocsPageActionsRuntimeScript() {
|
|
@@ -19154,13 +20305,13 @@ ${renderDocsHashRuntimeScript()}
|
|
|
19154
20305
|
${renderDocsPageActionsRuntimeScript()}`;
|
|
19155
20306
|
}
|
|
19156
20307
|
function readCssWithImports(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
19157
|
-
const resolved =
|
|
20308
|
+
const resolved = import_node_path13.default.resolve(filePath);
|
|
19158
20309
|
if (seen.has(resolved)) return "";
|
|
19159
20310
|
seen.add(resolved);
|
|
19160
|
-
const source = (0,
|
|
20311
|
+
const source = (0, import_node_fs9.readFileSync)(resolved, "utf8");
|
|
19161
20312
|
return source.replace(/@import\s+["']([^"']+)["'];?/g, (_match, importPath) => {
|
|
19162
20313
|
try {
|
|
19163
|
-
const importedPath = importPath.startsWith(".") ?
|
|
20314
|
+
const importedPath = importPath.startsWith(".") ? import_node_path13.default.resolve(import_node_path13.default.dirname(resolved), importPath) : (0, import_node_module5.createRequire)(resolved).resolve(importPath);
|
|
19164
20315
|
return readCssWithImports(importedPath, seen);
|
|
19165
20316
|
} catch {
|
|
19166
20317
|
return "";
|
|
@@ -19168,11 +20319,11 @@ function readCssWithImports(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
|
19168
20319
|
});
|
|
19169
20320
|
}
|
|
19170
20321
|
function resolvePixelBorderThemeCss(options) {
|
|
19171
|
-
const cacheKey =
|
|
20322
|
+
const cacheKey = import_node_path13.default.resolve(options.root);
|
|
19172
20323
|
const cached = themeCssCache.get(cacheKey);
|
|
19173
20324
|
if (cached !== void 0) return cached;
|
|
19174
20325
|
try {
|
|
19175
|
-
const requireFromApp = (0, import_node_module5.createRequire)(
|
|
20326
|
+
const requireFromApp = (0, import_node_module5.createRequire)(import_node_path13.default.join(cacheKey, "package.json"));
|
|
19176
20327
|
const themeCssPath = requireFromApp.resolve("@farming-labs/theme/pixel-border/css");
|
|
19177
20328
|
const requireFromTheme = (0, import_node_module5.createRequire)(themeCssPath);
|
|
19178
20329
|
const fumadocsCssPath = requireFromTheme.resolve("fumadocs-ui/style.css");
|
|
@@ -19185,17 +20336,28 @@ ${readCssWithImports(themeCssPath)}`;
|
|
|
19185
20336
|
return "";
|
|
19186
20337
|
}
|
|
19187
20338
|
}
|
|
19188
|
-
function renderFarmDocsBridgeCss(docs) {
|
|
20339
|
+
function renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts) {
|
|
19189
20340
|
const sidebarWidth = getThemeLayoutValue(docs, "sidebarWidth", 320);
|
|
19190
20341
|
const contentWidth = getThemeLayoutValue(docs, "contentWidth", 860);
|
|
20342
|
+
const fontFaces = fontAssets.map(
|
|
20343
|
+
({ family, url }) => `@font-face { font-family: "${family}"; src: url("${url}") format("woff2"); font-style: normal; font-weight: 100 900; font-display: block; }`
|
|
20344
|
+
).join("\n");
|
|
20345
|
+
const fontVariables = [
|
|
20346
|
+
fontAssets.some(({ family }) => family === "Geist Sans") ? '--font-geist-sans: "Geist Sans", ui-sans-serif, system-ui, sans-serif;' : "",
|
|
20347
|
+
fontAssets.some(({ family }) => family === "Geist Mono") ? '--font-geist-mono: "Geist Mono", ui-monospace, monospace;' : ""
|
|
20348
|
+
].filter(Boolean).join(" ");
|
|
20349
|
+
const fontCss = fontFaces ? `${fontFaces}
|
|
20350
|
+
:root { ${fontVariables} }` : "";
|
|
20351
|
+
const layoutFontVariables = [
|
|
20352
|
+
renderFarmDocsLayoutFontVariable("--fd-layout-font-body", layoutFonts?.body),
|
|
20353
|
+
renderFarmDocsLayoutFontVariable("--fd-layout-font-code", layoutFonts?.code)
|
|
20354
|
+
].filter(Boolean).join(" ");
|
|
19191
20355
|
return `
|
|
19192
|
-
|
|
19193
|
-
@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; }
|
|
19194
|
-
: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); }
|
|
20356
|
+
: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); }
|
|
19195
20357
|
* { box-sizing: border-box; }
|
|
19196
20358
|
html { background: var(--color-fd-background, hsl(0 0% 2%)); scroll-padding-top: calc(var(--fd-nav-height, 44px) + 24px); }
|
|
19197
20359
|
html[data-farm-docs-sidebar="open"], html[data-farm-docs-sidebar="open"] body { overflow: hidden; }
|
|
19198
|
-
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; }
|
|
20360
|
+
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; }
|
|
19199
20361
|
::selection { background: var(--color-fd-foreground, #fff); color: var(--color-fd-background, #000); }
|
|
19200
20362
|
a { color: inherit; }
|
|
19201
20363
|
#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%)); }
|
|
@@ -19375,14 +20537,45 @@ function renderFarmDocsBridgeCss(docs) {
|
|
|
19375
20537
|
.sh__line { min-height: 1.6em; }
|
|
19376
20538
|
}
|
|
19377
20539
|
${farmDocsPixelBorderCss}
|
|
20540
|
+
${fontCss}
|
|
19378
20541
|
`;
|
|
19379
20542
|
}
|
|
19380
|
-
function
|
|
20543
|
+
function renderFarmDocsLayoutFontVariable(name, font) {
|
|
20544
|
+
const family = font?.style.fontFamily;
|
|
20545
|
+
if (!family || /[;{}<>]/.test(family)) return "";
|
|
20546
|
+
return `${name}: ${family};`;
|
|
20547
|
+
}
|
|
20548
|
+
function renderFarmDocsFontPreloads(fontAssets) {
|
|
20549
|
+
return fontAssets.map(
|
|
20550
|
+
({ url }) => `<link rel="preload" href="${escapeAttribute2(url)}" as="font" type="font/woff2" crossorigin>`
|
|
20551
|
+
).join("\n ");
|
|
20552
|
+
}
|
|
20553
|
+
function renderFarmDocsFontPreloadHeader(fontAssets) {
|
|
20554
|
+
return fontAssets.map(({ url }) => `<${url}>; rel=preload; as=font; type=font/woff2; crossorigin`).join(", ");
|
|
20555
|
+
}
|
|
20556
|
+
function getFarmLayoutFontPreloads(layoutFonts) {
|
|
20557
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20558
|
+
return [layoutFonts?.body, layoutFonts?.code].flatMap(
|
|
20559
|
+
(font) => (font?.preloads || []).filter(({ href }) => {
|
|
20560
|
+
if (seen.has(href)) return false;
|
|
20561
|
+
seen.add(href);
|
|
20562
|
+
return true;
|
|
20563
|
+
})
|
|
20564
|
+
);
|
|
20565
|
+
}
|
|
20566
|
+
function renderFarmLayoutFontPreloadHeader(layoutFonts) {
|
|
20567
|
+
return getFarmLayoutFontPreloads(layoutFonts).map(({ href, type }) => `<${href}>; rel=preload; as=font; type=${type}; crossorigin`).join(", ");
|
|
20568
|
+
}
|
|
20569
|
+
function renderPixelDocsHtml(page2, pages, docs, themeCss, clientEntry, faviconHref, requestUrl, fontAssets, layoutFonts, fontStylesheetHref) {
|
|
19381
20570
|
const navTitle = typeof docs.config.nav === "object" && docs.config.nav && "title" in docs.config.nav ? String(docs.config.nav.title || "Docs") : "Docs";
|
|
19382
20571
|
const description = page2.description || docs.config.metadata?.description || "";
|
|
19383
20572
|
const tocItems = extractTocItems(page2.body, getThemeTocDepth(docs));
|
|
19384
20573
|
const themeName = getThemeName(docs);
|
|
19385
20574
|
const searchEnabled = isFarmDocsSearchEnabled(docs);
|
|
20575
|
+
const socialMetadata = isFarmDocsSocialImageEnabled(page2, docs) ? renderFarmDocsSocialMetadata(
|
|
20576
|
+
createFarmDocsSocialImageDescriptor(page2, docs, requestUrl),
|
|
20577
|
+
getFarmDocsCustomSocialImage(page2)
|
|
20578
|
+
) : "";
|
|
19386
20579
|
return `<!DOCTYPE html>
|
|
19387
20580
|
<html class="dark" lang="en" data-docs-theme="${escapeAttribute2(themeName)}">
|
|
19388
20581
|
<head>
|
|
@@ -19391,11 +20584,12 @@ function renderPixelDocsHtml(page2, pages, docs, themeCss, clientEntry, faviconH
|
|
|
19391
20584
|
<meta name="generator" content="@farming-labs/docs via Farm.js">
|
|
19392
20585
|
<title>${escapeHtml(page2.title)}</title>
|
|
19393
20586
|
${renderFarmDocsFaviconLink(faviconHref)}
|
|
19394
|
-
|
|
19395
|
-
|
|
20587
|
+
${renderFarmDocsFontPreloads(fontAssets)}
|
|
20588
|
+
${fontStylesheetHref ? `<link rel="stylesheet" href="${escapeAttribute2(fontStylesheetHref)}">` : ""}
|
|
19396
20589
|
${description ? `<meta name="description" content="${escapeHtml(description)}">` : ""}
|
|
20590
|
+
${socialMetadata}
|
|
19397
20591
|
<style>${themeCss}
|
|
19398
|
-
${renderFarmDocsBridgeCss(docs)}</style>
|
|
20592
|
+
${renderFarmDocsBridgeCss(docs, fontAssets, layoutFonts)}</style>
|
|
19399
20593
|
${searchEnabled ? renderDocsSearchBootstrapScript() : ""}
|
|
19400
20594
|
</head>
|
|
19401
20595
|
<body>
|
|
@@ -19447,9 +20641,34 @@ ${renderMarkdownHtmlWithTitleMeta(page2, docs)}
|
|
|
19447
20641
|
}
|
|
19448
20642
|
function createFarmDocsHandler(docs, options) {
|
|
19449
20643
|
const faviconHref = resolveFarmDocsFavicon(docs, options);
|
|
20644
|
+
const fontAssets = options.fontAssets ?? toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(options.root));
|
|
20645
|
+
const fallbackFontPreloadHeader = renderFarmDocsFontPreloadHeader(fontAssets);
|
|
19450
20646
|
return /* @__PURE__ */ __name(async function handleFarmDocsRequest(request) {
|
|
19451
20647
|
if (!docs?.enabled || request.method !== "GET" && request.method !== "HEAD") return null;
|
|
19452
20648
|
const contentDir = resolveFarmDocsContentDir(docs, options);
|
|
20649
|
+
const requestUrl = new URL(request.url);
|
|
20650
|
+
const socialImageSlug = getFarmDocsSocialImageSlug(docs, requestUrl);
|
|
20651
|
+
if (socialImageSlug !== null) {
|
|
20652
|
+
const socialImagePage = loadFarmDocsPage(contentDir, docs, socialImageSlug);
|
|
20653
|
+
if (!socialImagePage || !isFarmDocsSocialImageEnabled(socialImagePage, docs) || getFarmDocsCustomSocialImage(socialImagePage)) {
|
|
20654
|
+
return null;
|
|
20655
|
+
}
|
|
20656
|
+
const descriptor = createFarmDocsSocialImageDescriptor(socialImagePage, docs, requestUrl);
|
|
20657
|
+
if (requestUrl.pathname !== descriptor.imagePath) return null;
|
|
20658
|
+
const etag = `"${descriptor.hash}"`;
|
|
20659
|
+
const immutable = requestUrl.searchParams.get("v") === descriptor.hash;
|
|
20660
|
+
const headers = new Headers({
|
|
20661
|
+
"Content-Type": "image/svg+xml; charset=utf-8",
|
|
20662
|
+
"Cache-Control": immutable ? "public, max-age=31536000, immutable" : "public, max-age=0, must-revalidate",
|
|
20663
|
+
ETag: etag,
|
|
20664
|
+
"X-Content-Type-Options": "nosniff"
|
|
20665
|
+
});
|
|
20666
|
+
if (request.headers.get("if-none-match") === etag) {
|
|
20667
|
+
return new Response(null, { status: 304, headers });
|
|
20668
|
+
}
|
|
20669
|
+
if (request.method === "HEAD") return new Response(null, { status: 200, headers });
|
|
20670
|
+
return new Response(renderFarmDocsSocialImageSvg(descriptor), { status: 200, headers });
|
|
20671
|
+
}
|
|
19453
20672
|
const publicResponse = createFarmDocsPublicResponse(contentDir, docs, request);
|
|
19454
20673
|
if (publicResponse) return publicResponse;
|
|
19455
20674
|
if (!isFarmDocsRequest(docs, request)) return null;
|
|
@@ -19472,6 +20691,11 @@ function createFarmDocsHandler(docs, options) {
|
|
|
19472
20691
|
}
|
|
19473
20692
|
);
|
|
19474
20693
|
}
|
|
20694
|
+
const pathname = new URL(request.url).pathname;
|
|
20695
|
+
const layoutFonts = await options.resolveLayoutFonts?.(pathname);
|
|
20696
|
+
const usesLayoutFonts = Boolean(layoutFonts?.body || layoutFonts?.code);
|
|
20697
|
+
const activeFontAssets = usesLayoutFonts ? [] : fontAssets;
|
|
20698
|
+
const fontPreloadHeader = usesLayoutFonts ? renderFarmLayoutFontPreloadHeader(layoutFonts) : fallbackFontPreloadHeader;
|
|
19475
20699
|
return new Response(
|
|
19476
20700
|
renderPixelDocsHtml(
|
|
19477
20701
|
page2,
|
|
@@ -19479,39 +20703,44 @@ function createFarmDocsHandler(docs, options) {
|
|
|
19479
20703
|
docs,
|
|
19480
20704
|
resolvePixelBorderThemeCss(options),
|
|
19481
20705
|
options.clientEntry || "/farm-client.js",
|
|
19482
|
-
faviconHref
|
|
20706
|
+
faviconHref,
|
|
20707
|
+
requestUrl,
|
|
20708
|
+
activeFontAssets,
|
|
20709
|
+
layoutFonts,
|
|
20710
|
+
usesLayoutFonts ? options.fontStylesheetHref : void 0
|
|
19483
20711
|
),
|
|
19484
20712
|
{
|
|
19485
20713
|
status: 200,
|
|
19486
20714
|
headers: {
|
|
19487
20715
|
"Content-Type": "text/html; charset=utf-8",
|
|
19488
|
-
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=300"
|
|
20716
|
+
"Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
|
|
20717
|
+
...fontPreloadHeader ? { Link: fontPreloadHeader } : {}
|
|
19489
20718
|
}
|
|
19490
20719
|
}
|
|
19491
20720
|
);
|
|
19492
20721
|
}, "handleFarmDocsRequest");
|
|
19493
20722
|
}
|
|
19494
|
-
var
|
|
20723
|
+
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;
|
|
19495
20724
|
var init_handler = __esm({
|
|
19496
20725
|
"src/docs/handler.ts"() {
|
|
19497
20726
|
"use strict";
|
|
19498
|
-
|
|
20727
|
+
import_node_fs9 = require("fs");
|
|
19499
20728
|
import_node_module5 = require("module");
|
|
19500
|
-
|
|
20729
|
+
import_node_path13 = __toESM(require("path"));
|
|
19501
20730
|
import_docs = require("@farming-labs/docs");
|
|
19502
20731
|
import_marked = require("marked");
|
|
19503
20732
|
import_sugar_high = require("sugar-high");
|
|
20733
|
+
init_fonts();
|
|
19504
20734
|
init_last_modified();
|
|
19505
20735
|
init_pixel_border_css();
|
|
19506
20736
|
init_search_client();
|
|
20737
|
+
init_social_image();
|
|
19507
20738
|
DOCS_FILE_NAMES = ["page.mdx", "page.md", "index.mdx", "index.md"];
|
|
19508
20739
|
DOCS_FILE_EXTENSIONS2 = [".mdx", ".md"];
|
|
19509
20740
|
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";
|
|
19510
20741
|
FARM_DOCS_FAVICON_FILES = ["favicon.svg", "favicon.ico", "favicon.png"];
|
|
19511
|
-
GEIST_SANS_FONT_URL = "/assets/Geist-Variable-CrgPqtmy.woff2";
|
|
19512
|
-
GEIST_MONO_FONT_URL = "/assets/GeistMono-Variable-BNLlm6Cd.woff2";
|
|
19513
20742
|
__name(trimSlashes2, "trimSlashes");
|
|
19514
|
-
__name(
|
|
20743
|
+
__name(normalizeEntry2, "normalizeEntry");
|
|
19515
20744
|
__name(normalizeSlug, "normalizeSlug");
|
|
19516
20745
|
__name(resolveFarmDocsFavicon, "resolveFarmDocsFavicon");
|
|
19517
20746
|
__name(renderFarmDocsFaviconLink, "renderFarmDocsFaviconLink");
|
|
@@ -19701,6 +20930,11 @@ var init_handler = __esm({
|
|
|
19701
20930
|
__name(readCssWithImports, "readCssWithImports");
|
|
19702
20931
|
__name(resolvePixelBorderThemeCss, "resolvePixelBorderThemeCss");
|
|
19703
20932
|
__name(renderFarmDocsBridgeCss, "renderFarmDocsBridgeCss");
|
|
20933
|
+
__name(renderFarmDocsLayoutFontVariable, "renderFarmDocsLayoutFontVariable");
|
|
20934
|
+
__name(renderFarmDocsFontPreloads, "renderFarmDocsFontPreloads");
|
|
20935
|
+
__name(renderFarmDocsFontPreloadHeader, "renderFarmDocsFontPreloadHeader");
|
|
20936
|
+
__name(getFarmLayoutFontPreloads, "getFarmLayoutFontPreloads");
|
|
20937
|
+
__name(renderFarmLayoutFontPreloadHeader, "renderFarmLayoutFontPreloadHeader");
|
|
19704
20938
|
__name(renderPixelDocsHtml, "renderPixelDocsHtml");
|
|
19705
20939
|
__name(createFarmDocsHandler, "createFarmDocsHandler");
|
|
19706
20940
|
}
|
|
@@ -20469,8 +21703,8 @@ var init_generator = __esm({
|
|
|
20469
21703
|
}
|
|
20470
21704
|
routeGroups.get(key).push(route);
|
|
20471
21705
|
}
|
|
20472
|
-
for (const [
|
|
20473
|
-
const openAPIPath = this.convertToOpenAPIPath(
|
|
21706
|
+
for (const [path31, routeList] of routeGroups) {
|
|
21707
|
+
const openAPIPath = this.convertToOpenAPIPath(path31);
|
|
20474
21708
|
spec.paths[openAPIPath] = {};
|
|
20475
21709
|
for (const route of routeList) {
|
|
20476
21710
|
for (const method of route.methods) {
|
|
@@ -20484,8 +21718,8 @@ var init_generator = __esm({
|
|
|
20484
21718
|
/**
|
|
20485
21719
|
* Convert Farm.js API path to OpenAPI path format
|
|
20486
21720
|
*/
|
|
20487
|
-
convertToOpenAPIPath(
|
|
20488
|
-
return
|
|
21721
|
+
convertToOpenAPIPath(path31) {
|
|
21722
|
+
return path31.replace(/^\/api/, "");
|
|
20489
21723
|
}
|
|
20490
21724
|
/**
|
|
20491
21725
|
* Extract request body schema from endpoint
|
|
@@ -20647,8 +21881,8 @@ var init_generator = __esm({
|
|
|
20647
21881
|
/**
|
|
20648
21882
|
* Generate operation summary
|
|
20649
21883
|
*/
|
|
20650
|
-
generateSummary(
|
|
20651
|
-
const cleanPath =
|
|
21884
|
+
generateSummary(path31, method) {
|
|
21885
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20652
21886
|
const pathParts = cleanPath.split("/");
|
|
20653
21887
|
const lastPart = pathParts[pathParts.length - 1];
|
|
20654
21888
|
const action = method === "GET" ? "Get" : method === "POST" ? "Create" : method === "PUT" ? "Update" : method === "DELETE" ? "Delete" : method === "PATCH" ? "Update" : method;
|
|
@@ -20657,22 +21891,22 @@ var init_generator = __esm({
|
|
|
20657
21891
|
/**
|
|
20658
21892
|
* Generate operation description
|
|
20659
21893
|
*/
|
|
20660
|
-
generateDescription(
|
|
20661
|
-
const cleanPath =
|
|
21894
|
+
generateDescription(path31, method) {
|
|
21895
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20662
21896
|
return `${method} ${cleanPath} endpoint`;
|
|
20663
21897
|
}
|
|
20664
21898
|
/**
|
|
20665
21899
|
* Generate operation ID
|
|
20666
21900
|
*/
|
|
20667
|
-
generateOperationId(
|
|
20668
|
-
const cleanPath =
|
|
21901
|
+
generateOperationId(path31, method) {
|
|
21902
|
+
const cleanPath = path31.replace(/^\/api\//, "").replace(/\//g, "_");
|
|
20669
21903
|
return `${method.toLowerCase()}_${cleanPath}`;
|
|
20670
21904
|
}
|
|
20671
21905
|
/**
|
|
20672
21906
|
* Generate tags for grouping operations
|
|
20673
21907
|
*/
|
|
20674
|
-
generateTags(
|
|
20675
|
-
const cleanPath =
|
|
21908
|
+
generateTags(path31) {
|
|
21909
|
+
const cleanPath = path31.replace(/^\/api\//, "");
|
|
20676
21910
|
const pathParts = cleanPath.split("/");
|
|
20677
21911
|
if (pathParts.length > 1) {
|
|
20678
21912
|
return [pathParts[0]];
|
|
@@ -20685,8 +21919,8 @@ var init_generator = __esm({
|
|
|
20685
21919
|
async generateSpecFile(routes, outputPath) {
|
|
20686
21920
|
const spec = await this.generateSpec(routes);
|
|
20687
21921
|
const fs8 = require("fs");
|
|
20688
|
-
const
|
|
20689
|
-
const dir =
|
|
21922
|
+
const path31 = require("path");
|
|
21923
|
+
const dir = path31.dirname(outputPath);
|
|
20690
21924
|
if (!fs8.existsSync(dir)) {
|
|
20691
21925
|
fs8.mkdirSync(dir, { recursive: true });
|
|
20692
21926
|
}
|
|
@@ -21106,7 +22340,7 @@ async function createFarmDevtoolsSnapshot(input) {
|
|
|
21106
22340
|
generatedAt: (input.now?.() || /* @__PURE__ */ new Date()).toISOString(),
|
|
21107
22341
|
health: resolveHealth(diagnostics),
|
|
21108
22342
|
project: {
|
|
21109
|
-
name:
|
|
22343
|
+
name: import_node_path14.default.basename(import_node_path14.default.resolve(input.root)),
|
|
21110
22344
|
root: input.root,
|
|
21111
22345
|
srcDir: input.srcDir,
|
|
21112
22346
|
basePath: config.basePath || "/",
|
|
@@ -21155,11 +22389,11 @@ async function createFarmDevtoolsSnapshot(input) {
|
|
|
21155
22389
|
diagnostics
|
|
21156
22390
|
};
|
|
21157
22391
|
}
|
|
21158
|
-
var
|
|
22392
|
+
var import_node_path14;
|
|
21159
22393
|
var init_devtools = __esm({
|
|
21160
22394
|
"src/devtools.ts"() {
|
|
21161
22395
|
"use strict";
|
|
21162
|
-
|
|
22396
|
+
import_node_path14 = __toESM(require("path"));
|
|
21163
22397
|
init_config2();
|
|
21164
22398
|
init_cron();
|
|
21165
22399
|
init_route_runtime();
|
|
@@ -22983,7 +24217,7 @@ function fileContainsProgrammaticPageRoute(file) {
|
|
|
22983
24217
|
}
|
|
22984
24218
|
function rewriteEarlySsrRelativeImports(options) {
|
|
22985
24219
|
const cleanId = options.id.split("?", 1)[0];
|
|
22986
|
-
if (!
|
|
24220
|
+
if (!path27.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
|
|
22987
24221
|
return null;
|
|
22988
24222
|
}
|
|
22989
24223
|
const replacements = [];
|
|
@@ -23003,7 +24237,7 @@ function rewriteEarlySsrRelativeImports(options) {
|
|
|
23003
24237
|
const suffixIndex = source.value.search(/[?#]/);
|
|
23004
24238
|
const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
|
|
23005
24239
|
const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
|
|
23006
|
-
const resolvedPath =
|
|
24240
|
+
const resolvedPath = path27.resolve(path27.dirname(cleanId), sourcePath);
|
|
23007
24241
|
replacements.push({
|
|
23008
24242
|
start: source.start,
|
|
23009
24243
|
end: source.end,
|
|
@@ -23084,7 +24318,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23084
24318
|
...layerRoots.length ? {
|
|
23085
24319
|
server: {
|
|
23086
24320
|
fs: {
|
|
23087
|
-
allow: [
|
|
24321
|
+
allow: [path27.resolve(options.root || process.cwd()), ...layerRoots]
|
|
23088
24322
|
}
|
|
23089
24323
|
}
|
|
23090
24324
|
} : {}
|
|
@@ -23115,9 +24349,9 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23115
24349
|
},
|
|
23116
24350
|
server
|
|
23117
24351
|
);
|
|
23118
|
-
const globalsCSSPath =
|
|
24352
|
+
const globalsCSSPath = path27.join(server.config.root, "src/app/globals.css");
|
|
23119
24353
|
if (!fs7.existsSync(globalsCSSPath)) {
|
|
23120
|
-
const appDir =
|
|
24354
|
+
const appDir = path27.join(server.config.root, "src/app");
|
|
23121
24355
|
if (!fs7.existsSync(appDir)) {
|
|
23122
24356
|
fs7.mkdirSync(appDir, { recursive: true });
|
|
23123
24357
|
}
|
|
@@ -23139,10 +24373,10 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23139
24373
|
});
|
|
23140
24374
|
}
|
|
23141
24375
|
const sourceRoots = getFarmSourceRoots(farmConfig);
|
|
23142
|
-
server.watcher.add(sourceRoots.map((source) =>
|
|
24376
|
+
server.watcher.add(sourceRoots.map((source) => path27.join(source.root, source.srcDir)));
|
|
23143
24377
|
if (farmConfig.i18n.enabled) {
|
|
23144
24378
|
server.watcher.add(
|
|
23145
|
-
farmConfig.i18n.messages.includes("{locale}") ?
|
|
24379
|
+
farmConfig.i18n.messages.includes("{locale}") ? path27.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
|
|
23146
24380
|
);
|
|
23147
24381
|
}
|
|
23148
24382
|
const workflowConfig = farmConfig.workflows;
|
|
@@ -23152,7 +24386,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23152
24386
|
...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
|
|
23153
24387
|
], "getExtraRouteTypes");
|
|
23154
24388
|
const appDirSlugs = sourceRoots.map(
|
|
23155
|
-
(source) =>
|
|
24389
|
+
(source) => path27.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
|
|
23156
24390
|
);
|
|
23157
24391
|
const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
|
|
23158
24392
|
try {
|
|
@@ -23192,7 +24426,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23192
24426
|
}, "generateTypeArtifacts");
|
|
23193
24427
|
await generateTypeArtifacts("startup");
|
|
23194
24428
|
const srcDirSlugs = sourceRoots.map(
|
|
23195
|
-
(source) =>
|
|
24429
|
+
(source) => path27.join(source.root, source.srcDir).replace(/\\/g, "/")
|
|
23196
24430
|
);
|
|
23197
24431
|
const layerConfigFiles = new Set(
|
|
23198
24432
|
farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
|
|
@@ -23310,7 +24544,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23310
24544
|
await apiRouteManager.discoverRoutes();
|
|
23311
24545
|
let discoveredWorkflows = [];
|
|
23312
24546
|
const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
|
|
23313
|
-
(dir) => fs7.existsSync(
|
|
24547
|
+
(dir) => fs7.existsSync(path27.isAbsolute(dir) ? dir : path27.join(farmConfig.root, dir))
|
|
23314
24548
|
);
|
|
23315
24549
|
if (hasWorkflowDirectory) {
|
|
23316
24550
|
const { createFarmWorkflowRequestHandler: createFarmWorkflowRequestHandler2, discoverFarmWorkflows: discoverFarmWorkflows2 } = await loadFarmWorkflowsDevRuntime();
|
|
@@ -23374,10 +24608,20 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23374
24608
|
logger.info(`Refreshed routes: ${reason}`);
|
|
23375
24609
|
}
|
|
23376
24610
|
}, "refreshRouteDiscovery");
|
|
24611
|
+
const farmDocsFontAssetList = farmDocsDevRuntime ? resolveFarmDocsFontAssets(farmConfig.root) : [];
|
|
23377
24612
|
const farmDocsHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsHandler(farmConfig.docs, {
|
|
23378
24613
|
root: farmConfig.root,
|
|
23379
24614
|
srcDir: farmConfig.srcDir,
|
|
23380
|
-
clientEntry: "/@farm/client.js"
|
|
24615
|
+
clientEntry: "/@farm/client.js",
|
|
24616
|
+
fontAssets: toFarmDocsPublicFontAssets(farmDocsFontAssetList),
|
|
24617
|
+
resolveLayoutFonts: /* @__PURE__ */ __name(async (pathname) => {
|
|
24618
|
+
const layouts = routeManager.matchRoute(pathname).layouts;
|
|
24619
|
+
const layoutModules = await Promise.all(
|
|
24620
|
+
layouts.map((layout2) => routeManager.loadLayoutModule(layout2.modulePath))
|
|
24621
|
+
);
|
|
24622
|
+
return resolveFarmLayoutFonts(layoutModules);
|
|
24623
|
+
}, "resolveLayoutFonts"),
|
|
24624
|
+
fontStylesheetHref: "/@farm/fonts.css"
|
|
23381
24625
|
}) : null;
|
|
23382
24626
|
const farmDocsAPIHandler = farmDocsDevRuntime ? farmDocsDevRuntime.createFarmDocsAPIHandler({
|
|
23383
24627
|
rootDir: farmConfig.root,
|
|
@@ -23385,22 +24629,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23385
24629
|
docs: farmConfig.docs
|
|
23386
24630
|
}) : null;
|
|
23387
24631
|
const farmDocsFontAssets = new Map(
|
|
23388
|
-
|
|
23389
|
-
[
|
|
23390
|
-
"/assets/Geist-Variable-CrgPqtmy.woff2",
|
|
23391
|
-
path25.join(
|
|
23392
|
-
farmConfig.root,
|
|
23393
|
-
"node_modules/geist/dist/fonts/geist-sans/Geist-Variable.woff2"
|
|
23394
|
-
)
|
|
23395
|
-
],
|
|
23396
|
-
[
|
|
23397
|
-
"/assets/GeistMono-Variable-BNLlm6Cd.woff2",
|
|
23398
|
-
path25.join(
|
|
23399
|
-
farmConfig.root,
|
|
23400
|
-
"node_modules/geist/dist/fonts/geist-mono/GeistMono-Variable.woff2"
|
|
23401
|
-
)
|
|
23402
|
-
]
|
|
23403
|
-
] : []
|
|
24632
|
+
farmDocsFontAssetList.map(({ url, sourcePath }) => [url, sourcePath])
|
|
23404
24633
|
);
|
|
23405
24634
|
const logRequest = /* @__PURE__ */ __name((method, urlPath, tag) => {
|
|
23406
24635
|
try {
|
|
@@ -23464,11 +24693,12 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
23464
24693
|
}
|
|
23465
24694
|
}
|
|
23466
24695
|
const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
|
|
23467
|
-
if (farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
|
|
24696
|
+
if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs7.existsSync(farmDocsFontPath)) {
|
|
23468
24697
|
res.statusCode = 200;
|
|
23469
24698
|
res.setHeader("Content-Type", "font/woff2");
|
|
23470
24699
|
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
23471
|
-
|
|
24700
|
+
if (requestMethod === "HEAD") res.end();
|
|
24701
|
+
else fs7.createReadStream(farmDocsFontPath).pipe(res);
|
|
23472
24702
|
return;
|
|
23473
24703
|
}
|
|
23474
24704
|
if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
|
|
@@ -24074,6 +25304,7 @@ function farmPlugin(options = {}, initialPluginManager) {
|
|
|
24074
25304
|
modulePath: toUrlPath(route.modulePath),
|
|
24075
25305
|
isClientComponent: routeSlots.length > 0 ? false : isClientComponent,
|
|
24076
25306
|
shouldHydrate: shouldHydrate || routeSlots.some((slot) => slot.isClientComponent || slot.shouldHydrate),
|
|
25307
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
24077
25308
|
metadata: {
|
|
24078
25309
|
title: mergedMetadata.title,
|
|
24079
25310
|
description: mergedMetadata.description
|
|
@@ -24458,6 +25689,7 @@ export const getManifest = () => ({
|
|
|
24458
25689
|
search: route.search,
|
|
24459
25690
|
isClientComponent: moduleMetadata.isClientComponent,
|
|
24460
25691
|
shouldHydrate: moduleMetadata.shouldHydrate,
|
|
25692
|
+
islandStrategy: moduleMetadata.islandStrategy,
|
|
24461
25693
|
preloads: [route.modulePath],
|
|
24462
25694
|
// In dev, preload is just the module
|
|
24463
25695
|
assets: []
|
|
@@ -24584,8 +25816,8 @@ if (import.meta.hot) {
|
|
|
24584
25816
|
}
|
|
24585
25817
|
logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
|
|
24586
25818
|
logger.info("Pre-rendering SSG pages...");
|
|
24587
|
-
const outDir =
|
|
24588
|
-
const clientDir =
|
|
25819
|
+
const outDir = path27.join(server?.config.root || process.cwd(), options.outDir || "dist");
|
|
25820
|
+
const clientDir = path27.join(outDir, "client");
|
|
24589
25821
|
for (const page2 of ssgPages) {
|
|
24590
25822
|
try {
|
|
24591
25823
|
const staticRequest = new Request(new URL(page2.urlPath, "http://farm.static"));
|
|
@@ -24596,7 +25828,7 @@ if (import.meta.hot) {
|
|
|
24596
25828
|
const layoutModules = await Promise.all(
|
|
24597
25829
|
layouts.map((l) => routeManager.loadLayoutModule(l.modulePath))
|
|
24598
25830
|
);
|
|
24599
|
-
const
|
|
25831
|
+
const React4 = await import("react");
|
|
24600
25832
|
const { renderToString } = await import("react-dom/server");
|
|
24601
25833
|
const PageComponent = mod.default;
|
|
24602
25834
|
const pageProps = {
|
|
@@ -24604,14 +25836,14 @@ if (import.meta.hot) {
|
|
|
24604
25836
|
searchParams: Promise.resolve({}),
|
|
24605
25837
|
path: page2.urlPath
|
|
24606
25838
|
};
|
|
24607
|
-
let pageElement =
|
|
25839
|
+
let pageElement = React4.createElement(
|
|
24608
25840
|
PageComponent,
|
|
24609
25841
|
pageProps
|
|
24610
25842
|
);
|
|
24611
25843
|
for (let i = layoutModules.length - 1; i >= 0; i--) {
|
|
24612
25844
|
const layoutModule = layoutModules[i];
|
|
24613
25845
|
const LayoutComponent = layoutModule.default;
|
|
24614
|
-
pageElement =
|
|
25846
|
+
pageElement = React4.createElement(
|
|
24615
25847
|
LayoutComponent,
|
|
24616
25848
|
{
|
|
24617
25849
|
children: pageElement,
|
|
@@ -24637,8 +25869,8 @@ if (import.meta.hot) {
|
|
|
24637
25869
|
<script type="module" src="/assets/client.js"></script>
|
|
24638
25870
|
</body>
|
|
24639
25871
|
</html>`;
|
|
24640
|
-
const outputPath = page2.urlPath === "/" ?
|
|
24641
|
-
fs7.mkdirSync(
|
|
25872
|
+
const outputPath = page2.urlPath === "/" ? path27.join(clientDir, "index.html") : path27.join(clientDir, page2.urlPath + ".html");
|
|
25873
|
+
fs7.mkdirSync(path27.dirname(outputPath), { recursive: true });
|
|
24642
25874
|
fs7.writeFileSync(outputPath, fullHtml);
|
|
24643
25875
|
const revalidateInfo = page2.revalidate ? ` (revalidate: ${page2.revalidate}s)` : "";
|
|
24644
25876
|
logger.success(` \u2713 ${page2.urlPath}${revalidateInfo}`);
|
|
@@ -24647,7 +25879,7 @@ if (import.meta.hot) {
|
|
|
24647
25879
|
logger.error(` \u2717 ${page2.urlPath}: ${error}`);
|
|
24648
25880
|
}
|
|
24649
25881
|
}
|
|
24650
|
-
const manifestPath =
|
|
25882
|
+
const manifestPath = path27.join(outDir, "__ssg_manifest.json");
|
|
24651
25883
|
fs7.writeFileSync(
|
|
24652
25884
|
manifestPath,
|
|
24653
25885
|
JSON.stringify(
|
|
@@ -24683,9 +25915,9 @@ if (import.meta.hot) {
|
|
|
24683
25915
|
}
|
|
24684
25916
|
const currentFarmConfig = farmApp?.getConfig();
|
|
24685
25917
|
const normalizedFile = file.replace(/\\/g, "/");
|
|
24686
|
-
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) =>
|
|
25918
|
+
const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path27.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
|
|
24687
25919
|
if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
|
|
24688
|
-
logUpdate("PAGE", `updated ${
|
|
25920
|
+
logUpdate("PAGE", `updated ${path27.basename(file)}`);
|
|
24689
25921
|
for (const mod of modules) {
|
|
24690
25922
|
server2.moduleGraph.invalidateModule(mod);
|
|
24691
25923
|
}
|
|
@@ -25076,6 +26308,7 @@ import React from 'react'
|
|
|
25076
26308
|
import { hydrateRoot, createRoot } from 'react-dom/client'
|
|
25077
26309
|
import { installChunkErrorRecovery, SPARouter } from '@farm.js/core/client'
|
|
25078
26310
|
import { createClientPluginManager } from '@farm.js/core/plugin/client'
|
|
26311
|
+
import { scheduleFarmIslandHydration } from '@farm.js/core/internal/client-runtime'
|
|
25079
26312
|
import { reviveDeferredData } from '@farm.js/core/deferred'
|
|
25080
26313
|
import {
|
|
25081
26314
|
createFarmDeploymentMismatchError,
|
|
@@ -25328,6 +26561,7 @@ class LegacyManifestSPARouter {
|
|
|
25328
26561
|
|
|
25329
26562
|
// Only prefetch routes that will hydrate on the client.
|
|
25330
26563
|
if (!match.route.isClientComponent && !match.route.shouldHydrate) return;
|
|
26564
|
+
if (match.route.islandStrategy && match.route.islandStrategy !== 'load') return;
|
|
25331
26565
|
|
|
25332
26566
|
const modulePath = match.route.modulePath;
|
|
25333
26567
|
if (this.moduleCache.has(modulePath)) return;
|
|
@@ -25472,6 +26706,12 @@ let hasClientTakenOver = false;
|
|
|
25472
26706
|
const routeSlotRoots = new Map();
|
|
25473
26707
|
const routeSlotDefinitions = new Map();
|
|
25474
26708
|
let activeRouteInterception = null;
|
|
26709
|
+
let pendingPageHydrationController = null;
|
|
26710
|
+
|
|
26711
|
+
function cancelPendingPageHydration() {
|
|
26712
|
+
pendingPageHydrationController?.abort();
|
|
26713
|
+
pendingPageHydrationController = null;
|
|
26714
|
+
}
|
|
25475
26715
|
|
|
25476
26716
|
function normalizeServerProps(rawProps) {
|
|
25477
26717
|
const props = rawProps && typeof rawProps === 'object' ? { ...rawProps } : {};
|
|
@@ -25540,7 +26780,11 @@ async function hydrateInitialRouteSlots() {
|
|
|
25540
26780
|
routeSlotDefinitions.set(getRouteSlotKey(slot), slot);
|
|
25541
26781
|
if (!slot.isClientComponent && !slot.shouldHydrate) continue;
|
|
25542
26782
|
try {
|
|
25543
|
-
|
|
26783
|
+
const slotHydrated = await renderRouteSlot(slot, 'hydrate');
|
|
26784
|
+
hydrated = slotHydrated || hydrated;
|
|
26785
|
+
if (slotHydrated) {
|
|
26786
|
+
replayPreHydrationClicks(document.getElementById(slot.containerId));
|
|
26787
|
+
}
|
|
25544
26788
|
} catch (error) {
|
|
25545
26789
|
console.warn('[Farm.js] Could not hydrate route slot:', slot.name, error);
|
|
25546
26790
|
}
|
|
@@ -25611,16 +26855,29 @@ function applyCanonicalPathFromProps(props) {
|
|
|
25611
26855
|
window.history.replaceState({ ...(window.history.state || {}), path: canonicalPath }, '', canonicalPath);
|
|
25612
26856
|
}
|
|
25613
26857
|
|
|
25614
|
-
function replayPreHydrationClicks() {
|
|
25615
|
-
|
|
25616
|
-
|
|
26858
|
+
function replayPreHydrationClicks(container = null) {
|
|
26859
|
+
if (!container) {
|
|
26860
|
+
markFarmHydrated();
|
|
26861
|
+
} else {
|
|
26862
|
+
container.dataset.farmIslandHydrated = 'true';
|
|
26863
|
+
}
|
|
25617
26864
|
|
|
25618
26865
|
const queue = Array.isArray(window.__FARM_PREHYDRATION_CLICK_QUEUE__)
|
|
25619
26866
|
? window.__FARM_PREHYDRATION_CLICK_QUEUE__
|
|
25620
26867
|
: [];
|
|
25621
26868
|
if (queue.length === 0) return;
|
|
25622
26869
|
|
|
25623
|
-
const queuedClicks =
|
|
26870
|
+
const queuedClicks = [];
|
|
26871
|
+
const remainingClicks = [];
|
|
26872
|
+
for (const queuedClick of queue) {
|
|
26873
|
+
const target = queuedClick?.target;
|
|
26874
|
+
if (!container || (target instanceof Node && container.contains(target))) {
|
|
26875
|
+
queuedClicks.push(queuedClick);
|
|
26876
|
+
} else {
|
|
26877
|
+
remainingClicks.push(queuedClick);
|
|
26878
|
+
}
|
|
26879
|
+
}
|
|
26880
|
+
queue.splice(0, queue.length, ...remainingClicks);
|
|
25624
26881
|
for (const queuedClick of queuedClicks) {
|
|
25625
26882
|
const target = queuedClick?.target;
|
|
25626
26883
|
if (!target || typeof target.click !== 'function') continue;
|
|
@@ -25629,6 +26886,11 @@ function replayPreHydrationClicks() {
|
|
|
25629
26886
|
}
|
|
25630
26887
|
}
|
|
25631
26888
|
|
|
26889
|
+
function markFarmHydrated() {
|
|
26890
|
+
window.__FARM_HYDRATED__ = true;
|
|
26891
|
+
document.documentElement.dataset.farmHydrated = 'true';
|
|
26892
|
+
}
|
|
26893
|
+
|
|
25632
26894
|
async function buildClientHydrationElement(PageComponent, pageProps) {
|
|
25633
26895
|
let element = React.createElement(PageComponent, pageProps);
|
|
25634
26896
|
const loadingModulePath = window.__FARM_LOADING_MODULE__;
|
|
@@ -25771,9 +27033,10 @@ async function tryHydrateImportedPage(
|
|
|
25771
27033
|
layouts,
|
|
25772
27034
|
useHydrate = false,
|
|
25773
27035
|
existingProps = null,
|
|
27036
|
+
signal = null,
|
|
25774
27037
|
) {
|
|
25775
27038
|
const modulePath = route?.modulePath;
|
|
25776
|
-
if (!modulePath) {
|
|
27039
|
+
if (!modulePath || signal?.aborted) {
|
|
25777
27040
|
return false;
|
|
25778
27041
|
}
|
|
25779
27042
|
|
|
@@ -25782,6 +27045,7 @@ async function tryHydrateImportedPage(
|
|
|
25782
27045
|
pageModule = await import(/* @vite-ignore */ modulePath);
|
|
25783
27046
|
pageModuleCache.set(modulePath, pageModule);
|
|
25784
27047
|
}
|
|
27048
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25785
27049
|
|
|
25786
27050
|
const PageComponent = pageModule?.default;
|
|
25787
27051
|
if (!PageComponent) {
|
|
@@ -25796,6 +27060,7 @@ async function tryHydrateImportedPage(
|
|
|
25796
27060
|
window.location.pathname,
|
|
25797
27061
|
existingProps,
|
|
25798
27062
|
);
|
|
27063
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25799
27064
|
|
|
25800
27065
|
const wrappedElement = useHydrate && container?.id === '__farm_page__'
|
|
25801
27066
|
? wrapWithIntegrationProviders(
|
|
@@ -25806,6 +27071,7 @@ async function tryHydrateImportedPage(
|
|
|
25806
27071
|
currentPageProps,
|
|
25807
27072
|
layouts,
|
|
25808
27073
|
);
|
|
27074
|
+
if (signal?.aborted || !container?.isConnected) return false;
|
|
25809
27075
|
|
|
25810
27076
|
if (useHydrate) {
|
|
25811
27077
|
try {
|
|
@@ -25836,6 +27102,7 @@ async function tryHydrateImportedPage(
|
|
|
25836
27102
|
async function renderPage(pageData) {
|
|
25837
27103
|
const container = document.getElementById('root');
|
|
25838
27104
|
if (!container) return;
|
|
27105
|
+
cancelPendingPageHydration();
|
|
25839
27106
|
const destination = window.location.pathname + window.location.search;
|
|
25840
27107
|
|
|
25841
27108
|
if (pageData.interception) {
|
|
@@ -25852,6 +27119,7 @@ async function renderPage(pageData) {
|
|
|
25852
27119
|
modulePath: pageData.modulePath,
|
|
25853
27120
|
isClientComponent: pageData.isClientComponent === true,
|
|
25854
27121
|
shouldHydrate: pageData.shouldHydrate === true,
|
|
27122
|
+
islandStrategy: pageData.islandStrategy || 'load',
|
|
25855
27123
|
};
|
|
25856
27124
|
const params = pageData.props?.params || {};
|
|
25857
27125
|
const layouts = (pageData.layoutModules || []).map((modulePath, index) => ({
|
|
@@ -26051,14 +27319,6 @@ async function hydrate() {
|
|
|
26051
27319
|
}
|
|
26052
27320
|
|
|
26053
27321
|
try {
|
|
26054
|
-
// Pre-load layout for SPA navigation
|
|
26055
|
-
try {
|
|
26056
|
-
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
26057
|
-
LayoutComponent = layoutModule.default;
|
|
26058
|
-
} catch (e) {
|
|
26059
|
-
console.warn('[Farm.js] Could not preload layout:', e);
|
|
26060
|
-
}
|
|
26061
|
-
|
|
26062
27322
|
// Check if this is a client component (set by SSR)
|
|
26063
27323
|
const isClientComponent = window.__FARM_IS_CLIENT__ === true;
|
|
26064
27324
|
const modulePath = window.__FARM_PAGE_MODULE__;
|
|
@@ -26106,34 +27366,88 @@ async function hydrate() {
|
|
|
26106
27366
|
return
|
|
26107
27367
|
}
|
|
26108
27368
|
|
|
26109
|
-
const
|
|
26110
|
-
|
|
26111
|
-
|
|
26112
|
-
|
|
27369
|
+
const currentRoute = findRoute(window.location.pathname)?.route;
|
|
27370
|
+
const islandStrategy = window.__FARM_ISLAND_STRATEGY__ || currentRoute?.islandStrategy || 'load';
|
|
27371
|
+
pageContainer.dataset.farmIsland = 'page';
|
|
27372
|
+
pageContainer.dataset.farmIslandStrategy = islandStrategy;
|
|
26113
27373
|
|
|
26114
|
-
|
|
27374
|
+
const hydrationPathname = window.location.pathname;
|
|
27375
|
+
const hydrationController = new AbortController();
|
|
27376
|
+
pendingPageHydrationController = hydrationController;
|
|
26115
27377
|
try {
|
|
26116
|
-
|
|
26117
|
-
pageContainer,
|
|
26118
|
-
|
|
26119
|
-
|
|
26120
|
-
|
|
26121
|
-
|
|
26122
|
-
|
|
26123
|
-
|
|
26124
|
-
|
|
26125
|
-
|
|
26126
|
-
|
|
26127
|
-
|
|
26128
|
-
}
|
|
27378
|
+
await scheduleFarmIslandHydration({
|
|
27379
|
+
container: pageContainer,
|
|
27380
|
+
strategy: islandStrategy,
|
|
27381
|
+
signal: hydrationController.signal,
|
|
27382
|
+
hydrate: async () => {
|
|
27383
|
+
if (
|
|
27384
|
+
hydrationController.signal.aborted ||
|
|
27385
|
+
!pageContainer.isConnected ||
|
|
27386
|
+
window.location.pathname !== hydrationPathname
|
|
27387
|
+
) {
|
|
27388
|
+
return;
|
|
27389
|
+
}
|
|
26129
27390
|
|
|
26130
|
-
|
|
26131
|
-
|
|
26132
|
-
|
|
26133
|
-
|
|
26134
|
-
|
|
27391
|
+
// Layout code is only needed when this route boundary actually hydrates.
|
|
27392
|
+
try {
|
|
27393
|
+
const layoutModule = await import(/* @vite-ignore */ '/src/app/layout.tsx');
|
|
27394
|
+
LayoutComponent = layoutModule.default;
|
|
27395
|
+
} catch (e) {
|
|
27396
|
+
console.warn('[Farm.js] Could not preload layout:', e);
|
|
27397
|
+
}
|
|
27398
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) return;
|
|
27399
|
+
|
|
27400
|
+
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
27401
|
+
container: pageContainer,
|
|
27402
|
+
mode: shouldHydrate ? 'hydrate' : 'render',
|
|
27403
|
+
});
|
|
27404
|
+
|
|
27405
|
+
let hydrated = false;
|
|
27406
|
+
try {
|
|
27407
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
27408
|
+
await farmClientRuntime.failHydration(
|
|
27409
|
+
hydrationSession,
|
|
27410
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
27411
|
+
);
|
|
27412
|
+
return;
|
|
27413
|
+
}
|
|
27414
|
+
hydrated = await tryHydrateImportedPage(
|
|
27415
|
+
pageContainer,
|
|
27416
|
+
{ modulePath },
|
|
27417
|
+
currentPageProps.params || {},
|
|
27418
|
+
layouts,
|
|
27419
|
+
shouldHydrate,
|
|
27420
|
+
currentPageProps,
|
|
27421
|
+
hydrationController.signal,
|
|
27422
|
+
);
|
|
27423
|
+
if (hydrationController.signal.aborted || !pageContainer.isConnected) {
|
|
27424
|
+
await farmClientRuntime.failHydration(
|
|
27425
|
+
hydrationSession,
|
|
27426
|
+
new DOMException('Route hydration was cancelled', 'AbortError'),
|
|
27427
|
+
);
|
|
27428
|
+
return;
|
|
27429
|
+
}
|
|
27430
|
+
await farmClientRuntime.completeHydration(hydrationSession);
|
|
27431
|
+
} catch (error) {
|
|
27432
|
+
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
27433
|
+
throw error;
|
|
27434
|
+
}
|
|
26135
27435
|
|
|
26136
|
-
|
|
27436
|
+
if (hydrated) {
|
|
27437
|
+
// The scheduler owns queue draining and exactly-once click replay.
|
|
27438
|
+
markFarmHydrated();
|
|
27439
|
+
console.log('[Farm.js] \u2705 Hydrated:', modulePath, '(' + islandStrategy + ')');
|
|
27440
|
+
return;
|
|
27441
|
+
}
|
|
27442
|
+
|
|
27443
|
+
console.log('[Farm.js] Server component - SPA router ready')
|
|
27444
|
+
},
|
|
27445
|
+
});
|
|
27446
|
+
} finally {
|
|
27447
|
+
if (pendingPageHydrationController === hydrationController) {
|
|
27448
|
+
pendingPageHydrationController = null;
|
|
27449
|
+
}
|
|
27450
|
+
}
|
|
26137
27451
|
} catch (error) {
|
|
26138
27452
|
console.error('[Farm.js] Hydration error:', error)
|
|
26139
27453
|
}
|
|
@@ -26236,7 +27550,7 @@ function generateClientManifest(bundle) {
|
|
|
26236
27550
|
}
|
|
26237
27551
|
async function defineConfig2(config = {}) {
|
|
26238
27552
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
26239
|
-
const appRoot =
|
|
27553
|
+
const appRoot = path27.resolve(config.root || process.cwd());
|
|
26240
27554
|
if (config.extends?.length) {
|
|
26241
27555
|
const { config: layeredConfig } = await Promise.resolve().then(() => (init_layers(), layers_exports)).then(
|
|
26242
27556
|
({ resolveFarmLayers: resolveFarmLayers2 }) => resolveFarmLayers2(config, {
|
|
@@ -26381,13 +27695,16 @@ async function defineConfig2(config = {}) {
|
|
|
26381
27695
|
customLogger: farmLogger,
|
|
26382
27696
|
clearScreen: false,
|
|
26383
27697
|
optimizeDeps: {
|
|
26384
|
-
|
|
26385
|
-
|
|
26386
|
-
|
|
26387
|
-
|
|
26388
|
-
|
|
26389
|
-
|
|
26390
|
-
|
|
27698
|
+
...createFarmClientOptimizeDepsConfig(
|
|
27699
|
+
createFarmClientOptimizeDepsEntries(
|
|
27700
|
+
appRoot,
|
|
27701
|
+
getFarmAppDirectories({ ...config, root: appRoot })
|
|
27702
|
+
)
|
|
27703
|
+
),
|
|
27704
|
+
// Pre-bundle every framework client-runtime entry with React. Without
|
|
27705
|
+
// this, Vite can discover a linked Farm entry after the page has loaded,
|
|
27706
|
+
// regenerate the optimizer browser hash, and leave React DOM holding a
|
|
27707
|
+
// different React module instance from a client component.
|
|
26391
27708
|
// Exclude server-side packages from browser bundling
|
|
26392
27709
|
exclude: [
|
|
26393
27710
|
"@farm.js/core/server",
|
|
@@ -26422,7 +27739,7 @@ async function defineConfig2(config = {}) {
|
|
|
26422
27739
|
// Stub out problematic server-only modules during dev mode
|
|
26423
27740
|
alias: {
|
|
26424
27741
|
...getFarmLayerAliases(config.layers),
|
|
26425
|
-
"@":
|
|
27742
|
+
"@": path27.resolve(appRoot, "src"),
|
|
26426
27743
|
// Nitro internals that should not be resolved in browser
|
|
26427
27744
|
"supports-color": "data:text/javascript,export default false; export const supportsColor = false; export const stdout = false; export const stderr = false;",
|
|
26428
27745
|
"@poppinss/dumper": "data:text/javascript,export default {};",
|
|
@@ -26439,7 +27756,7 @@ async function defineConfig2(config = {}) {
|
|
|
26439
27756
|
}
|
|
26440
27757
|
};
|
|
26441
27758
|
}
|
|
26442
|
-
var fs7,
|
|
27759
|
+
var fs7, path27, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES;
|
|
26443
27760
|
var init_vite = __esm({
|
|
26444
27761
|
"src/vite.ts"() {
|
|
26445
27762
|
"use strict";
|
|
@@ -26460,7 +27777,7 @@ var init_vite = __esm({
|
|
|
26460
27777
|
init_route_context();
|
|
26461
27778
|
init_devtools_config();
|
|
26462
27779
|
fs7 = __toESM(require("fs"));
|
|
26463
|
-
|
|
27780
|
+
path27 = __toESM(require("path"));
|
|
26464
27781
|
init_layers();
|
|
26465
27782
|
init_environment_vite();
|
|
26466
27783
|
init_version();
|
|
@@ -26470,9 +27787,12 @@ var init_vite = __esm({
|
|
|
26470
27787
|
init_image_config();
|
|
26471
27788
|
init_image_vite();
|
|
26472
27789
|
init_font_vite();
|
|
27790
|
+
init_font();
|
|
26473
27791
|
init_image_server();
|
|
26474
27792
|
init_server2();
|
|
26475
27793
|
init_routing();
|
|
27794
|
+
init_vite_config();
|
|
27795
|
+
init_fonts();
|
|
26476
27796
|
ALL_TYPE_ARTIFACTS = {
|
|
26477
27797
|
routes: true,
|
|
26478
27798
|
api: true,
|
|
@@ -27866,6 +29186,7 @@ init_layers();
|
|
|
27866
29186
|
init_environment_vite();
|
|
27867
29187
|
init_last_modified();
|
|
27868
29188
|
init_search_client();
|
|
29189
|
+
init_fonts();
|
|
27869
29190
|
|
|
27870
29191
|
// src/route-runtime-manifest.ts
|
|
27871
29192
|
var import_path8 = __toESM(require("path"));
|
|
@@ -28047,7 +29368,7 @@ function farmRoutePatternToVercelSource(pattern) {
|
|
|
28047
29368
|
} else if (segment === "*" || /^\[.+\]$/.test(segment)) {
|
|
28048
29369
|
source += "/([^/]+)";
|
|
28049
29370
|
} else {
|
|
28050
|
-
source += `/${
|
|
29371
|
+
source += `/${escapeRegExp3(segment)}`;
|
|
28051
29372
|
}
|
|
28052
29373
|
}
|
|
28053
29374
|
return source || "/";
|
|
@@ -28092,10 +29413,35 @@ function normalizePattern(value) {
|
|
|
28092
29413
|
return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
|
|
28093
29414
|
}
|
|
28094
29415
|
__name(normalizePattern, "normalizePattern");
|
|
28095
|
-
function
|
|
29416
|
+
function escapeRegExp3(value) {
|
|
29417
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
29418
|
+
}
|
|
29419
|
+
__name(escapeRegExp3, "escapeRegExp");
|
|
29420
|
+
|
|
29421
|
+
// src/nitro/vercel-assets.ts
|
|
29422
|
+
var FARM_IMMUTABLE_ASSET_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
29423
|
+
function createFarmVercelImmutableAssetRoute(basePath = "/") {
|
|
29424
|
+
const normalizedBasePath = normalizeBasePath3(basePath);
|
|
29425
|
+
const escapedBasePath = escapeRegex(normalizedBasePath);
|
|
29426
|
+
const prefix = escapedBasePath ? `/${escapedBasePath}` : "";
|
|
29427
|
+
return {
|
|
29428
|
+
src: `^${prefix}/(?:assets|chunks)/(?:.+/)*[^/]+-h(?:[a-fA-F0-9]{8}|[a-fA-F0-9]{12}|[a-fA-F0-9]{16})\\.(?!(?:[hH][tT][mM][lL]?)$)[^/]+$`,
|
|
29429
|
+
headers: {
|
|
29430
|
+
"Cache-Control": FARM_IMMUTABLE_ASSET_CACHE_CONTROL
|
|
29431
|
+
},
|
|
29432
|
+
continue: true,
|
|
29433
|
+
caseSensitive: true
|
|
29434
|
+
};
|
|
29435
|
+
}
|
|
29436
|
+
__name(createFarmVercelImmutableAssetRoute, "createFarmVercelImmutableAssetRoute");
|
|
29437
|
+
function normalizeBasePath3(basePath) {
|
|
29438
|
+
return basePath.trim().replace(/^\/+|\/+$/g, "");
|
|
29439
|
+
}
|
|
29440
|
+
__name(normalizeBasePath3, "normalizeBasePath");
|
|
29441
|
+
function escapeRegex(value) {
|
|
28096
29442
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28097
29443
|
}
|
|
28098
|
-
__name(
|
|
29444
|
+
__name(escapeRegex, "escapeRegex");
|
|
28099
29445
|
|
|
28100
29446
|
// src/nitro/universal-build.ts
|
|
28101
29447
|
init_catalog();
|
|
@@ -28304,6 +29650,10 @@ function isCloudflareImagePreset(preset) {
|
|
|
28304
29650
|
return preset === "cloudflare" || preset === "cloudflare-pages" || preset === "cloudflare-module";
|
|
28305
29651
|
}
|
|
28306
29652
|
__name(isCloudflareImagePreset, "isCloudflareImagePreset");
|
|
29653
|
+
function shouldUseExternalMetadataImageRuntime(preset, hasGeneratedMetadataImages) {
|
|
29654
|
+
return hasGeneratedMetadataImages && preset !== "vercel-edge" && !isCloudflareImagePreset(preset);
|
|
29655
|
+
}
|
|
29656
|
+
__name(shouldUseExternalMetadataImageRuntime, "shouldUseExternalMetadataImageRuntime");
|
|
28307
29657
|
function resolveImageRuntime(config, preset) {
|
|
28308
29658
|
if (config.images.provider === "none") return "none";
|
|
28309
29659
|
const cloudflarePreset = isCloudflareImagePreset(preset);
|
|
@@ -28321,6 +29671,31 @@ function isNitroRollupExternal(id) {
|
|
|
28321
29671
|
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/");
|
|
28322
29672
|
}
|
|
28323
29673
|
__name(isNitroRollupExternal, "isNitroRollupExternal");
|
|
29674
|
+
var FARM_METADATA_IMAGE_WASM_PREFIX = "\0farm-metadata-image-wasm:";
|
|
29675
|
+
function createMetadataImageWasmPlugin() {
|
|
29676
|
+
return {
|
|
29677
|
+
name: "farm-metadata-image-wasm",
|
|
29678
|
+
resolveId(source, importer) {
|
|
29679
|
+
if (!source.endsWith(".wasm?module") || !importer?.replace(/\\/g, "/").includes("/@vercel/og/")) {
|
|
29680
|
+
return null;
|
|
29681
|
+
}
|
|
29682
|
+
const requestPath = source.slice(0, -"?module".length);
|
|
29683
|
+
const resolvedPath = import_path12.default.isAbsolute(requestPath) ? requestPath : import_path12.default.resolve(import_path12.default.dirname(importer.split("?", 1)[0]), requestPath);
|
|
29684
|
+
return `${FARM_METADATA_IMAGE_WASM_PREFIX}${resolvedPath}`;
|
|
29685
|
+
},
|
|
29686
|
+
load(id) {
|
|
29687
|
+
if (!id.startsWith(FARM_METADATA_IMAGE_WASM_PREFIX)) return null;
|
|
29688
|
+
const wasmPath = id.slice(FARM_METADATA_IMAGE_WASM_PREFIX.length);
|
|
29689
|
+
const encoded = (0, import_fs5.readFileSync)(wasmPath).toString("base64");
|
|
29690
|
+
return `
|
|
29691
|
+
const encoded = ${JSON.stringify(encoded)};
|
|
29692
|
+
const bytes = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));
|
|
29693
|
+
export default new WebAssembly.Module(bytes);
|
|
29694
|
+
`;
|
|
29695
|
+
}
|
|
29696
|
+
};
|
|
29697
|
+
}
|
|
29698
|
+
__name(createMetadataImageWasmPlugin, "createMetadataImageWasmPlugin");
|
|
28324
29699
|
function collectSSRExternalPackages(ssrBundle) {
|
|
28325
29700
|
const emittedFiles = new Set(
|
|
28326
29701
|
Object.keys(ssrBundle).map((fileName) => fileName.replace(/^\.\//, ""))
|
|
@@ -28704,6 +30079,9 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
28704
30079
|
}
|
|
28705
30080
|
const { bundle: ssrBundle, entryFile: ssrEntryFile, configuredHeaderRoutes } = ssrResult;
|
|
28706
30081
|
await writeSSRAssetsToClient(ssrBundle, clientOutputDir);
|
|
30082
|
+
if (config.docs.enabled) {
|
|
30083
|
+
await copyFarmDocsFontAssetsToClient(root, clientOutputDir);
|
|
30084
|
+
}
|
|
28707
30085
|
logger.info(`\u{1F680} Building server with Nitro (preset: ${preset})...`);
|
|
28708
30086
|
await buildNitroUniversal(
|
|
28709
30087
|
config,
|
|
@@ -28758,6 +30136,17 @@ async function writeSSRAssetsToClient(bundle, outputDir) {
|
|
|
28758
30136
|
}
|
|
28759
30137
|
}
|
|
28760
30138
|
__name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
|
|
30139
|
+
async function copyFarmDocsFontAssetsToClient(root, outputDir) {
|
|
30140
|
+
const fs8 = await import("fs/promises");
|
|
30141
|
+
await Promise.all(
|
|
30142
|
+
resolveFarmDocsFontAssets(root).map(async ({ sourcePath, url }) => {
|
|
30143
|
+
const targetPath = import_path12.default.join(outputDir, url.replace(/^\/+/, ""));
|
|
30144
|
+
await fs8.mkdir(import_path12.default.dirname(targetPath), { recursive: true });
|
|
30145
|
+
await fs8.copyFile(sourcePath, targetPath);
|
|
30146
|
+
})
|
|
30147
|
+
);
|
|
30148
|
+
}
|
|
30149
|
+
__name(copyFarmDocsFontAssetsToClient, "copyFarmDocsFontAssetsToClient");
|
|
28761
30150
|
async function mergeBuiltFontCss(outputDir, fontCssSource) {
|
|
28762
30151
|
const fs8 = await import("fs/promises");
|
|
28763
30152
|
const fontCssPath = import_path12.default.join(outputDir, "farm-fonts.css");
|
|
@@ -28776,11 +30165,8 @@ async function mergeBuiltFontCss(outputDir, fontCssSource) {
|
|
|
28776
30165
|
} catch {
|
|
28777
30166
|
}
|
|
28778
30167
|
const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
|
|
30168
|
+
await fs8.writeFile(fontCssPath, normalizedFontCss);
|
|
28779
30169
|
await fs8.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
|
|
28780
|
-
try {
|
|
28781
|
-
await fs8.rm(fontCssPath, { force: true });
|
|
28782
|
-
} catch {
|
|
28783
|
-
}
|
|
28784
30170
|
}
|
|
28785
30171
|
__name(mergeBuiltFontCss, "mergeBuiltFontCss");
|
|
28786
30172
|
var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
|
|
@@ -28845,7 +30231,11 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
28845
30231
|
const metadata = getClientModuleMetadata(route.modulePath, root);
|
|
28846
30232
|
if (metadata.shouldHydrate) {
|
|
28847
30233
|
const relativePath2 = route.modulePath.replace(root, "").replace(/^\//, "");
|
|
28848
|
-
clientPages.push({
|
|
30234
|
+
clientPages.push({
|
|
30235
|
+
...route,
|
|
30236
|
+
relativePath: relativePath2,
|
|
30237
|
+
islandStrategy: metadata.islandStrategy ?? "load"
|
|
30238
|
+
});
|
|
28849
30239
|
logger.info(`\u{1F4F1} Found hydratable route: ${route.pattern} -> ${route.modulePath}`);
|
|
28850
30240
|
}
|
|
28851
30241
|
} catch (error) {
|
|
@@ -28919,13 +30309,14 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
28919
30309
|
},
|
|
28920
30310
|
output: {
|
|
28921
30311
|
entryFileNames: "[name].js",
|
|
28922
|
-
chunkFileNames: "chunks/[name]-[hash].js",
|
|
30312
|
+
chunkFileNames: "chunks/[name]-h[hash].js",
|
|
30313
|
+
hashCharacters: "hex",
|
|
28923
30314
|
// Use predictable name for CSS so we can reference it in SSR HTML
|
|
28924
30315
|
assetFileNames: /* @__PURE__ */ __name((assetInfo) => {
|
|
28925
30316
|
if (assetInfo.name?.endsWith(".css")) {
|
|
28926
30317
|
return "farm-client.css";
|
|
28927
30318
|
}
|
|
28928
|
-
return "assets/[name]-[hash][extname]";
|
|
30319
|
+
return "assets/[name]-h[hash][extname]";
|
|
28929
30320
|
}, "assetFileNames")
|
|
28930
30321
|
},
|
|
28931
30322
|
// Externalize Node.js built-ins and server-side modules for client build
|
|
@@ -29524,10 +30915,13 @@ document.addEventListener("click", function(e) {
|
|
|
29524
30915
|
const imports = [];
|
|
29525
30916
|
const routeEntries = [];
|
|
29526
30917
|
const routeSlotEntries = [];
|
|
29527
|
-
clientPages.forEach((page2
|
|
30918
|
+
clientPages.forEach((page2) => {
|
|
29528
30919
|
const importPath = toImportPath(page2.modulePath);
|
|
29529
|
-
|
|
29530
|
-
|
|
30920
|
+
routeEntries.push(` {
|
|
30921
|
+
pattern: ${JSON.stringify(page2.pattern)},
|
|
30922
|
+
islandStrategy: ${JSON.stringify(page2.islandStrategy)},
|
|
30923
|
+
load: () => import(${JSON.stringify(importPath)}).then((module) => module.default),
|
|
30924
|
+
}`);
|
|
29531
30925
|
});
|
|
29532
30926
|
clientRouteSlots.forEach((slot, index) => {
|
|
29533
30927
|
const importPath = toImportPath(slot.modulePath);
|
|
@@ -29548,7 +30942,7 @@ ${cssImport}
|
|
|
29548
30942
|
${layoutImports}
|
|
29549
30943
|
import React from "react";
|
|
29550
30944
|
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
29551
|
-
import { createClientPluginManager, installChunkErrorRecovery } from "@farm.js/core/internal/client-runtime";
|
|
30945
|
+
import { createClientPluginManager, installChunkErrorRecovery, scheduleFarmIslandHydration } from "@farm.js/core/internal/client-runtime";
|
|
29552
30946
|
import { matchFarmRoute } from "@farm.js/core/router";
|
|
29553
30947
|
${clientPluginEntry.imports}
|
|
29554
30948
|
${i18nClientRuntime}
|
|
@@ -29621,6 +31015,12 @@ function matchRoute(pathname) {
|
|
|
29621
31015
|
return null;
|
|
29622
31016
|
}
|
|
29623
31017
|
|
|
31018
|
+
async function loadRouteComponent(route) {
|
|
31019
|
+
if (route.Component) return route.Component;
|
|
31020
|
+
route.Component = await route.load();
|
|
31021
|
+
return route.Component;
|
|
31022
|
+
}
|
|
31023
|
+
|
|
29624
31024
|
function matchesRoutePrefix(pathname, pattern) {
|
|
29625
31025
|
if (pattern === "/") return true;
|
|
29626
31026
|
const pathSegments = getFarmRoutePathname(pathname).split("/").filter(Boolean);
|
|
@@ -29763,15 +31163,24 @@ function clearRouteInterception(destination) {
|
|
|
29763
31163
|
|
|
29764
31164
|
// State
|
|
29765
31165
|
let reactRoot = null;
|
|
31166
|
+
let reactRootContainer = null;
|
|
29766
31167
|
let currentPathname = null;
|
|
29767
31168
|
let isHydrated = false;
|
|
31169
|
+
let pendingPageHydrationController = null;
|
|
29768
31170
|
|
|
29769
31171
|
${generateUniversalRouterStateRuntime()}
|
|
29770
31172
|
|
|
31173
|
+
function cancelPendingPageHydration() {
|
|
31174
|
+
pendingPageHydrationController?.abort();
|
|
31175
|
+
pendingPageHydrationController = null;
|
|
31176
|
+
}
|
|
31177
|
+
|
|
29771
31178
|
function resetReactRoot() {
|
|
31179
|
+
cancelPendingPageHydration();
|
|
29772
31180
|
if (!reactRoot) return;
|
|
29773
31181
|
reactRoot.unmount();
|
|
29774
31182
|
reactRoot = null;
|
|
31183
|
+
reactRootContainer = null;
|
|
29775
31184
|
isHydrated = false;
|
|
29776
31185
|
}
|
|
29777
31186
|
|
|
@@ -29785,49 +31194,77 @@ async function hydrate() {
|
|
|
29785
31194
|
return;
|
|
29786
31195
|
}
|
|
29787
31196
|
|
|
29788
|
-
const hasRouteSlots =
|
|
29789
|
-
Array.isArray(window.__FARM_ROUTE_SLOTS__) && window.__FARM_ROUTE_SLOTS__.length > 0;
|
|
29790
31197
|
const container =
|
|
29791
|
-
|
|
31198
|
+
document.getElementById("__farm_page__") ||
|
|
29792
31199
|
document.getElementById("root");
|
|
29793
31200
|
if (!container) {
|
|
29794
31201
|
console.error("[Farm.js] No root element found");
|
|
29795
31202
|
return;
|
|
29796
31203
|
}
|
|
29797
31204
|
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
const searchParams = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
29801
|
-
|
|
29802
|
-
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
29803
|
-
|
|
29804
|
-
// Create page element and wrap with layouts
|
|
29805
|
-
const pageElement = React.createElement(Component, props);
|
|
29806
|
-
const wrappedElement = hasRouteSlots
|
|
29807
|
-
? pageElement
|
|
29808
|
-
: wrapWithLayouts(pageElement, pathname, params);
|
|
29809
|
-
|
|
29810
|
-
const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
|
|
29811
|
-
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
29812
|
-
container,
|
|
29813
|
-
mode: shouldHydrate ? "hydrate" : "render",
|
|
29814
|
-
});
|
|
31205
|
+
container.dataset.farmIsland = "page";
|
|
31206
|
+
container.dataset.farmIslandStrategy = matched.route.islandStrategy || "load";
|
|
29815
31207
|
|
|
31208
|
+
const hydrationController = new AbortController();
|
|
31209
|
+
pendingPageHydrationController = hydrationController;
|
|
29816
31210
|
try {
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29821
|
-
|
|
29822
|
-
|
|
29823
|
-
|
|
29824
|
-
|
|
31211
|
+
await scheduleFarmIslandHydration({
|
|
31212
|
+
container,
|
|
31213
|
+
strategy: matched.route.islandStrategy,
|
|
31214
|
+
signal: hydrationController.signal,
|
|
31215
|
+
hydrate: async function() {
|
|
31216
|
+
const Component = await loadRouteComponent(matched.route);
|
|
31217
|
+
if (
|
|
31218
|
+
hydrationController.signal.aborted ||
|
|
31219
|
+
!container.isConnected ||
|
|
31220
|
+
window.location.pathname !== pathname
|
|
31221
|
+
) {
|
|
31222
|
+
return;
|
|
31223
|
+
}
|
|
31224
|
+
const params = matched.params;
|
|
31225
|
+
const searchParams = Object.fromEntries(new URLSearchParams(window.location.search));
|
|
31226
|
+
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
31227
|
+
const pageElement = React.createElement(Component, props);
|
|
31228
|
+
const wrappedElement = container.id === "__farm_page__"
|
|
31229
|
+
? pageElement
|
|
31230
|
+
: wrapWithLayouts(pageElement, pathname, params);
|
|
31231
|
+
const shouldHydrate = !isHydrated && Boolean(container.innerHTML.trim());
|
|
31232
|
+
const hydrationSession = await farmClientRuntime.beginHydration({
|
|
31233
|
+
container,
|
|
31234
|
+
mode: shouldHydrate ? "hydrate" : "render",
|
|
31235
|
+
});
|
|
31236
|
+
|
|
31237
|
+
try {
|
|
31238
|
+
if (hydrationController.signal.aborted || !container.isConnected) {
|
|
31239
|
+
await farmClientRuntime.failHydration(
|
|
31240
|
+
hydrationSession,
|
|
31241
|
+
new DOMException("Route hydration was cancelled", "AbortError"),
|
|
31242
|
+
);
|
|
31243
|
+
return;
|
|
31244
|
+
}
|
|
31245
|
+
if (shouldHydrate) {
|
|
31246
|
+
reactRoot = hydrateRoot(container, wrappedElement);
|
|
31247
|
+
reactRootContainer = container;
|
|
31248
|
+
isHydrated = true;
|
|
31249
|
+
} else {
|
|
31250
|
+
if (!reactRoot) {
|
|
31251
|
+
reactRoot = createRoot(container);
|
|
31252
|
+
reactRootContainer = container;
|
|
31253
|
+
}
|
|
31254
|
+
reactRoot.render(wrappedElement);
|
|
31255
|
+
}
|
|
31256
|
+
currentPathname = pathname;
|
|
31257
|
+
await farmClientRuntime.completeHydration(hydrationSession);
|
|
31258
|
+
} catch (error) {
|
|
31259
|
+
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
31260
|
+
console.error("[Farm.js] Hydration error:", error);
|
|
31261
|
+
}
|
|
31262
|
+
},
|
|
31263
|
+
});
|
|
31264
|
+
} finally {
|
|
31265
|
+
if (pendingPageHydrationController === hydrationController) {
|
|
31266
|
+
pendingPageHydrationController = null;
|
|
29825
31267
|
}
|
|
29826
|
-
currentPathname = pathname;
|
|
29827
|
-
await farmClientRuntime.completeHydration(hydrationSession);
|
|
29828
|
-
} catch (error) {
|
|
29829
|
-
await farmClientRuntime.failHydration(hydrationSession, error);
|
|
29830
|
-
console.error("[Farm.js] Hydration error:", error);
|
|
29831
31268
|
}
|
|
29832
31269
|
}
|
|
29833
31270
|
|
|
@@ -29856,6 +31293,8 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29856
31293
|
const from = this.currentPath;
|
|
29857
31294
|
if (await this.shouldBlockNavigation({ from, to, action })) return;
|
|
29858
31295
|
|
|
31296
|
+
// A route transition invalidates any trigger waiting on the previous DOM boundary.
|
|
31297
|
+
cancelPendingPageHydration();
|
|
29859
31298
|
this.saveScrollPosition(window.location.pathname);
|
|
29860
31299
|
this.startNavigation(from, url, action);
|
|
29861
31300
|
let clientNavigation;
|
|
@@ -29922,7 +31361,9 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29922
31361
|
}
|
|
29923
31362
|
|
|
29924
31363
|
if (matched) {
|
|
29925
|
-
|
|
31364
|
+
// Navigation itself signals intent, so destination routes load eagerly even
|
|
31365
|
+
// when their initial document hydration strategy is deferred.
|
|
31366
|
+
const Component = await loadRouteComponent(matched.route);
|
|
29926
31367
|
const params = matched.params;
|
|
29927
31368
|
const searchParams = Object.fromEntries(url.searchParams);
|
|
29928
31369
|
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
@@ -29948,8 +31389,10 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29948
31389
|
|
|
29949
31390
|
const container = document.getElementById("root");
|
|
29950
31391
|
if (container) {
|
|
31392
|
+
if (reactRoot && reactRootContainer !== container) resetReactRoot();
|
|
29951
31393
|
if (!reactRoot) {
|
|
29952
31394
|
reactRoot = createRoot(container);
|
|
31395
|
+
reactRootContainer = container;
|
|
29953
31396
|
}
|
|
29954
31397
|
reactRoot.render(wrappedElement);
|
|
29955
31398
|
currentPathname = pathname;
|
|
@@ -29959,7 +31402,7 @@ ${generateUniversalRouterStateProperties()}
|
|
|
29959
31402
|
const html = await this.fetchPage(url.pathname + url.search);
|
|
29960
31403
|
await farmClientRuntime.markNavigationLoaded(clientNavigation, html);
|
|
29961
31404
|
await this.runViewTransition(options.viewTransition, async () => {
|
|
29962
|
-
if (!this.swapContent(html, url.pathname + url.search)) {
|
|
31405
|
+
if (!(await this.swapContent(html, url.pathname + url.search))) {
|
|
29963
31406
|
throw new Error("Farm could not swap the target document");
|
|
29964
31407
|
}
|
|
29965
31408
|
const historyState = createHistoryState(
|
|
@@ -30014,7 +31457,7 @@ ${generateUniversalRouterStateProperties()}
|
|
|
30014
31457
|
return html;
|
|
30015
31458
|
},
|
|
30016
31459
|
|
|
30017
|
-
swapContent: function(html, targetPath) {
|
|
31460
|
+
swapContent: async function(html, targetPath) {
|
|
30018
31461
|
const parser = new DOMParser();
|
|
30019
31462
|
const doc = parser.parseFromString(html, "text/html");
|
|
30020
31463
|
if (isFarmLocaleDocumentChange(doc)) return false;
|
|
@@ -30054,18 +31497,18 @@ ${generateUniversalRouterStateProperties()}
|
|
|
30054
31497
|
const matched = matchRoute(newPathname);
|
|
30055
31498
|
if (matched) {
|
|
30056
31499
|
// Re-hydrate the client component
|
|
30057
|
-
const Component = matched.route
|
|
31500
|
+
const Component = await loadRouteComponent(matched.route);
|
|
30058
31501
|
const params = matched.params;
|
|
30059
31502
|
const searchParams = Object.fromEntries(targetUrl.searchParams);
|
|
30060
31503
|
const props = { params: params, searchParams: Promise.resolve(searchParams) };
|
|
30061
31504
|
const pageElement = React.createElement(Component, props);
|
|
30062
|
-
const hasRouteSlots = nextRouteSlots.length > 0;
|
|
30063
31505
|
const pageContainer =
|
|
30064
|
-
|
|
30065
|
-
const wrappedElement =
|
|
31506
|
+
document.getElementById("__farm_page__") || currentRoot;
|
|
31507
|
+
const wrappedElement = pageContainer.id === "__farm_page__"
|
|
30066
31508
|
? pageElement
|
|
30067
31509
|
: wrapWithLayouts(pageElement, newPathname, params);
|
|
30068
31510
|
reactRoot = hydrateRoot(pageContainer, wrappedElement);
|
|
31511
|
+
reactRootContainer = pageContainer;
|
|
30069
31512
|
isHydrated = true;
|
|
30070
31513
|
}
|
|
30071
31514
|
return true;
|
|
@@ -30356,6 +31799,10 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30356
31799
|
i18nCatalogs
|
|
30357
31800
|
);
|
|
30358
31801
|
const virtualEntryId = "\0virtual:farm-ssr-entry";
|
|
31802
|
+
const useExternalMetadataImageRuntime = shouldUseExternalMetadataImageRuntime(
|
|
31803
|
+
preset,
|
|
31804
|
+
metadataImageRoutes.some((image) => image.sourceType === "module")
|
|
31805
|
+
);
|
|
30359
31806
|
try {
|
|
30360
31807
|
await viteBuild({
|
|
30361
31808
|
root,
|
|
@@ -30376,6 +31823,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30376
31823
|
external: [
|
|
30377
31824
|
"fsevents",
|
|
30378
31825
|
"sharp",
|
|
31826
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : [],
|
|
30379
31827
|
"@prisma/client",
|
|
30380
31828
|
"@prisma/client/default",
|
|
30381
31829
|
"@prisma/client/default.js",
|
|
@@ -30404,6 +31852,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30404
31852
|
external: [
|
|
30405
31853
|
"fsevents",
|
|
30406
31854
|
"sharp",
|
|
31855
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : [],
|
|
30407
31856
|
"esbuild",
|
|
30408
31857
|
"lightningcss",
|
|
30409
31858
|
"rollup",
|
|
@@ -30430,7 +31879,12 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30430
31879
|
// React runtime. Leaving a React component package external can make it
|
|
30431
31880
|
// resolve a second React instance at runtime and break hooks during SSR.
|
|
30432
31881
|
// Native and build-only packages above remain explicitly external.
|
|
30433
|
-
noExternal: preset === "cloudflare-module" ? [
|
|
31882
|
+
noExternal: preset === "cloudflare-module" ? [
|
|
31883
|
+
"@farm.js/core",
|
|
31884
|
+
"@farm.js/core/image",
|
|
31885
|
+
"better-call",
|
|
31886
|
+
...metadataImageRoutes.some((image) => image.sourceType === "module") ? ["@vercel/og"] : []
|
|
31887
|
+
] : true
|
|
30434
31888
|
},
|
|
30435
31889
|
define: {
|
|
30436
31890
|
__FARM_ENV__: JSON.stringify(config.env || { server: {}, public: {} }),
|
|
@@ -30438,6 +31892,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30438
31892
|
},
|
|
30439
31893
|
plugins: [
|
|
30440
31894
|
...tailwindVitePlugin ? [tailwindVitePlugin] : [],
|
|
31895
|
+
...!useExternalMetadataImageRuntime && metadataImageRoutes.some((image) => image.sourceType === "module") ? [createMetadataImageWasmPlugin()] : [],
|
|
30441
31896
|
{
|
|
30442
31897
|
name: "farm-react-production-mode",
|
|
30443
31898
|
enforce: "pre",
|
|
@@ -30516,8 +31971,12 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
30516
31971
|
__name(buildSSRInMemory, "buildSSRInMemory");
|
|
30517
31972
|
function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlots, errorRoutes, metadataImageRoutes, middlewareRoutes, redirectRoutes, configuredRewriteRoutes, configuredHeaderRoutes, notFoundPath, config, configModulePath, hasServerRuntimeIntegrations, hasRuntimeIntegrationConfig, hasConfiguredRuntimePlugins, preset, i18nCatalogs) {
|
|
30518
31973
|
const hasPluginRuntime = hasRuntimeIntegrationConfig || hasConfiguredRuntimePlugins;
|
|
31974
|
+
const hasGeneratedMetadataImages = metadataImageRoutes.some(
|
|
31975
|
+
(image) => image.sourceType === "module"
|
|
31976
|
+
);
|
|
30519
31977
|
const hasMiddlewareRuntime = middlewareRoutes.length > 0 || hasFarmMiddlewareConfig(config.middleware);
|
|
30520
31978
|
const farmDocsBaseConfig = config.docs?.enabled ? { ...config.docs, config: void 0 } : void 0;
|
|
31979
|
+
const farmDocsFontAssets = config.docs?.enabled ? toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(config.root)) : [];
|
|
30521
31980
|
const apiImports = [];
|
|
30522
31981
|
const apiRegistrations = [];
|
|
30523
31982
|
apiRoutes.forEach((route, index) => {
|
|
@@ -30556,12 +32015,13 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
|
|
|
30556
32015
|
return;
|
|
30557
32016
|
}
|
|
30558
32017
|
pageImports.push(`import * as ${varName} from "${route.modulePath}";`);
|
|
30559
|
-
const
|
|
32018
|
+
const clientMetadata = getClientModuleMetadata(route.modulePath, config.root);
|
|
30560
32019
|
pageRegistrations.push(`
|
|
30561
32020
|
{
|
|
30562
32021
|
pattern: ${JSON.stringify(route.pattern)},
|
|
30563
32022
|
module: ${varName},
|
|
30564
|
-
shouldHydrate: ${JSON.stringify(shouldHydrate)},
|
|
32023
|
+
shouldHydrate: ${JSON.stringify(clientMetadata.shouldHydrate)},
|
|
32024
|
+
islandStrategy: ${JSON.stringify(clientMetadata.islandStrategy)},
|
|
30565
32025
|
${route.source !== void 0 ? `markdownSource: {
|
|
30566
32026
|
source: ${JSON.stringify(route.source)},
|
|
30567
32027
|
filePath: ${JSON.stringify(route.markdownSourcePath)},
|
|
@@ -30659,16 +32119,21 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
|
|
|
30659
32119
|
isFarmRedirectError,
|
|
30660
32120
|
localizeFarmHref,
|
|
30661
32121
|
localizeFarmPathname,
|
|
32122
|
+
manageFarmDocumentPreloads,
|
|
32123
|
+
manageFarmLinkHeaderPreloads,
|
|
30662
32124
|
mergeMetadata,
|
|
30663
32125
|
normalizeRevalidatePath,
|
|
32126
|
+
reportFarmPreloadWarnings,
|
|
30664
32127
|
renderMetadataHead,
|
|
30665
32128
|
resolveFarmRouteContext,
|
|
30666
32129
|
stripFarmLocaleFromPathname,
|
|
30667
32130
|
withFarmRouteContext,
|
|
30668
32131
|
} from "@farm.js/core/internal/production-runtime";`;
|
|
32132
|
+
const metadataImageRuntimeImport = hasGeneratedMetadataImages ? `import { createFarmMetadataImageResponse } from "@farm.js/core/internal/metadata-image-runtime";` : "";
|
|
30669
32133
|
const pluginRuntimeImport = hasPluginRuntime ? `import { PluginManager } from "@farm.js/core/plugin";` : "";
|
|
30670
32134
|
const i18nServerImport = config.i18n.enabled ? `import { _runWithFarmI18nRequest, _setDefaultFarmI18nRuntime, createFarmI18nRuntime, getFarmI18nClientSnapshot } from "@farm.js/core/i18n/server";` : "";
|
|
30671
32135
|
const docsHandlerImport = config.docs?.enabled ? `import { createFarmDocsAPIHandler, createFarmDocsHandler, isFarmDocsAPIRequest } from "@farm.js/core/docs";` : "";
|
|
32136
|
+
const docsFontImport = config.docs?.enabled ? `import { resolveFarmLayoutFonts } from "@farm.js/core/font";` : "";
|
|
30672
32137
|
const docsRuntimeImport = config.docs?.enabled ? `import { existsSync as farmDocsExistsSync } from "node:fs";
|
|
30673
32138
|
import { dirname as farmDocsDirname, join as farmDocsJoin } from "node:path";
|
|
30674
32139
|
import { fileURLToPath as farmDocsFileURLToPath } from "node:url";` : "";
|
|
@@ -30756,9 +32221,11 @@ ${middlewareImports.join("\n")}
|
|
|
30756
32221
|
${notFoundImport}
|
|
30757
32222
|
${apiRouteHelpersImport}
|
|
30758
32223
|
${productionRuntimeImport}
|
|
32224
|
+
${metadataImageRuntimeImport}
|
|
30759
32225
|
${pluginRuntimeImport}
|
|
30760
32226
|
${i18nServerImport}
|
|
30761
32227
|
${docsHandlerImport}
|
|
32228
|
+
${docsFontImport}
|
|
30762
32229
|
${docsRuntimeImport}
|
|
30763
32230
|
${markdownHandlerImport}
|
|
30764
32231
|
${appMarkdownImport}
|
|
@@ -30770,6 +32237,8 @@ import { farmFontPreloadHeader } from "virtual:farm-font-runtime";
|
|
|
30770
32237
|
import * as React from "react";
|
|
30771
32238
|
import * as ReactDOMServer from "react-dom/server";
|
|
30772
32239
|
|
|
32240
|
+
const farmPreloadConfig = ${JSON.stringify(config.performance.preload)};
|
|
32241
|
+
|
|
30773
32242
|
// Custom 404 page component (if provided)
|
|
30774
32243
|
const hasCustomNotFound = ${notFoundPath ? "true" : "false"};
|
|
30775
32244
|
const CustomNotFoundComponent = ${notFoundPath ? "CustomNotFound.default || CustomNotFound" : "null"};
|
|
@@ -30861,7 +32330,17 @@ globalThis.__FARM_DOCS_RUNTIME_CONFIG__ = {
|
|
|
30861
32330
|
srcDir: ${JSON.stringify(config.srcDir)},
|
|
30862
32331
|
docs: farmDocsResolvedConfig,
|
|
30863
32332
|
};
|
|
30864
|
-
const farmDocsHandler = ${config.docs?.enabled ? `createFarmDocsHandler(farmDocsResolvedConfig, {
|
|
32333
|
+
const farmDocsHandler = ${config.docs?.enabled ? `createFarmDocsHandler(farmDocsResolvedConfig, {
|
|
32334
|
+
root: farmDocsRuntimeRoot,
|
|
32335
|
+
srcDir: ${JSON.stringify(config.srcDir)},
|
|
32336
|
+
clientEntry: "/farm-client.js",
|
|
32337
|
+
fontAssets: ${JSON.stringify(farmDocsFontAssets)},
|
|
32338
|
+
resolveLayoutFonts: (pathname) =>
|
|
32339
|
+
resolveFarmLayoutFonts(
|
|
32340
|
+
getApplicableLayouts(getFarmRoutePathname(pathname)).map((layout) => layout.module),
|
|
32341
|
+
),
|
|
32342
|
+
fontStylesheetHref: "/farm-fonts.css",
|
|
32343
|
+
})` : "null"};
|
|
30865
32344
|
const farmDocsAPIHandler = ${config.docs?.enabled ? `createFarmDocsAPIHandler({ rootDir: farmDocsRuntimeRoot, srcDir: ${JSON.stringify(config.srcDir)}, docs: farmDocsResolvedConfig })` : "null"};
|
|
30866
32345
|
|
|
30867
32346
|
// API routes bundled at build time
|
|
@@ -31522,30 +33001,10 @@ async function handleMetadataImageRequest(request, routePathname) {
|
|
|
31522
33001
|
? await imageModule.default(props)
|
|
31523
33002
|
: imageModule.default;
|
|
31524
33003
|
|
|
31525
|
-
|
|
31526
|
-
|
|
31527
|
-
|
|
31528
|
-
|
|
31529
|
-
}
|
|
31530
|
-
|
|
31531
|
-
let body;
|
|
31532
|
-
if (typeof value === "string" || value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
31533
|
-
body = value;
|
|
31534
|
-
} else {
|
|
31535
|
-
if (!React.isValidElement(value)) {
|
|
31536
|
-
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
31537
|
-
}
|
|
31538
|
-
body = ReactDOMServer.renderToStaticMarkup(value);
|
|
31539
|
-
}
|
|
31540
|
-
|
|
31541
|
-
return new Response(method === "HEAD" ? null : body, {
|
|
31542
|
-
status: 200,
|
|
31543
|
-
headers: {
|
|
31544
|
-
"Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
|
|
31545
|
-
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
31546
|
-
"X-Content-Type-Options": "nosniff",
|
|
31547
|
-
},
|
|
31548
|
-
});
|
|
33004
|
+
${hasGeneratedMetadataImages ? `return createFarmMetadataImageResponse(value, imageModule, {
|
|
33005
|
+
method,
|
|
33006
|
+
ifNoneMatch: request.headers.get("if-none-match"),
|
|
33007
|
+
});` : 'throw new Error("Generated metadata image runtime is unavailable");'}
|
|
31549
33008
|
} catch (error) {
|
|
31550
33009
|
console.error("Metadata image render failed:", error);
|
|
31551
33010
|
return new Response("Internal Server Error", {
|
|
@@ -32081,7 +33540,16 @@ async function handleFarmRequestInContext(
|
|
|
32081
33540
|
if (farmDocsHandler) {
|
|
32082
33541
|
const docsResponse = await farmDocsHandler(request.clone());
|
|
32083
33542
|
if (docsResponse) {
|
|
32084
|
-
|
|
33543
|
+
if (!docsResponse.headers.get("content-type")?.toLowerCase().includes("text/html")) {
|
|
33544
|
+
return docsResponse;
|
|
33545
|
+
}
|
|
33546
|
+
const docsHeaders = new Headers(docsResponse.headers);
|
|
33547
|
+
docsHeaders.set("x-farm-preload-buffered", "1");
|
|
33548
|
+
return new Response(docsResponse.body, {
|
|
33549
|
+
status: docsResponse.status,
|
|
33550
|
+
statusText: docsResponse.statusText,
|
|
33551
|
+
headers: docsHeaders,
|
|
33552
|
+
});
|
|
32085
33553
|
}
|
|
32086
33554
|
}
|
|
32087
33555
|
` : ""}
|
|
@@ -32209,6 +33677,7 @@ async function handleFarmRequestInContext(
|
|
|
32209
33677
|
status: 200,
|
|
32210
33678
|
headers: {
|
|
32211
33679
|
"Content-Type": "text/html; charset=utf-8",
|
|
33680
|
+
"x-farm-preload-buffered": "1",
|
|
32212
33681
|
...(farmFontPreloadHeader ? { "Link": farmFontPreloadHeader } : {}),
|
|
32213
33682
|
...getPPRHeaders("hit", pprConfig),
|
|
32214
33683
|
},
|
|
@@ -32436,10 +33905,15 @@ async function handleFarmRequestInContext(
|
|
|
32436
33905
|
pageElement = React.createElement(PageComponent, pageProps);
|
|
32437
33906
|
}
|
|
32438
33907
|
|
|
32439
|
-
if (route.shouldHydrate
|
|
33908
|
+
if (route.shouldHydrate) {
|
|
32440
33909
|
pageElement = React.createElement(
|
|
32441
33910
|
"div",
|
|
32442
|
-
{
|
|
33911
|
+
{
|
|
33912
|
+
id: "__farm_page__",
|
|
33913
|
+
"data-farm-client": "true",
|
|
33914
|
+
"data-farm-island": "page",
|
|
33915
|
+
"data-farm-island-strategy": route.islandStrategy || "load",
|
|
33916
|
+
},
|
|
32443
33917
|
pageElement,
|
|
32444
33918
|
);
|
|
32445
33919
|
}
|
|
@@ -32590,7 +34064,7 @@ async function handleFarmRequestInContext(
|
|
|
32590
34064
|
);
|
|
32591
34065
|
return applyProductionMiddlewareHeaders(new Response(streamedDocument, {
|
|
32592
34066
|
status: pageStatus,
|
|
32593
|
-
headers: responseHeaders,
|
|
34067
|
+
headers: { ...responseHeaders, "x-farm-preload-streaming": "1" },
|
|
32594
34068
|
}), middlewareHeaders);
|
|
32595
34069
|
}
|
|
32596
34070
|
|
|
@@ -32691,7 +34165,7 @@ async function handleFarmRequestInContext(
|
|
|
32691
34165
|
fullHtml,
|
|
32692
34166
|
{
|
|
32693
34167
|
status: pageStatus,
|
|
32694
|
-
headers: responseHeaders
|
|
34168
|
+
headers: { ...responseHeaders, "x-farm-preload-buffered": "1" }
|
|
32695
34169
|
}
|
|
32696
34170
|
), middlewareHeaders);
|
|
32697
34171
|
}
|
|
@@ -32795,6 +34269,7 @@ async function handleFarmRequestInContext(
|
|
|
32795
34269
|
headers: {
|
|
32796
34270
|
"Content-Type": "text/html; charset=utf-8",
|
|
32797
34271
|
"Cache-Control": "private, no-store",
|
|
34272
|
+
"x-farm-preload-buffered": "1",
|
|
32798
34273
|
},
|
|
32799
34274
|
}), middlewareHeaders);
|
|
32800
34275
|
} catch (boundaryError) {
|
|
@@ -32817,6 +34292,7 @@ async function handleFarmRequestInContext(
|
|
|
32817
34292
|
headers: {
|
|
32818
34293
|
"Content-Type": "text/html; charset=utf-8",
|
|
32819
34294
|
"Cache-Control": "private, no-store",
|
|
34295
|
+
"x-farm-preload-buffered": "1",
|
|
32820
34296
|
},
|
|
32821
34297
|
}
|
|
32822
34298
|
), middlewareHeaders);
|
|
@@ -32963,13 +34439,19 @@ async function handleFarmRequestInContext(
|
|
|
32963
34439
|
|
|
32964
34440
|
return applyProductionMiddlewareHeaders(new Response(fullHtml, {
|
|
32965
34441
|
status: 404,
|
|
32966
|
-
headers: {
|
|
34442
|
+
headers: {
|
|
34443
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
34444
|
+
"x-farm-preload-buffered": "1",
|
|
34445
|
+
}
|
|
32967
34446
|
}), middlewareHeaders);
|
|
32968
34447
|
} catch (error) {
|
|
32969
34448
|
console.error("404 render error:", error);
|
|
32970
34449
|
return applyProductionMiddlewareHeaders(new Response(
|
|
32971
34450
|
\`<!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>\`,
|
|
32972
|
-
{
|
|
34451
|
+
{
|
|
34452
|
+
status: 404,
|
|
34453
|
+
headers: { "Content-Type": "text/html", "x-farm-preload-buffered": "1" },
|
|
34454
|
+
}
|
|
32973
34455
|
), middlewareHeaders);
|
|
32974
34456
|
}
|
|
32975
34457
|
${hasMiddlewareRuntime ? `
|
|
@@ -33011,7 +34493,10 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33011
34493
|
await farmPluginRuntime.runHookParallel("beforeRender", renderPayload);
|
|
33012
34494
|
|
|
33013
34495
|
const response = await handleFarmRequest(request);
|
|
33014
|
-
if (
|
|
34496
|
+
if (
|
|
34497
|
+
!hasFarmPluginHTMLTransforms ||
|
|
34498
|
+
!response.headers.get("content-type")?.toLowerCase().includes("text/html")
|
|
34499
|
+
) {
|
|
33015
34500
|
return response;
|
|
33016
34501
|
}
|
|
33017
34502
|
|
|
@@ -33021,6 +34506,8 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33021
34506
|
|
|
33022
34507
|
const headers = new Headers(response.headers);
|
|
33023
34508
|
headers.delete("content-length");
|
|
34509
|
+
headers.delete("x-farm-preload-streaming");
|
|
34510
|
+
headers.set("x-farm-preload-buffered", "1");
|
|
33024
34511
|
return new Response(html, {
|
|
33025
34512
|
status: response.status,
|
|
33026
34513
|
statusText: response.statusText,
|
|
@@ -33028,6 +34515,49 @@ async function handleFarmPluginRequest(request, runtimeOptions) {
|
|
|
33028
34515
|
});
|
|
33029
34516
|
}
|
|
33030
34517
|
|
|
34518
|
+
async function applyFarmPreloadBudget(response, pathname) {
|
|
34519
|
+
const headers = new Headers(response.headers);
|
|
34520
|
+
const linkHeader = headers.get("Link") || "";
|
|
34521
|
+
const isHtml = headers.get("Content-Type")?.toLowerCase().includes("text/html");
|
|
34522
|
+
const isStreaming = headers.get("x-farm-preload-streaming") === "1";
|
|
34523
|
+
const isBuffered = headers.get("x-farm-preload-buffered") === "1";
|
|
34524
|
+
headers.delete("x-farm-preload-streaming");
|
|
34525
|
+
headers.delete("x-farm-preload-buffered");
|
|
34526
|
+
|
|
34527
|
+
if (!isHtml) {
|
|
34528
|
+
if (!isStreaming && !isBuffered) return response;
|
|
34529
|
+
return new Response(response.body, {
|
|
34530
|
+
status: response.status,
|
|
34531
|
+
statusText: response.statusText,
|
|
34532
|
+
headers,
|
|
34533
|
+
});
|
|
34534
|
+
}
|
|
34535
|
+
|
|
34536
|
+
if (isStreaming || !isBuffered || response.body === null) {
|
|
34537
|
+
const managed = manageFarmLinkHeaderPreloads(linkHeader, farmPreloadConfig);
|
|
34538
|
+
if (managed.value) headers.set("Link", managed.value);
|
|
34539
|
+
else headers.delete("Link");
|
|
34540
|
+
reportFarmPreloadWarnings(managed.warnings, "route " + pathname);
|
|
34541
|
+
return new Response(response.body, {
|
|
34542
|
+
status: response.status,
|
|
34543
|
+
statusText: response.statusText,
|
|
34544
|
+
headers,
|
|
34545
|
+
});
|
|
34546
|
+
}
|
|
34547
|
+
|
|
34548
|
+
const html = await response.text();
|
|
34549
|
+
const managed = manageFarmDocumentPreloads(html, linkHeader, farmPreloadConfig);
|
|
34550
|
+
if (managed.linkHeader) headers.set("Link", managed.linkHeader);
|
|
34551
|
+
else headers.delete("Link");
|
|
34552
|
+
if (managed.html !== html) headers.delete("Content-Length");
|
|
34553
|
+
reportFarmPreloadWarnings(managed.warnings, "route " + pathname);
|
|
34554
|
+
return new Response(managed.html, {
|
|
34555
|
+
status: response.status,
|
|
34556
|
+
statusText: response.statusText,
|
|
34557
|
+
headers,
|
|
34558
|
+
});
|
|
34559
|
+
}
|
|
34560
|
+
|
|
33031
34561
|
// Export as Web Standard fetch API
|
|
33032
34562
|
export async function fetch(request, context) {
|
|
33033
34563
|
const runtimeOptions = farmPluginRuntime ? getFarmPluginRequestOptions(request) : null;
|
|
@@ -33050,7 +34580,8 @@ export async function fetch(request, context) {
|
|
|
33050
34580
|
const response = await _runWithCurrentRequest(request, () =>
|
|
33051
34581
|
_runWithAfterRequest(request, runRequest, context),
|
|
33052
34582
|
);
|
|
33053
|
-
|
|
34583
|
+
const pathname = new URL(request.url).pathname;
|
|
34584
|
+
return applyFarmPreloadBudget(applyConfiguredResponseHeaders(response, pathname), pathname);
|
|
33054
34585
|
}
|
|
33055
34586
|
export default { fetch };
|
|
33056
34587
|
`.trim();
|
|
@@ -33206,8 +34737,19 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
33206
34737
|
const outputDir = resolveDeployOutputPath(root, config.deploy.outputDir);
|
|
33207
34738
|
const ssrOutputDir = import_path12.default.join(root, distDir, "ssr");
|
|
33208
34739
|
const imageRuntime = resolveImageRuntime(config, preset);
|
|
34740
|
+
const hasGeneratedMetadataImages = Array.from(routeManager.getMetadataImages().values()).some(
|
|
34741
|
+
(image) => image.sourceType === "module"
|
|
34742
|
+
);
|
|
34743
|
+
const useExternalMetadataImageRuntime = shouldUseExternalMetadataImageRuntime(
|
|
34744
|
+
preset,
|
|
34745
|
+
hasGeneratedMetadataImages
|
|
34746
|
+
);
|
|
34747
|
+
const nitroRollupExternal = /* @__PURE__ */ __name((id) => useExternalMetadataImageRuntime && id === "@vercel/og" || isNitroRollupExternal(id), "nitroRollupExternal");
|
|
33209
34748
|
const ssrExternalPackages = collectSSRExternalPackages(ssrBundle);
|
|
33210
|
-
const copiedRuntimePackages = new Set(
|
|
34749
|
+
const copiedRuntimePackages = /* @__PURE__ */ new Set([
|
|
34750
|
+
...imageRuntime === "node" ? ["sharp"] : [],
|
|
34751
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : []
|
|
34752
|
+
]);
|
|
33211
34753
|
const isPrebuiltSSRCandidate = preset === "node-server" && [...ssrExternalPackages].every((packageName) => copiedRuntimePackages.has(packageName));
|
|
33212
34754
|
logger.info(`\u{1F4E6} Nitro output directory: ${outputDir}`);
|
|
33213
34755
|
logger.info(`\u{1F4E6} SSR entry file: ${ssrEntryFile}`);
|
|
@@ -33423,11 +34965,13 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33423
34965
|
".prisma/client",
|
|
33424
34966
|
".prisma/client/default",
|
|
33425
34967
|
"better-sqlite3",
|
|
33426
|
-
"sharp"
|
|
34968
|
+
"sharp",
|
|
34969
|
+
...useExternalMetadataImageRuntime ? ["@vercel/og"] : []
|
|
33427
34970
|
]
|
|
33428
34971
|
},
|
|
33429
34972
|
rollupConfig: {
|
|
33430
|
-
external:
|
|
34973
|
+
external: nitroRollupExternal,
|
|
34974
|
+
plugins: hasGeneratedMetadataImages && !useExternalMetadataImageRuntime ? [createMetadataImageWasmPlugin()] : []
|
|
33431
34975
|
},
|
|
33432
34976
|
// Keep the public Nitro boolean intact for build hooks. It is translated to
|
|
33433
34977
|
// Nitro's existing esbuild pass after hooks run, avoiding a second Terser pass.
|
|
@@ -33455,7 +34999,7 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33455
34999
|
snapshotSSRRebundleOptions(nitroConfig)
|
|
33456
35000
|
);
|
|
33457
35001
|
const requestedBuilder = nitroConfig.builder ?? process.env.NITRO_BUILDER;
|
|
33458
|
-
const canReusePrebuiltSSR = isPrebuiltSSRCandidate && nitroConfig.preset === "node-server" && (requestedBuilder === void 0 || requestedBuilder === "rollup" || requestedBuilder === "rolldown") && nitroConfig.sourceMap === false && !hasUnsupportedEsbuildOverrides && !hasLateBuildMutationConfig && !hasUnsupportedSSRRebundleOverrides && nitroConfig.rollupConfig?.external ===
|
|
35002
|
+
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(
|
|
33459
35003
|
nitroConfig.handlers?.some(
|
|
33460
35004
|
(handler) => import_path12.default.resolve(handler?.handler || "") === nitroEntryPath
|
|
33461
35005
|
)
|
|
@@ -33543,7 +35087,8 @@ export default async function farmNitroEventHandler(event) {
|
|
|
33543
35087
|
effectiveMinify,
|
|
33544
35088
|
fs8
|
|
33545
35089
|
) : Promise.resolve(),
|
|
33546
|
-
imageRuntime === "node" ? copySharpRuntime(config, root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve()
|
|
35090
|
+
imageRuntime === "node" ? copySharpRuntime(config, root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve(),
|
|
35091
|
+
useExternalMetadataImageRuntime ? copyMetadataImageRuntime(root, import_path12.default.join(outputDir, "server"), fs8) : Promise.resolve()
|
|
33547
35092
|
]);
|
|
33548
35093
|
const failedCopy = copyResults.find(
|
|
33549
35094
|
(result) => result.status === "rejected"
|
|
@@ -33655,6 +35200,9 @@ async function postProcessVercelOutput(root, outputDir, fs8, config, farmWorkflo
|
|
|
33655
35200
|
fs8
|
|
33656
35201
|
);
|
|
33657
35202
|
vercelConfig.routes = [
|
|
35203
|
+
// Apply the header before the filesystem handler. `continue` lets Vercel
|
|
35204
|
+
// serve the matching file while preserving the immutable cache policy.
|
|
35205
|
+
createFarmVercelImmutableAssetRoute(config.basePath),
|
|
33658
35206
|
// Serve static files first
|
|
33659
35207
|
{
|
|
33660
35208
|
handle: "filesystem"
|
|
@@ -33772,6 +35320,42 @@ async function copySharpRuntime(config, root, nitroFuncDir, fs8) {
|
|
|
33772
35320
|
logger.info(`\u{1F5BC}\uFE0F Bundled Sharp image runtime (${copiedPackages.size} packages)`);
|
|
33773
35321
|
}
|
|
33774
35322
|
__name(copySharpRuntime, "copySharpRuntime");
|
|
35323
|
+
async function copyMetadataImageRuntime(root, nitroFuncDir, fs8) {
|
|
35324
|
+
const projectRequire = (0, import_module2.createRequire)(import_path12.default.join(root, "package.json"));
|
|
35325
|
+
let runtimeRequire = projectRequire;
|
|
35326
|
+
let packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
|
|
35327
|
+
if (!packageJsonPath) {
|
|
35328
|
+
try {
|
|
35329
|
+
runtimeRequire = (0, import_module2.createRequire)(projectRequire.resolve("@farm.js/core"));
|
|
35330
|
+
packageJsonPath = resolvePackageJson(runtimeRequire, "@vercel/og");
|
|
35331
|
+
} catch {
|
|
35332
|
+
}
|
|
35333
|
+
}
|
|
35334
|
+
if (!packageJsonPath) {
|
|
35335
|
+
throw new Error(
|
|
35336
|
+
"Generated metadata images require @vercel/og. Reinstall @farm.js/core with production dependencies."
|
|
35337
|
+
);
|
|
35338
|
+
}
|
|
35339
|
+
const packageJson = JSON.parse(await fs8.readFile(packageJsonPath, "utf8"));
|
|
35340
|
+
const packageDir = import_path12.default.dirname(packageJsonPath);
|
|
35341
|
+
const targetDir = import_path12.default.join(nitroFuncDir, "node_modules", "@vercel", "og");
|
|
35342
|
+
await fs8.mkdir(import_path12.default.dirname(targetDir), { recursive: true });
|
|
35343
|
+
await fs8.cp(packageDir, targetDir, {
|
|
35344
|
+
recursive: true,
|
|
35345
|
+
force: true,
|
|
35346
|
+
dereference: true,
|
|
35347
|
+
mode: import_fs5.constants.COPYFILE_FICLONE
|
|
35348
|
+
});
|
|
35349
|
+
const functionPackagePath = import_path12.default.join(nitroFuncDir, "package.json");
|
|
35350
|
+
const functionPackage = JSON.parse(await fs8.readFile(functionPackagePath, "utf8"));
|
|
35351
|
+
functionPackage.dependencies = {
|
|
35352
|
+
...functionPackage.dependencies,
|
|
35353
|
+
"@vercel/og": String(packageJson.version || "0.11.1")
|
|
35354
|
+
};
|
|
35355
|
+
await fs8.writeFile(functionPackagePath, JSON.stringify(functionPackage, null, 2));
|
|
35356
|
+
logger.info("\u{1F5BC}\uFE0F Bundled generated metadata image runtime");
|
|
35357
|
+
}
|
|
35358
|
+
__name(copyMetadataImageRuntime, "copyMetadataImageRuntime");
|
|
33775
35359
|
function resolvePackageJson(parentRequire, packageName) {
|
|
33776
35360
|
for (const request of [`${packageName}/package.json`, `${packageName}/package`]) {
|
|
33777
35361
|
try {
|
|
@@ -33831,54 +35415,7 @@ init_type_artifacts();
|
|
|
33831
35415
|
init_plugin();
|
|
33832
35416
|
init_environment_vite();
|
|
33833
35417
|
init_font_vite();
|
|
33834
|
-
|
|
33835
|
-
// src/server/vite-config.ts
|
|
33836
|
-
function mergeNoExternal(farmValue, userValue) {
|
|
33837
|
-
if (farmValue === true || userValue === true) return true;
|
|
33838
|
-
const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
|
|
33839
|
-
return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
|
|
33840
|
-
}
|
|
33841
|
-
__name(mergeNoExternal, "mergeNoExternal");
|
|
33842
|
-
function mergeFarmViteConfig(farmConfig, userConfig = {}) {
|
|
33843
|
-
return {
|
|
33844
|
-
...farmConfig,
|
|
33845
|
-
...userConfig,
|
|
33846
|
-
plugins: [...farmConfig.plugins || [], ...userConfig.plugins || []],
|
|
33847
|
-
server: {
|
|
33848
|
-
...farmConfig.server,
|
|
33849
|
-
...userConfig.server
|
|
33850
|
-
},
|
|
33851
|
-
resolve: {
|
|
33852
|
-
...farmConfig.resolve,
|
|
33853
|
-
...userConfig.resolve,
|
|
33854
|
-
dedupe: Array.from(
|
|
33855
|
-
/* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
|
|
33856
|
-
)
|
|
33857
|
-
},
|
|
33858
|
-
optimizeDeps: {
|
|
33859
|
-
...farmConfig.optimizeDeps,
|
|
33860
|
-
...userConfig.optimizeDeps,
|
|
33861
|
-
include: Array.from(
|
|
33862
|
-
/* @__PURE__ */ new Set([
|
|
33863
|
-
...farmConfig.optimizeDeps?.include || [],
|
|
33864
|
-
...userConfig.optimizeDeps?.include || []
|
|
33865
|
-
])
|
|
33866
|
-
),
|
|
33867
|
-
exclude: Array.from(
|
|
33868
|
-
/* @__PURE__ */ new Set([
|
|
33869
|
-
...farmConfig.optimizeDeps?.exclude || [],
|
|
33870
|
-
...userConfig.optimizeDeps?.exclude || []
|
|
33871
|
-
])
|
|
33872
|
-
)
|
|
33873
|
-
},
|
|
33874
|
-
ssr: {
|
|
33875
|
-
...farmConfig.ssr,
|
|
33876
|
-
...userConfig.ssr,
|
|
33877
|
-
noExternal: mergeNoExternal(farmConfig.ssr?.noExternal, userConfig.ssr?.noExternal)
|
|
33878
|
-
}
|
|
33879
|
-
};
|
|
33880
|
-
}
|
|
33881
|
-
__name(mergeFarmViteConfig, "mergeFarmViteConfig");
|
|
35418
|
+
init_vite_config();
|
|
33882
35419
|
|
|
33883
35420
|
// src/build/production-node-env.ts
|
|
33884
35421
|
var productionNodeEnvStateKey = /* @__PURE__ */ Symbol.for("@farm.js/core/production-node-env-state");
|