@farm.js/core 0.1.28 → 0.1.30
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/agent-runtime.d.mts +2 -2
- package/dist/agent-runtime.d.ts +2 -2
- package/dist/api/route-manager.d.mts +1 -1
- package/dist/api/route-manager.d.ts +1 -1
- package/dist/api/runtime.d.mts +2 -2
- package/dist/api/runtime.d.ts +2 -2
- package/dist/api.cjs +2 -2
- package/dist/api.d.mts +18 -4
- package/dist/api.d.ts +18 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-DSSq6wiN.d.mts → app-DAuUTIZf.d.mts} +3 -3
- package/dist/app-markdown.cjs +5 -4
- package/dist/app-markdown.d.mts +3 -3
- package/dist/app-markdown.d.ts +3 -3
- package/dist/app-markdown.mjs +4 -3
- package/dist/{app-M8nVWvNU.d.ts → app-sUJ3jnTZ.d.ts} +3 -3
- package/dist/{chunk-N6UROPT7.mjs → chunk-2FQHH5SC.mjs} +12 -13
- package/dist/{chunk-2CNBR3EB.mjs → chunk-2UABTL3Y.mjs} +2 -2
- package/dist/{chunk-JUFRXDTK.cjs → chunk-3FCFQP5V.cjs} +17 -5
- package/dist/{chunk-XSPGWQWA.cjs → chunk-6CNX6Q3K.cjs} +96 -24
- package/dist/{chunk-NVBS5WSZ.mjs → chunk-6G3ZZ2IE.mjs} +1 -1
- package/dist/{chunk-QBPXNZGV.cjs → chunk-6MVFL3R5.cjs} +25 -6
- package/dist/{chunk-PZPDGOU5.mjs → chunk-7CXKSRKL.mjs} +11 -7
- package/dist/{chunk-K3YEZLSY.mjs → chunk-ATXI6LGT.mjs} +96 -24
- package/dist/{chunk-2DLN6HG4.mjs → chunk-BZ3CHOFX.mjs} +1 -1
- package/dist/{chunk-EWZ3XHKQ.cjs → chunk-BZAGKCKB.cjs} +2 -2
- package/dist/{chunk-FB3H4INL.mjs → chunk-D234YWNA.mjs} +1 -1
- package/dist/{chunk-KXGDXYUC.mjs → chunk-DGXN3L4D.mjs} +17 -5
- package/dist/chunk-FJ3M4CUX.cjs +46 -0
- package/dist/chunk-FXEF4PPL.mjs +47 -0
- package/dist/{chunk-ID6OVSLH.cjs → chunk-GIWC4CFJ.cjs} +175 -171
- package/dist/{chunk-F52CDFJM.cjs → chunk-HPQC2LHF.cjs} +435 -274
- package/dist/{chunk-FVCSLZWT.mjs → chunk-IVLUJUT4.mjs} +315 -154
- package/dist/{chunk-KOQ555NR.cjs → chunk-JFHKNFEO.cjs} +24 -20
- package/dist/{chunk-UX2DD2VK.mjs → chunk-K6V52QMI.mjs} +1 -1
- package/dist/{chunk-BYODCJD6.cjs → chunk-K7CELQLK.cjs} +12 -13
- package/dist/{chunk-A672WZEG.cjs → chunk-NPPL5YDT.cjs} +2 -2
- package/dist/{chunk-TII23GJC.cjs → chunk-NXG66MR7.cjs} +3 -3
- package/dist/{chunk-R6AIILII.cjs → chunk-OZVEHHMA.cjs} +15 -14
- package/dist/{chunk-T7HQ3I4C.mjs → chunk-PQD2AI3B.mjs} +1 -1
- package/dist/{chunk-VQXDC5UV.cjs → chunk-Q5JFU33Q.cjs} +4 -4
- package/dist/{chunk-FZC7EEPM.mjs → chunk-RSOJ7DRT.mjs} +26 -7
- package/dist/{chunk-ZRIE4KMG.mjs → chunk-S4K74WI4.mjs} +17 -13
- package/dist/{chunk-Y7GW7J46.cjs → chunk-X5TXZFMN.cjs} +1 -1
- package/dist/chunk-XD32KALF.cjs +47 -0
- package/dist/{chunk-RDV44SED.mjs → chunk-XJJVLDM6.mjs} +15 -14
- package/dist/{chunk-55ZY4ZA7.cjs → chunk-XLTV4VOG.cjs} +21 -16
- package/dist/{chunk-REGFZJEJ.mjs → chunk-YMUE7L3D.mjs} +18 -13
- package/dist/chunk-Z3HATSKO.mjs +46 -0
- package/dist/{chunk-MH24QDVJ.cjs → chunk-ZDILFMWN.cjs} +13 -13
- package/dist/{client-plugins-CgYNY7jF.d.mts → client-plugins-BX2ptm4H.d.mts} +7 -2
- package/dist/{client-plugins-Fl9Og3yB.d.ts → client-plugins-BmxM5KW_.d.ts} +7 -2
- package/dist/client-plugins.d.mts +2 -2
- package/dist/client-plugins.d.ts +2 -2
- package/dist/client.d.mts +5 -5
- package/dist/client.d.ts +5 -5
- package/dist/config.d.mts +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/{devtools-5AREISIA.cjs → devtools-GGVPZHJX.cjs} +95 -20
- package/dist/{devtools-3E7ZANMZ.mjs → devtools-THVNPI2M.mjs} +79 -4
- package/dist/{devtools-client-4WAPJY5L.cjs → devtools-client-CXQ6PXI6.cjs} +1 -1
- package/dist/{devtools-client-LEUIHHAS.mjs → devtools-client-HJS2T34Y.mjs} +1 -1
- package/dist/docs.cjs +8 -7
- package/dist/docs.mjs +7 -6
- package/dist/index.cjs +18 -16
- package/dist/index.d.mts +24 -14
- package/dist/index.d.ts +24 -14
- package/dist/index.mjs +17 -15
- package/dist/integrations.d.mts +2 -2
- package/dist/integrations.d.ts +2 -2
- package/dist/internal/app-markdown-runtime.cjs +4 -3
- package/dist/internal/app-markdown-runtime.d.mts +3 -3
- package/dist/internal/app-markdown-runtime.d.ts +3 -3
- package/dist/internal/app-markdown-runtime.mjs +3 -2
- package/dist/internal/build-runtime.cjs +15 -13
- package/dist/internal/build-runtime.d.mts +4 -4
- package/dist/internal/build-runtime.d.ts +4 -4
- package/dist/internal/build-runtime.mjs +14 -12
- package/dist/internal/cli-runtime.cjs +7 -6
- package/dist/internal/cli-runtime.mjs +6 -5
- package/dist/internal/client-error-overlay.cjs +4 -4
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/compression-runtime.cjs +3 -2
- package/dist/internal/compression-runtime.d.mts +5 -3
- package/dist/internal/compression-runtime.d.ts +5 -3
- package/dist/internal/compression-runtime.mjs +2 -1
- package/dist/internal/config-runtime.cjs +6 -5
- package/dist/internal/config-runtime.d.mts +3 -3
- package/dist/internal/config-runtime.d.ts +3 -3
- package/dist/internal/config-runtime.mjs +5 -4
- package/dist/internal/product-telemetry-runtime.cjs +10 -6
- package/dist/internal/product-telemetry-runtime.mjs +9 -5
- package/dist/internal/production-runtime.cjs +19 -5
- package/dist/internal/production-runtime.d.mts +35 -8
- package/dist/internal/production-runtime.d.ts +35 -8
- package/dist/internal/production-runtime.mjs +18 -4
- package/dist/markdown.cjs +3 -2
- package/dist/markdown.d.mts +2 -2
- package/dist/markdown.d.ts +2 -2
- package/dist/markdown.mjs +2 -1
- package/dist/{metadata-B0X-qtcQ.d.mts → metadata-DsEaK7mQ.d.mts} +1 -1
- package/dist/{metadata-BdDKgd7K.d.ts → metadata-fwZ3gfG6.d.ts} +1 -1
- package/dist/middleware.cjs +3 -2
- package/dist/middleware.d.mts +3 -3
- package/dist/middleware.d.ts +3 -3
- package/dist/middleware.mjs +2 -1
- package/dist/navigation.d.mts +4 -4
- package/dist/navigation.d.ts +4 -4
- package/dist/plugin.cjs +10 -9
- package/dist/plugin.d.mts +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.mjs +9 -8
- package/dist/{production-runtime-BjgFgDIg.d.mts → production-runtime-Baqgwtvc.d.mts} +1 -1
- package/dist/{production-runtime-Dx_qMA3t.d.ts → production-runtime-DNkpFnmg.d.ts} +1 -1
- package/dist/{render-plan-_1TAWODt.d.mts → render-plan-DhwQnmmX.d.mts} +1 -1
- package/dist/{render-plan-B41EWmBb.d.ts → render-plan-rkIK9wd9.d.ts} +1 -1
- package/dist/renderer-client.d.mts +3 -3
- package/dist/renderer-client.d.ts +3 -3
- package/dist/{request-Dbf3G0zM.d.ts → request-BcY4RYPC.d.ts} +1 -1
- package/dist/{request-BhE4luLv.d.mts → request-CFy1BltJ.d.mts} +1 -1
- package/dist/request.d.mts +3 -3
- package/dist/request.d.ts +3 -3
- package/dist/{route-rendering-zzfx_GHf.d.mts → route-rendering-BkS0TBlB.d.mts} +1 -1
- package/dist/{route-rendering-Z7PveTZE.d.ts → route-rendering-D4XpMjam.d.ts} +1 -1
- package/dist/{router-BatNMsa1.d.mts → router-C4zPlC3V.d.mts} +1 -1
- package/dist/{router-DtNRhQl3.d.ts → router-Cq7BcZxg.d.ts} +1 -1
- package/dist/routes.d.mts +2 -2
- package/dist/routes.d.ts +2 -2
- package/dist/server-plugins.cjs +3 -2
- package/dist/server-plugins.d.mts +2 -2
- package/dist/server-plugins.d.ts +2 -2
- package/dist/server-plugins.mjs +2 -1
- package/dist/server.cjs +33 -28
- package/dist/server.d.mts +8 -8
- package/dist/server.d.ts +8 -8
- package/dist/server.mjs +16 -11
- package/dist/{spa-router-BE3bwU-J.d.ts → spa-router-B1HI3X9k.d.ts} +2 -2
- package/dist/{spa-router-DQOnHZVj.d.mts → spa-router-DzPZH-AO.d.mts} +2 -2
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{utils-DLK1ERNl.d.mts → utils-CEBktlBG.d.mts} +1 -1
- package/dist/{utils-u7ZBSWAK.d.ts → utils-DMD1Hzta.d.ts} +1 -1
- package/dist/version.cjs +2 -2
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +10 -9
- package/dist/vite.d.mts +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.mjs +9 -8
- package/package.json +1 -1
|
@@ -4,10 +4,13 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
withProductionNodeEnv
|
|
6
6
|
} from "./chunk-655RLQQL.mjs";
|
|
7
|
+
import {
|
|
8
|
+
generateNativeMCPPluginSource
|
|
9
|
+
} from "./chunk-FXEF4PPL.mjs";
|
|
7
10
|
import {
|
|
8
11
|
compileFarmDocsAdapterEdgeManifest,
|
|
9
12
|
createFarmDocsAPIHandler
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2UABTL3Y.mjs";
|
|
11
14
|
import {
|
|
12
15
|
FARM_DOCS_LAST_MODIFIED_MANIFEST,
|
|
13
16
|
createFarmDocsHandler,
|
|
@@ -17,7 +20,7 @@ import {
|
|
|
17
20
|
loadFarmDocsPage,
|
|
18
21
|
resolveFarmDocsContentDir,
|
|
19
22
|
toFarmDocsMarkdownPage
|
|
20
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-PQD2AI3B.mjs";
|
|
21
24
|
import {
|
|
22
25
|
generateFarmDocsSearchClientRuntime,
|
|
23
26
|
isFarmDocsSearchEnabled,
|
|
@@ -34,7 +37,7 @@ import {
|
|
|
34
37
|
getDeployTargetForPreset,
|
|
35
38
|
hasCustomFarmRouteContext,
|
|
36
39
|
resolveDeployOutputPath
|
|
37
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-7CXKSRKL.mjs";
|
|
38
41
|
import {
|
|
39
42
|
resolveFarmInstrumentationFile
|
|
40
43
|
} from "./chunk-ZZSRYEYU.mjs";
|
|
@@ -70,7 +73,7 @@ import {
|
|
|
70
73
|
resolveFarmImageProviderForRuntime,
|
|
71
74
|
resolveFarmIsolatedClientHydrationMode,
|
|
72
75
|
resolveFarmNotFoundComponentPath
|
|
73
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-S4K74WI4.mjs";
|
|
74
77
|
import {
|
|
75
78
|
findRequestBoundSourceBlockers,
|
|
76
79
|
generateFarmTypeArtifacts,
|
|
@@ -80,7 +83,7 @@ import {
|
|
|
80
83
|
import {
|
|
81
84
|
FARM_API_CATALOG_PATH,
|
|
82
85
|
resolveFarmApiCatalogInput
|
|
83
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-D234YWNA.mjs";
|
|
84
87
|
import {
|
|
85
88
|
isFarmPreviewDeploymentEnvironment
|
|
86
89
|
} from "./chunk-BOYNDCZL.mjs";
|
|
@@ -112,7 +115,7 @@ import {
|
|
|
112
115
|
} from "./chunk-DAATZTKJ.mjs";
|
|
113
116
|
import {
|
|
114
117
|
applyFarmCspHashesToHtml
|
|
115
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-YMUE7L3D.mjs";
|
|
116
119
|
import {
|
|
117
120
|
applyFarmCronVercelCrons,
|
|
118
121
|
createFarmCronCloudflareConfig,
|
|
@@ -124,14 +127,14 @@ import {
|
|
|
124
127
|
} from "./chunk-4OOBRCJX.mjs";
|
|
125
128
|
import {
|
|
126
129
|
isFarmMarkdownPageFile
|
|
127
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-BZ3CHOFX.mjs";
|
|
128
131
|
import {
|
|
129
132
|
resolveFarmMdxComponentsModulePath,
|
|
130
133
|
resolveMdxConfig
|
|
131
134
|
} from "./chunk-FA2W42OV.mjs";
|
|
132
135
|
import {
|
|
133
136
|
getFarmMarkdownAlternatePath
|
|
134
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-ATXI6LGT.mjs";
|
|
135
138
|
import {
|
|
136
139
|
applyFarmWorkflowVercelCrons,
|
|
137
140
|
prepareFarmWorkflowsForNitro
|
|
@@ -1255,6 +1258,19 @@ function isNitroRollupExternal(id) {
|
|
|
1255
1258
|
}
|
|
1256
1259
|
__name(isNitroRollupExternal, "isNitroRollupExternal");
|
|
1257
1260
|
var FARM_METADATA_IMAGE_WASM_PREFIX = "\0farm-metadata-image-wasm:";
|
|
1261
|
+
function createReactProductionModePlugin() {
|
|
1262
|
+
const nodeEnvExpression = ["process", "env", "NODE_ENV"].join(".");
|
|
1263
|
+
return {
|
|
1264
|
+
name: "farm-react-production-mode",
|
|
1265
|
+
transform(code, id) {
|
|
1266
|
+
const normalizedId = id.replace(/\\/g, "/");
|
|
1267
|
+
const isReactRuntime = normalizedId.includes("/node_modules/react/") || normalizedId.includes("/node_modules/react-dom/");
|
|
1268
|
+
if (!isReactRuntime || !code.includes(nodeEnvExpression)) return null;
|
|
1269
|
+
return { code: code.split(nodeEnvExpression).join('"production"'), map: null };
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
__name(createReactProductionModePlugin, "createReactProductionModePlugin");
|
|
1258
1274
|
function createMetadataImageWasmPlugin() {
|
|
1259
1275
|
return {
|
|
1260
1276
|
name: "farm-metadata-image-wasm",
|
|
@@ -1349,42 +1365,75 @@ async function minifyFarmServerChunk(code, fileName, options) {
|
|
|
1349
1365
|
}
|
|
1350
1366
|
__name(minifyFarmServerChunk, "minifyFarmServerChunk");
|
|
1351
1367
|
function restoreLiteralModuleSpecifiers(code, fileName, { parseSync, Visitor }) {
|
|
1352
|
-
|
|
1368
|
+
const hasImportTemplate = code.includes("import(`");
|
|
1369
|
+
const hasRequireTemplate = code.includes("require(`");
|
|
1370
|
+
if (!hasImportTemplate && !hasRequireTemplate) return code;
|
|
1353
1371
|
const parsed = parseSync(fileName, code, { lang: "js", sourceType: "module" });
|
|
1354
1372
|
if (parsed.errors.length > 0) {
|
|
1355
1373
|
throw new Error(`Failed to minify ${fileName}: ${parsed.errors[0].message}`);
|
|
1356
1374
|
}
|
|
1357
1375
|
const replacements = [];
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
const
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
ImportExpression(node) {
|
|
1371
|
-
restore(node.source);
|
|
1372
|
-
},
|
|
1373
|
-
CallExpression(node) {
|
|
1374
|
-
if (node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1) {
|
|
1375
|
-
restore(node.arguments[0]);
|
|
1376
|
+
let needsAst = hasRequireTemplate;
|
|
1377
|
+
if (!needsAst) {
|
|
1378
|
+
const seenStarts = /* @__PURE__ */ new Set();
|
|
1379
|
+
for (const { moduleRequest } of parsed.module.dynamicImports) {
|
|
1380
|
+
if (seenStarts.has(moduleRequest.start)) continue;
|
|
1381
|
+
seenStarts.add(moduleRequest.start);
|
|
1382
|
+
const source = code.slice(moduleRequest.start, moduleRequest.end);
|
|
1383
|
+
if (!source.startsWith("`")) continue;
|
|
1384
|
+
const value = source.slice(1, -1);
|
|
1385
|
+
if (source.length < 2 || !source.endsWith("`") || /[\\\r\n`]|\$\{/.test(value)) {
|
|
1386
|
+
needsAst = true;
|
|
1387
|
+
break;
|
|
1376
1388
|
}
|
|
1389
|
+
replacements.push({
|
|
1390
|
+
start: moduleRequest.start,
|
|
1391
|
+
end: moduleRequest.end,
|
|
1392
|
+
text: toAsciiStringLiteral(value)
|
|
1393
|
+
});
|
|
1377
1394
|
}
|
|
1378
|
-
}
|
|
1395
|
+
}
|
|
1396
|
+
if (needsAst) {
|
|
1397
|
+
replacements.length = 0;
|
|
1398
|
+
const restore = /* @__PURE__ */ __name((node) => {
|
|
1399
|
+
if (node?.type !== "TemplateLiteral") return;
|
|
1400
|
+
const template = node;
|
|
1401
|
+
const value = template.quasis[0]?.value.cooked;
|
|
1402
|
+
if (template.expressions.length > 0 || typeof value !== "string") return;
|
|
1403
|
+
replacements.push({
|
|
1404
|
+
start: template.start,
|
|
1405
|
+
end: template.end,
|
|
1406
|
+
text: toAsciiStringLiteral(value)
|
|
1407
|
+
});
|
|
1408
|
+
}, "restore");
|
|
1409
|
+
new Visitor({
|
|
1410
|
+
ImportExpression(node) {
|
|
1411
|
+
restore(node.source);
|
|
1412
|
+
},
|
|
1413
|
+
CallExpression(node) {
|
|
1414
|
+
if (node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1) {
|
|
1415
|
+
restore(node.arguments[0]);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
}).visit(parsed.program);
|
|
1419
|
+
}
|
|
1379
1420
|
let restored = "";
|
|
1380
1421
|
let offset = 0;
|
|
1381
1422
|
for (const { start, end, text } of replacements.sort((a, b) => a.start - b.start)) {
|
|
1423
|
+
if (start < offset) continue;
|
|
1382
1424
|
restored += code.slice(offset, start) + text;
|
|
1383
1425
|
offset = end;
|
|
1384
1426
|
}
|
|
1385
1427
|
return restored + code.slice(offset);
|
|
1386
1428
|
}
|
|
1387
1429
|
__name(restoreLiteralModuleSpecifiers, "restoreLiteralModuleSpecifiers");
|
|
1430
|
+
function toAsciiStringLiteral(value) {
|
|
1431
|
+
return JSON.stringify(value).replace(
|
|
1432
|
+
/[\u007f-]/g,
|
|
1433
|
+
(character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
__name(toAsciiStringLiteral, "toAsciiStringLiteral");
|
|
1388
1437
|
function createServerChunkMinifyPlugin(options) {
|
|
1389
1438
|
return {
|
|
1390
1439
|
name: "farm-server-chunk-minify",
|
|
@@ -4713,20 +4762,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
4713
4762
|
...rendererVitePlugins,
|
|
4714
4763
|
...config.vite.plugins || [],
|
|
4715
4764
|
...!useExternalMetadataImageRuntime && metadataImageRoutes.some((image) => image.sourceType === "module") ? [createMetadataImageWasmPlugin()] : [],
|
|
4716
|
-
{
|
|
4717
|
-
name: "farm-react-production-mode",
|
|
4718
|
-
enforce: "pre",
|
|
4719
|
-
transform(code, id) {
|
|
4720
|
-
const normalizedId = id.replace(/\\/g, "/");
|
|
4721
|
-
const isReactRuntime = normalizedId.includes("/node_modules/react/") || normalizedId.includes("/node_modules/react-dom/");
|
|
4722
|
-
const nodeEnvExpression = ["process", "env", "NODE_ENV"].join(".");
|
|
4723
|
-
if (!isReactRuntime || !code.includes(nodeEnvExpression)) return null;
|
|
4724
|
-
return {
|
|
4725
|
-
code: code.split(nodeEnvExpression).join('"production"'),
|
|
4726
|
-
map: null
|
|
4727
|
-
};
|
|
4728
|
-
}
|
|
4729
|
-
},
|
|
4765
|
+
{ ...createReactProductionModePlugin(), enforce: "pre" },
|
|
4730
4766
|
farmServerOnlyEntriesPlugin(),
|
|
4731
4767
|
farmPlugin({ ...config, isolatedClientBoundaryModules }, pluginManager),
|
|
4732
4768
|
farmEnvironmentFunctionsPlugin(),
|
|
@@ -4857,44 +4893,6 @@ function generateNativeAuthIntegrationSource(auth) {
|
|
|
4857
4893
|
};
|
|
4858
4894
|
}
|
|
4859
4895
|
__name(generateNativeAuthIntegrationSource, "generateNativeAuthIntegrationSource");
|
|
4860
|
-
function generateNativeMCPPluginSource(mcp) {
|
|
4861
|
-
if (mcp?.enabled !== true) {
|
|
4862
|
-
return { importSource: "", registerSource: "", pluginSource: "" };
|
|
4863
|
-
}
|
|
4864
|
-
return {
|
|
4865
|
-
importSource: `import { createFarmMCPPlugin as __farmCreateMCPPlugin } from "@farm.js/mcp/internal";`,
|
|
4866
|
-
registerSource: `function __farmMCPIsPlainObject(value) {
|
|
4867
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
4868
|
-
const prototype = Object.getPrototypeOf(value);
|
|
4869
|
-
return prototype === Object.prototype || prototype === null;
|
|
4870
|
-
}
|
|
4871
|
-
|
|
4872
|
-
function __farmMergeMCPConfig(base, override) {
|
|
4873
|
-
const output = { ...base };
|
|
4874
|
-
for (const [key, value] of Object.entries(override)) {
|
|
4875
|
-
if (value === undefined) continue;
|
|
4876
|
-
output[key] =
|
|
4877
|
-
__farmMCPIsPlainObject(output[key]) && __farmMCPIsPlainObject(value)
|
|
4878
|
-
? __farmMergeMCPConfig(output[key], value)
|
|
4879
|
-
: value;
|
|
4880
|
-
}
|
|
4881
|
-
return output;
|
|
4882
|
-
}
|
|
4883
|
-
|
|
4884
|
-
const farmNativeMCPConfig = farmRuntimeConfigs.reduce((merged, runtimeConfig) => {
|
|
4885
|
-
const value = runtimeConfig?.mcp;
|
|
4886
|
-
if (value === undefined) return merged;
|
|
4887
|
-
if (value === false) return false;
|
|
4888
|
-
return __farmMergeMCPConfig(merged && merged !== false ? merged : {}, value);
|
|
4889
|
-
}, undefined);
|
|
4890
|
-
const farmNativeMCPPlugin =
|
|
4891
|
-
farmNativeMCPConfig && farmNativeMCPConfig.enabled !== false
|
|
4892
|
-
? __farmCreateMCPPlugin(farmNativeMCPConfig)
|
|
4893
|
-
: null;`,
|
|
4894
|
-
pluginSource: `...(farmNativeMCPPlugin ? [farmNativeMCPPlugin] : []),`
|
|
4895
|
-
};
|
|
4896
|
-
}
|
|
4897
|
-
__name(generateNativeMCPPluginSource, "generateNativeMCPPluginSource");
|
|
4898
4896
|
function generateIntegrationRequestRuntimeSource(options) {
|
|
4899
4897
|
return `
|
|
4900
4898
|
function matchLocalIntegrationRequest(request) {
|
|
@@ -4945,6 +4943,24 @@ function getConfiguredSetCookieHeaders(headers) {
|
|
|
4945
4943
|
return value ? [value] : [];
|
|
4946
4944
|
}
|
|
4947
4945
|
|
|
4946
|
+
// Owned responses (core's owned-response.ts, RFC 0002) are edited in place.
|
|
4947
|
+
function farmEditableHeaders(response) {
|
|
4948
|
+
return (globalThis[Symbol.for("farm.ownedResponses")] ??= new WeakSet()).has(response)
|
|
4949
|
+
? response.headers
|
|
4950
|
+
: new Headers(response.headers);
|
|
4951
|
+
}
|
|
4952
|
+
|
|
4953
|
+
function farmResponseWithHeaders(response, headers) {
|
|
4954
|
+
if (!headers || headers === response.headers) return response;
|
|
4955
|
+
const output = new Response(response.body, {
|
|
4956
|
+
status: response.status,
|
|
4957
|
+
statusText: response.statusText,
|
|
4958
|
+
headers,
|
|
4959
|
+
});
|
|
4960
|
+
(globalThis[Symbol.for("farm.ownedResponses")] ??= new WeakSet()).add(output);
|
|
4961
|
+
return output;
|
|
4962
|
+
}
|
|
4963
|
+
|
|
4948
4964
|
function applyConfiguredResponseHeaders(response, pathname) {
|
|
4949
4965
|
if (preparedHeaderRoutes.length === 0) return response;
|
|
4950
4966
|
const pathnameSegments = splitRuntimePath(pathname).map(decodeRouteSegment);
|
|
@@ -4959,12 +4975,12 @@ function applyConfiguredResponseHeaders(response, pathname) {
|
|
|
4959
4975
|
const normalizedKey = header.key.toLowerCase();
|
|
4960
4976
|
if (normalizedKey === "set-cookie") {
|
|
4961
4977
|
if (getConfiguredSetCookieHeaders(currentHeaders).includes(header.value)) continue;
|
|
4962
|
-
if (!headers) headers =
|
|
4978
|
+
if (!headers) headers = farmEditableHeaders(response);
|
|
4963
4979
|
headers.append("Set-Cookie", header.value);
|
|
4964
4980
|
} else {
|
|
4965
4981
|
const currentValue = currentHeaders.get(header.key);
|
|
4966
4982
|
if (currentValue === header.value) continue;
|
|
4967
|
-
if (!headers) headers =
|
|
4983
|
+
if (!headers) headers = farmEditableHeaders(response);
|
|
4968
4984
|
if (normalizedKey === "link") {
|
|
4969
4985
|
appendFarmLinkHeader(headers, header.value);
|
|
4970
4986
|
} else {
|
|
@@ -4974,12 +4990,7 @@ function applyConfiguredResponseHeaders(response, pathname) {
|
|
|
4974
4990
|
}
|
|
4975
4991
|
}
|
|
4976
4992
|
|
|
4977
|
-
|
|
4978
|
-
return new Response(response.body, {
|
|
4979
|
-
status: response.status,
|
|
4980
|
-
statusText: response.statusText,
|
|
4981
|
-
headers,
|
|
4982
|
-
});
|
|
4993
|
+
return farmResponseWithHeaders(response, headers);
|
|
4983
4994
|
}
|
|
4984
4995
|
`.trim();
|
|
4985
4996
|
}
|
|
@@ -5006,7 +5017,73 @@ function generatePreloadResponseRuntimeSource() {
|
|
|
5006
5017
|
// reading it, so a changed body is never paired with a stale string.
|
|
5007
5018
|
const farmBufferedHtml = new WeakMap();
|
|
5008
5019
|
|
|
5020
|
+
// A Response Farm creates for this request. Later header steps edit it in place
|
|
5021
|
+
// instead of copying it; responses from app code are never owned. Same registry
|
|
5022
|
+
// as core's owned-response.ts (RFC 0002).
|
|
5023
|
+
function farmOwnedResponse(body, init) {
|
|
5024
|
+
const response = new Response(body, init);
|
|
5025
|
+
(globalThis[Symbol.for("farm.ownedResponses")] ??= new WeakSet()).add(response);
|
|
5026
|
+
return response;
|
|
5027
|
+
}
|
|
5028
|
+
|
|
5029
|
+
// node-server registers srvx's FastResponse here (RFC 0002). A buffered page
|
|
5030
|
+
// built with it keeps its HTML as a string until something reads the body, and
|
|
5031
|
+
// srvx writes that string in one call; other runtimes keep the Web Response.
|
|
5032
|
+
let FarmNodePageResponse;
|
|
5033
|
+
function useFarmNodePageResponse(ResponseClass) {
|
|
5034
|
+
FarmNodePageResponse = ResponseClass;
|
|
5035
|
+
}
|
|
5036
|
+
|
|
5037
|
+
// HTML of buffered pages built as FarmNodePageResponse, keyed by the response:
|
|
5038
|
+
// its body always comes from this string, and looking it up never creates the
|
|
5039
|
+
// Web body the way reading response.body would.
|
|
5040
|
+
const farmLazyBufferedHtml = new WeakMap();
|
|
5041
|
+
|
|
5042
|
+
function hasFarmContentType(headers) {
|
|
5043
|
+
if (!headers) return false;
|
|
5044
|
+
if (typeof headers.has === "function") return headers.has("content-type");
|
|
5045
|
+
for (const key in headers) if (key.toLowerCase() === "content-type") return true;
|
|
5046
|
+
return false;
|
|
5047
|
+
}
|
|
5048
|
+
|
|
5049
|
+
// A complete HTML document Farm built for this request. Same contract as
|
|
5050
|
+
// farmOwnedResponse followed by rememberFarmBufferedHtml.
|
|
5051
|
+
function farmOwnedHtmlResponse(html, init) {
|
|
5052
|
+
if (
|
|
5053
|
+
!FarmNodePageResponse ||
|
|
5054
|
+
typeof html !== "string" ||
|
|
5055
|
+
html.charCodeAt(0) === 0xfeff ||
|
|
5056
|
+
!hasFarmContentType(init?.headers)
|
|
5057
|
+
) {
|
|
5058
|
+
return rememberFarmBufferedHtml(farmOwnedResponse(html, init), html);
|
|
5059
|
+
}
|
|
5060
|
+
const response = new FarmNodePageResponse(html, init);
|
|
5061
|
+
(globalThis[Symbol.for("farm.ownedResponses")] ??= new WeakSet()).add(response);
|
|
5062
|
+
farmLazyBufferedHtml.set(response, html);
|
|
5063
|
+
return response;
|
|
5064
|
+
}
|
|
5065
|
+
|
|
5066
|
+
function isFarmOwnedResponseForPreload(response) {
|
|
5067
|
+
return (globalThis[Symbol.for("farm.ownedResponses")] ??= new WeakSet()).has(response);
|
|
5068
|
+
}
|
|
5069
|
+
|
|
5070
|
+
// Header-only rebuild: in place for an owned response, otherwise a copy Farm owns.
|
|
5071
|
+
function farmPreloadHeadersResponse(response, edit) {
|
|
5072
|
+
if (isFarmOwnedResponseForPreload(response)) {
|
|
5073
|
+
edit(response.headers);
|
|
5074
|
+
return response;
|
|
5075
|
+
}
|
|
5076
|
+
const headers = new Headers(response.headers);
|
|
5077
|
+
edit(headers);
|
|
5078
|
+
return farmOwnedResponse(response.body, {
|
|
5079
|
+
status: response.status,
|
|
5080
|
+
statusText: response.statusText,
|
|
5081
|
+
headers,
|
|
5082
|
+
});
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5009
5085
|
function rememberFarmBufferedHtml(response, html) {
|
|
5086
|
+
if (farmLazyBufferedHtml.has(response)) return response;
|
|
5010
5087
|
// Response.text() strips a leading BOM, so a BOM document keeps reading its
|
|
5011
5088
|
// body to preserve that behavior.
|
|
5012
5089
|
if (typeof html === "string" && html.charCodeAt(0) !== 0xfeff && response.body) {
|
|
@@ -5016,6 +5093,8 @@ function rememberFarmBufferedHtml(response, html) {
|
|
|
5016
5093
|
}
|
|
5017
5094
|
|
|
5018
5095
|
function getFarmOwnedBufferedHtml(response) {
|
|
5096
|
+
const lazyHtml = farmLazyBufferedHtml.get(response);
|
|
5097
|
+
if (lazyHtml !== undefined) return lazyHtml;
|
|
5019
5098
|
const body = response.body;
|
|
5020
5099
|
if (!body || response.bodyUsed || body.locked) return undefined;
|
|
5021
5100
|
return farmBufferedHtml.get(body);
|
|
@@ -5038,17 +5117,14 @@ async function applyFarmPreloadBudget(response, pathname, request) {
|
|
|
5038
5117
|
const isBuffered = bufferedMarker === "1" || hasNoHtmlPreloads;
|
|
5039
5118
|
if (!isHtml) {
|
|
5040
5119
|
if (!isStreaming && !isBuffered) return response;
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
return new Response(response.body, {
|
|
5045
|
-
status: response.status,
|
|
5046
|
-
statusText: response.statusText,
|
|
5047
|
-
headers,
|
|
5120
|
+
return farmPreloadHeadersResponse(response, (editable) => {
|
|
5121
|
+
editable.delete("x-farm-preload-streaming");
|
|
5122
|
+
editable.delete("x-farm-preload-buffered");
|
|
5048
5123
|
});
|
|
5049
5124
|
}
|
|
5050
5125
|
|
|
5051
|
-
|
|
5126
|
+
const isLazyPage = farmLazyBufferedHtml.has(response);
|
|
5127
|
+
if (isStreaming || !isBuffered || (!isLazyPage && response.body === null)) {
|
|
5052
5128
|
const managed = manageFarmLinkHeaderPreloads(linkHeader, farmPreloadConfig);
|
|
5053
5129
|
reportFarmPreloadWarnings(managed.warnings, managed.warnings.length > 0
|
|
5054
5130
|
? "route " + (pathname ?? getFarmRoutePathname(new URL(request.url).pathname))
|
|
@@ -5058,42 +5134,43 @@ async function applyFarmPreloadBudget(response, pathname, request) {
|
|
|
5058
5134
|
if (!headers.has("x-farm-preload-streaming") &&
|
|
5059
5135
|
!headers.has("x-farm-preload-buffered") &&
|
|
5060
5136
|
(managed.value || null) === headers.get("Link")) return response;
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
return new Response(response.body, {
|
|
5067
|
-
status: response.status,
|
|
5068
|
-
statusText: response.statusText,
|
|
5069
|
-
headers,
|
|
5137
|
+
return farmPreloadHeadersResponse(response, (editable) => {
|
|
5138
|
+
editable.delete("x-farm-preload-streaming");
|
|
5139
|
+
editable.delete("x-farm-preload-buffered");
|
|
5140
|
+
if (managed.value) editable.set("Link", managed.value);
|
|
5141
|
+
else editable.delete("Link");
|
|
5070
5142
|
});
|
|
5071
5143
|
}
|
|
5072
5144
|
|
|
5073
5145
|
// Keep the document/header budget semantics (including unchanged Link
|
|
5074
5146
|
// formatting), but do not consume and re-encode a proven preload-free body.
|
|
5075
|
-
headers = new Headers(headers);
|
|
5076
|
-
headers.delete("x-farm-preload-streaming");
|
|
5077
|
-
headers.delete("x-farm-preload-buffered");
|
|
5078
5147
|
const ownedHtml = hasNoHtmlPreloads ? undefined : getFarmOwnedBufferedHtml(response);
|
|
5079
5148
|
const html = hasNoHtmlPreloads ? "" : (ownedHtml ?? await response.text());
|
|
5080
5149
|
const managed = manageFarmDocumentPreloads(html, linkHeader, farmPreloadConfig);
|
|
5081
5150
|
// A remembered document the budget left unchanged keeps its unread body.
|
|
5082
5151
|
const reusesBody = hasNoHtmlPreloads || (ownedHtml !== undefined && managed.html === html);
|
|
5083
|
-
if (ownedHtml !== undefined && !reusesBody
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
if (managed.html !== html) headers.delete("Content-Length");
|
|
5152
|
+
if (ownedHtml !== undefined && !reusesBody && !isLazyPage) {
|
|
5153
|
+
response.body?.cancel().catch(() => {});
|
|
5154
|
+
}
|
|
5087
5155
|
reportFarmPreloadWarnings(managed.warnings, managed.warnings.length > 0
|
|
5088
5156
|
? "route " + (pathname ?? getFarmRoutePathname(new URL(request.url).pathname))
|
|
5089
5157
|
: undefined);
|
|
5090
|
-
const
|
|
5158
|
+
const applyBudgetHeaders = (editable) => {
|
|
5159
|
+
editable.delete("x-farm-preload-streaming");
|
|
5160
|
+
editable.delete("x-farm-preload-buffered");
|
|
5161
|
+
if (managed.linkHeader) editable.set("Link", managed.linkHeader);
|
|
5162
|
+
else editable.delete("Link");
|
|
5163
|
+
if (managed.html !== html) editable.delete("Content-Length");
|
|
5164
|
+
};
|
|
5165
|
+
if (reusesBody) return farmPreloadHeadersResponse(response, applyBudgetHeaders);
|
|
5166
|
+
const rebuiltHeaders = new Headers(headers);
|
|
5167
|
+
applyBudgetHeaders(rebuiltHeaders);
|
|
5168
|
+
// A rebuilt document is still a complete string Farm holds.
|
|
5169
|
+
return farmOwnedHtmlResponse(managed.html, {
|
|
5091
5170
|
status: response.status,
|
|
5092
5171
|
statusText: response.statusText,
|
|
5093
|
-
headers,
|
|
5172
|
+
headers: rebuiltHeaders,
|
|
5094
5173
|
});
|
|
5095
|
-
// A rebuilt document is still a complete string Farm holds.
|
|
5096
|
-
return reusesBody ? output : rememberFarmBufferedHtml(output, managed.html);
|
|
5097
5174
|
}
|
|
5098
5175
|
`.trim();
|
|
5099
5176
|
}
|
|
@@ -5126,6 +5203,7 @@ function generateVirtualEntryCode(apiRoutes, pageRoutes, layoutRoutes, routeSlot
|
|
|
5126
5203
|
config.renderer,
|
|
5127
5204
|
getFarmPresetRuntime(preset)
|
|
5128
5205
|
);
|
|
5206
|
+
const hasReactSyncRender = isReactRenderer(config.renderer);
|
|
5129
5207
|
const rendererServerImports = isReactRenderer(config.renderer) ? `import * as React from "react";
|
|
5130
5208
|
import * as ReactDOMServer from "react-dom/server";${hasIsolatedClientGraphRuntime ? '\nimport { isolateFarmServerPageGraph, wrapFarmIsolatedClientGraph } from "@farm.js/core/internal/isolated-boundary";' : ""}` : `import React, * as ReactDOMServer from ${JSON.stringify(config.renderer.server)};${generateFarmRendererAppSetupServerCode(config)}`;
|
|
5131
5209
|
const routeClientGraphServerRuntime = hasIsolatedClientGraphRuntime ? `function wrapFarmRouteClientGraph(element) {
|
|
@@ -5651,6 +5729,7 @@ ${routeClientGraphServerRuntime}
|
|
|
5651
5729
|
|
|
5652
5730
|
const farmRendererStreamingCapabilities = ${JSON.stringify(rendererStreamingCapabilities)};
|
|
5653
5731
|
const farmRendererName = ${JSON.stringify(config.renderer.name)};
|
|
5732
|
+
const farmReactSyncRender = ${JSON.stringify(hasReactSyncRender)};
|
|
5654
5733
|
const farmRendererRuntime = ${JSON.stringify(getFarmPresetRuntime(preset))};
|
|
5655
5734
|
const farmRendererRuntimeStreamingCapabilities = ReactDOMServer.capabilities &&
|
|
5656
5735
|
ReactDOMServer.capabilities.streaming;
|
|
@@ -6050,8 +6129,10 @@ function escapeFarmHtmlAttribute(value) {
|
|
|
6050
6129
|
.replace(/>/g, ">");
|
|
6051
6130
|
}
|
|
6052
6131
|
|
|
6053
|
-
async function renderFarmElement(ReactDOMServer, element) {
|
|
6132
|
+
async function renderFarmElement(ReactDOMServer, element, routeKey) {
|
|
6054
6133
|
const streamErrors = [];
|
|
6134
|
+
const syncHtml = renderFarmElementSync(ReactDOMServer, element, routeKey);
|
|
6135
|
+
if (syncHtml !== undefined) return { html: syncHtml, shellHtml: syncHtml, streamErrors };
|
|
6055
6136
|
let encoder;
|
|
6056
6137
|
const normalizeChunk = function(chunk) {
|
|
6057
6138
|
if (typeof chunk === "string") return (encoder ||= new TextEncoder()).encode(chunk);
|
|
@@ -6122,6 +6203,7 @@ async function renderFarmElement(ReactDOMServer, element) {
|
|
|
6122
6203
|
}
|
|
6123
6204
|
throwStreamError();
|
|
6124
6205
|
const html = decodeChunks(chunks);
|
|
6206
|
+
rememberFarmSyncRender(routeKey, html);
|
|
6125
6207
|
return { html, shellHtml: html, streamErrors };
|
|
6126
6208
|
}
|
|
6127
6209
|
|
|
@@ -6253,6 +6335,7 @@ async function renderFarmElement(ReactDOMServer, element) {
|
|
|
6253
6335
|
await complete;
|
|
6254
6336
|
throwStreamError();
|
|
6255
6337
|
const html = decodeChunks(chunks);
|
|
6338
|
+
rememberFarmSyncRender(routeKey, html);
|
|
6256
6339
|
return { html, shellHtml: html, streamErrors };
|
|
6257
6340
|
}
|
|
6258
6341
|
|
|
@@ -6293,6 +6376,45 @@ async function renderFarmElementToString(ReactDOMServer, element) {
|
|
|
6293
6376
|
return html;
|
|
6294
6377
|
}
|
|
6295
6378
|
|
|
6379
|
+
// Most pages render without suspending. React's renderToString renders them in
|
|
6380
|
+
// one synchronous pass with string output, about half the CPU of the streaming
|
|
6381
|
+
// renderer, and the same markup, except that React 19's streaming renderer adds
|
|
6382
|
+
// a doctype before an <html> root. A route uses it only after a streaming render
|
|
6383
|
+
// of that route finished without suspending (remembering whether that render
|
|
6384
|
+
// started with a doctype), so a page that suspends keeps streaming and renders
|
|
6385
|
+
// once. If such a route suspends later (a Suspense boundary left to the
|
|
6386
|
+
// client, marked <!--$!-->, or a throw), that request renders again through the
|
|
6387
|
+
// streaming path and the route streams for the rest of this server process.
|
|
6388
|
+
const farmSyncRenderRoutes = new Map();
|
|
6389
|
+
const farmStreamingRenderRoutes = new Set();
|
|
6390
|
+
const FARM_STREAMED_DOCTYPE = "<!DOCTYPE html>";
|
|
6391
|
+
|
|
6392
|
+
function rememberFarmSyncRender(routeKey, streamedHtml) {
|
|
6393
|
+
if (!farmReactSyncRender || routeKey === undefined) return;
|
|
6394
|
+
if (!farmStreamingRenderRoutes.has(routeKey)) {
|
|
6395
|
+
farmSyncRenderRoutes.set(routeKey, streamedHtml.startsWith(FARM_STREAMED_DOCTYPE));
|
|
6396
|
+
}
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6399
|
+
function renderFarmElementSync(ReactDOMServer, element, routeKey) {
|
|
6400
|
+
if (!farmReactSyncRender) return undefined;
|
|
6401
|
+
const addsDoctype = routeKey === undefined ? undefined : farmSyncRenderRoutes.get(routeKey);
|
|
6402
|
+
if (addsDoctype === undefined) return undefined;
|
|
6403
|
+
if (typeof ReactDOMServer.renderToString !== "function") return undefined;
|
|
6404
|
+
let html;
|
|
6405
|
+
try {
|
|
6406
|
+
html = ReactDOMServer.renderToString(element);
|
|
6407
|
+
} catch {
|
|
6408
|
+
html = undefined;
|
|
6409
|
+
}
|
|
6410
|
+
if (typeof html !== "string" || html.includes("<!--$!-->")) {
|
|
6411
|
+
farmSyncRenderRoutes.delete(routeKey);
|
|
6412
|
+
farmStreamingRenderRoutes.add(routeKey);
|
|
6413
|
+
return undefined;
|
|
6414
|
+
}
|
|
6415
|
+
return addsDoctype && html.startsWith("<html") ? FARM_STREAMED_DOCTYPE + html : html;
|
|
6416
|
+
}
|
|
6417
|
+
|
|
6296
6418
|
function createFarmDocumentStream(contentStream, prefix, suffix, onComplete) {
|
|
6297
6419
|
const encoder = new TextEncoder();
|
|
6298
6420
|
const reader = contentStream.getReader();
|
|
@@ -7422,7 +7544,7 @@ async function handleFarmRequestInContext(
|
|
|
7422
7544
|
url.search,
|
|
7423
7545
|
);
|
|
7424
7546
|
if (redirectMatch) {
|
|
7425
|
-
return
|
|
7547
|
+
return farmOwnedResponse("Redirecting to " + redirectMatch.destination, {
|
|
7426
7548
|
status: redirectMatch.statusCode,
|
|
7427
7549
|
headers: { Location: redirectMatch.destination },
|
|
7428
7550
|
});
|
|
@@ -7526,7 +7648,7 @@ async function handleFarmRequestInContext(
|
|
|
7526
7648
|
);
|
|
7527
7649
|
const docsHeaders = new Headers(wrappedDocsResponse.headers);
|
|
7528
7650
|
docsHeaders.set("x-farm-preload-buffered", "1");
|
|
7529
|
-
return applyProductionMiddlewareHeaders(
|
|
7651
|
+
return applyProductionMiddlewareHeaders(farmOwnedResponse(wrappedDocsResponse.body, {
|
|
7530
7652
|
status: wrappedDocsResponse.status,
|
|
7531
7653
|
statusText: wrappedDocsResponse.statusText,
|
|
7532
7654
|
headers: docsHeaders,
|
|
@@ -7572,9 +7694,13 @@ async function handleFarmRequestInContext(
|
|
|
7572
7694
|
` : ""}
|
|
7573
7695
|
|
|
7574
7696
|
${apiRoutes.length > 0 ? `
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7697
|
+
// Clone only for an API request: cloning a Request costs more than the match,
|
|
7698
|
+
// and handleAPIRequest returns null without one.
|
|
7699
|
+
if (matchLocalAPIRequest(request)) {
|
|
7700
|
+
const apiResponse = await handleAPIRequest(cloneFarmRequestWithContext(request));
|
|
7701
|
+
if (apiResponse) {
|
|
7702
|
+
return applyProductionMiddlewareHeaders(apiResponse, middlewareHeaders);
|
|
7703
|
+
}
|
|
7578
7704
|
}
|
|
7579
7705
|
` : ""}
|
|
7580
7706
|
|
|
@@ -7585,7 +7711,7 @@ async function handleFarmRequestInContext(
|
|
|
7585
7711
|
) {
|
|
7586
7712
|
const method = request.method.toUpperCase();
|
|
7587
7713
|
const specResponse = method === "GET" || method === "HEAD"
|
|
7588
|
-
?
|
|
7714
|
+
? farmOwnedResponse(method === "HEAD" ? null : JSON.stringify(farmOpenAPIReference.spec), {
|
|
7589
7715
|
status: 200,
|
|
7590
7716
|
headers: {
|
|
7591
7717
|
"Content-Type": "application/json; charset=utf-8",
|
|
@@ -7593,7 +7719,7 @@ async function handleFarmRequestInContext(
|
|
|
7593
7719
|
"X-Content-Type-Options": "nosniff",
|
|
7594
7720
|
},
|
|
7595
7721
|
})
|
|
7596
|
-
:
|
|
7722
|
+
: farmOwnedResponse("Method Not Allowed", {
|
|
7597
7723
|
status: 405,
|
|
7598
7724
|
headers: {
|
|
7599
7725
|
"Allow": "GET, HEAD",
|
|
@@ -7609,7 +7735,7 @@ async function handleFarmRequestInContext(
|
|
|
7609
7735
|
) {
|
|
7610
7736
|
const method = request.method.toUpperCase();
|
|
7611
7737
|
const response = method === "GET" || method === "HEAD"
|
|
7612
|
-
?
|
|
7738
|
+
? farmOwnedResponse(method === "HEAD" ? null : farmOpenAPIReference.html, {
|
|
7613
7739
|
status: 200,
|
|
7614
7740
|
headers: {
|
|
7615
7741
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -7617,7 +7743,7 @@ async function handleFarmRequestInContext(
|
|
|
7617
7743
|
"X-Content-Type-Options": "nosniff",
|
|
7618
7744
|
},
|
|
7619
7745
|
})
|
|
7620
|
-
:
|
|
7746
|
+
: farmOwnedResponse("Method Not Allowed", {
|
|
7621
7747
|
status: 405,
|
|
7622
7748
|
headers: {
|
|
7623
7749
|
"Allow": "GET, HEAD",
|
|
@@ -7712,7 +7838,7 @@ async function handleFarmRequestInContext(
|
|
|
7712
7838
|
|
|
7713
7839
|
// Preserve the explicit JSON 404 for misses below the configured local API path.
|
|
7714
7840
|
if (isFarmLocalAPIPathname(pathname)) {
|
|
7715
|
-
return applyProductionMiddlewareHeaders(
|
|
7841
|
+
return applyProductionMiddlewareHeaders(farmOwnedResponse(
|
|
7716
7842
|
JSON.stringify({ error: "API route not found", pathname }),
|
|
7717
7843
|
{ status: 404, headers: { "Content-Type": "application/json" } }
|
|
7718
7844
|
), middlewareHeaders);
|
|
@@ -7728,7 +7854,7 @@ async function handleFarmRequestInContext(
|
|
|
7728
7854
|
);
|
|
7729
7855
|
if (trailingSlashLocation) {
|
|
7730
7856
|
return applyProductionMiddlewareHeaders(
|
|
7731
|
-
|
|
7857
|
+
farmOwnedResponse(null, {
|
|
7732
7858
|
status: 308,
|
|
7733
7859
|
headers: { Location: trailingSlashLocation },
|
|
7734
7860
|
}),
|
|
@@ -7771,7 +7897,7 @@ async function handleFarmRequestInContext(
|
|
|
7771
7897
|
status: 200,
|
|
7772
7898
|
durationMs: Date.now() - requestStartTime,
|
|
7773
7899
|
});
|
|
7774
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
7900
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(cachedPPRShell, {
|
|
7775
7901
|
status: 200,
|
|
7776
7902
|
headers: {
|
|
7777
7903
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -8078,7 +8204,7 @@ async function handleFarmRequestInContext(
|
|
|
8078
8204
|
}
|
|
8079
8205
|
|
|
8080
8206
|
wrappedElement = wrapWithFarmIntegrationProviders(wrappedElement);
|
|
8081
|
-
return renderFarmElement(ReactDOMServer, wrappedElement);
|
|
8207
|
+
return renderFarmElement(ReactDOMServer, wrappedElement, route.pattern);
|
|
8082
8208
|
};
|
|
8083
8209
|
const renderedPage = ${hasMiddlewareRuntime ? `await _runWithMiddlewareData(middlewareData, () =>
|
|
8084
8210
|
_runWithMiddlewareContext(middlewareContext, renderPageElement)
|
|
@@ -8266,7 +8392,7 @@ async function handleFarmRequestInContext(
|
|
|
8266
8392
|
});
|
|
8267
8393
|
}
|
|
8268
8394
|
);
|
|
8269
|
-
return applyProductionMiddlewareHeaders(
|
|
8395
|
+
return applyProductionMiddlewareHeaders(farmOwnedResponse(streamedDocument, {
|
|
8270
8396
|
status: pageStatus,
|
|
8271
8397
|
headers: { ...responseHeaders, "x-farm-preload-streaming": "1" },
|
|
8272
8398
|
}), middlewareHeaders);
|
|
@@ -8407,7 +8533,7 @@ async function handleFarmRequestInContext(
|
|
|
8407
8533
|
durationMs: Date.now() - requestStartTime,
|
|
8408
8534
|
});
|
|
8409
8535
|
|
|
8410
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
8536
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(
|
|
8411
8537
|
fullHtml,
|
|
8412
8538
|
{
|
|
8413
8539
|
status: pageStatus,
|
|
@@ -8441,7 +8567,7 @@ async function handleFarmRequestInContext(
|
|
|
8441
8567
|
status: redirect.status,
|
|
8442
8568
|
durationMs: Date.now() - requestStartTime,
|
|
8443
8569
|
});
|
|
8444
|
-
return applyProductionMiddlewareHeaders(
|
|
8570
|
+
return applyProductionMiddlewareHeaders(farmOwnedResponse(null, {
|
|
8445
8571
|
status: redirect.status,
|
|
8446
8572
|
headers: {
|
|
8447
8573
|
Location: redirectUrl,
|
|
@@ -8509,7 +8635,7 @@ async function handleFarmRequestInContext(
|
|
|
8509
8635
|
status: errorStatus,
|
|
8510
8636
|
durationMs: Date.now() - requestStartTime,
|
|
8511
8637
|
});
|
|
8512
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
8638
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(errorDocument, {
|
|
8513
8639
|
status: errorStatus,
|
|
8514
8640
|
headers: {
|
|
8515
8641
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -8544,7 +8670,7 @@ async function handleFarmRequestInContext(
|
|
|
8544
8670
|
farmResolvedRuntimeConfig.basePath,
|
|
8545
8671
|
getFarmTheme(request)
|
|
8546
8672
|
);
|
|
8547
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
8673
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(
|
|
8548
8674
|
fallbackDocument,
|
|
8549
8675
|
{
|
|
8550
8676
|
status: errorStatus,
|
|
@@ -8575,7 +8701,7 @@ async function handleFarmRequestInContext(
|
|
|
8575
8701
|
status: 404,
|
|
8576
8702
|
durationMs: Date.now() - requestStartTime,
|
|
8577
8703
|
});
|
|
8578
|
-
return applyProductionMiddlewareHeaders(
|
|
8704
|
+
return applyProductionMiddlewareHeaders(farmOwnedResponse(
|
|
8579
8705
|
createFarmMarkdownErrorBody(404, pathname, applyFarmBasePath("/", farmResolvedRuntimeConfig.basePath)),
|
|
8580
8706
|
{
|
|
8581
8707
|
status: 404,
|
|
@@ -8672,7 +8798,7 @@ async function handleFarmRequestInContext(
|
|
|
8672
8798
|
durationMs: Date.now() - requestStartTime,
|
|
8673
8799
|
});
|
|
8674
8800
|
|
|
8675
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
8801
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(fullHtml, {
|
|
8676
8802
|
status: 404,
|
|
8677
8803
|
headers: {
|
|
8678
8804
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -8687,7 +8813,7 @@ async function handleFarmRequestInContext(
|
|
|
8687
8813
|
farmResolvedRuntimeConfig.basePath,
|
|
8688
8814
|
getFarmTheme(request)
|
|
8689
8815
|
);
|
|
8690
|
-
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(
|
|
8816
|
+
return rememberFarmBufferedHtml(applyProductionMiddlewareHeaders(farmOwnedHtmlResponse(
|
|
8691
8817
|
fallbackDocument,
|
|
8692
8818
|
{
|
|
8693
8819
|
status: 404,
|
|
@@ -8750,11 +8876,11 @@ async function handleFarmPluginRequest(request, runtimeOptions, adapterContext)
|
|
|
8750
8876
|
headers.delete("content-length");
|
|
8751
8877
|
headers.delete("x-farm-preload-streaming");
|
|
8752
8878
|
headers.set("x-farm-preload-buffered", getFarmBufferedPreloadMarker(html));
|
|
8753
|
-
return
|
|
8879
|
+
return farmOwnedHtmlResponse(html, {
|
|
8754
8880
|
status: response.status,
|
|
8755
8881
|
statusText: response.statusText,
|
|
8756
8882
|
headers,
|
|
8757
|
-
})
|
|
8883
|
+
});
|
|
8758
8884
|
}
|
|
8759
8885
|
|
|
8760
8886
|
${generatePreloadResponseRuntimeSource()}
|
|
@@ -8831,7 +8957,7 @@ async function handleFarmFetch(request, context) {
|
|
|
8831
8957
|
const response = await _runWithCurrentRequest(request, () =>
|
|
8832
8958
|
_runWithAfterRequest(request, runRequest, context),
|
|
8833
8959
|
);
|
|
8834
|
-
return ${hasCompressionRuntime && !hasPluginRuntime ? "compressFarmResponse(request, response, getFarmOwnedBufferedHtml(response))" : "response"};
|
|
8960
|
+
return ${hasCompressionRuntime && !hasPluginRuntime ? "compressFarmResponse(request, response, getFarmOwnedBufferedHtml(response), farmLazyBufferedHtml.has(response))" : "response"};
|
|
8835
8961
|
}),
|
|
8836
8962
|
{
|
|
8837
8963
|
onResponseFinished: typeof context?.onResponseFinished === "function"
|
|
@@ -8840,7 +8966,7 @@ async function handleFarmFetch(request, context) {
|
|
|
8840
8966
|
},
|
|
8841
8967
|
);
|
|
8842
8968
|
}
|
|
8843
|
-
export { createFarmNodeRequestAbortSignal };
|
|
8969
|
+
export { createFarmNodeRequestAbortSignal, getFarmOwnedBufferedHtml, useFarmNodePageResponse };
|
|
8844
8970
|
export default { fetch, lifecycle: farmProductionLifecycle };
|
|
8845
8971
|
`.trim();
|
|
8846
8972
|
}
|
|
@@ -9081,12 +9207,16 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
9081
9207
|
await fs.writeFile(filePath, output.type === "chunk" ? output.code : output.source);
|
|
9082
9208
|
}
|
|
9083
9209
|
const nitroEntryPath = path5.join(ssrOutputDir, "nitro-entry.mjs");
|
|
9210
|
+
const nodeAdapterModule = preset === "node-server" ? resolveNitroRuntimeDependency(root, "srvx/node") : null;
|
|
9084
9211
|
const nitroEntryCode = `
|
|
9085
9212
|
// Farm.js Nitro Entry
|
|
9086
9213
|
// This file adapts Farm's Web fetch handler to Nitro's event handler contract.
|
|
9087
9214
|
|
|
9088
9215
|
import { useNitroHooks } from '#nitro/runtime/app'
|
|
9089
|
-
import handler, { farmProductionLifecycle, createFarmNodeRequestAbortSignal } from './${ssrEntryFile}'
|
|
9216
|
+
import handler, { farmProductionLifecycle, createFarmNodeRequestAbortSignal${nodeAdapterModule ? ", getFarmOwnedBufferedHtml, useFarmNodePageResponse" : ""} } from './${ssrEntryFile}'${nodeAdapterModule ? `
|
|
9217
|
+
import { FastResponse } from ${JSON.stringify(nodeAdapterModule)}
|
|
9218
|
+
|
|
9219
|
+
useFarmNodePageResponse(FastResponse)` : ""}
|
|
9090
9220
|
|
|
9091
9221
|
export { farmProductionLifecycle }
|
|
9092
9222
|
|
|
@@ -9182,11 +9312,14 @@ function resolveTrustedLocalOrigin(event, request) {
|
|
|
9182
9312
|
// Export the event handler for Nitro
|
|
9183
9313
|
export default async function farmNitroEventHandler(event) {
|
|
9184
9314
|
registerFarmCloseHook()
|
|
9185
|
-
//
|
|
9186
|
-
//
|
|
9315
|
+
// Abort only on an actual disconnect, the same events as Farm's development
|
|
9316
|
+
// server. srvx's Request already aborts that way (on a response close before
|
|
9317
|
+
// it ended, never on a normal IncomingMessage close), so use it as is. Other
|
|
9318
|
+
// Node adapters get a copy with Farm's own signal.
|
|
9187
9319
|
const node = event.node
|
|
9188
|
-
const
|
|
9189
|
-
const
|
|
9320
|
+
const srvxRequest = event.req?._request
|
|
9321
|
+
const webRequest = srvxRequest || event.req
|
|
9322
|
+
const request = !srvxRequest && node?.req && node?.res
|
|
9190
9323
|
? new Request(webRequest, { signal: createFarmNodeRequestAbortSignal(node.req, node.res) })
|
|
9191
9324
|
: webRequest
|
|
9192
9325
|
const response = await handler.fetch(request, {
|
|
@@ -9197,20 +9330,42 @@ export default async function farmNitroEventHandler(event) {
|
|
|
9197
9330
|
})
|
|
9198
9331
|
|
|
9199
9332
|
// Nitro records asset compression negotiation on the event response. Merge
|
|
9200
|
-
// Farm's cache signals there so H3 preserves both sets of Vary values.
|
|
9333
|
+
// Farm's cache signals there so H3 preserves both sets of Vary values. Only
|
|
9334
|
+
// merge into a Vary Nitro set: any event header makes H3 rebuild the response
|
|
9335
|
+
// around its body, and without one H3 keeps Farm's Vary as it is.
|
|
9201
9336
|
const farmVary = response.headers.get('Vary')
|
|
9202
|
-
if (farmVary)
|
|
9203
|
-
|
|
9204
|
-
|
|
9337
|
+
if (farmVary) {
|
|
9338
|
+
const nitroHeaders = event.res.headers
|
|
9339
|
+
if (nitroHeaders.has('Vary')) mergeVaryHeaders(nitroHeaders, farmVary)
|
|
9340
|
+
}
|
|
9341
|
+
return ${nodeAdapterModule ? "toFarmNodeResponse(request, response)" : "response"}
|
|
9342
|
+
}${nodeAdapterModule ? `
|
|
9343
|
+
|
|
9344
|
+
// A page Farm still holds as one complete string is sent in a single write with
|
|
9345
|
+
// Content-Length, instead of srvx reading the Web stream chunk by chunk. Any
|
|
9346
|
+
// step that read, cloned or replaced the body made a new stream, so its lookup
|
|
9347
|
+
// misses and that response is sent as it is.
|
|
9348
|
+
function toFarmNodeResponse(request, response) {
|
|
9349
|
+
if (request.method === 'HEAD') return response
|
|
9350
|
+
// Already a FastResponse (a buffered page built as one): srvx sends it as is.
|
|
9351
|
+
if (typeof response._toNodeResponse === 'function') return response
|
|
9352
|
+
const html = getFarmOwnedBufferedHtml(response)
|
|
9353
|
+
if (html === undefined) return response
|
|
9354
|
+
return new FastResponse(html, {
|
|
9355
|
+
status: response.status,
|
|
9356
|
+
statusText: response.statusText,
|
|
9357
|
+
headers: response.headers,
|
|
9358
|
+
})
|
|
9359
|
+
}` : ""}
|
|
9205
9360
|
`.trim();
|
|
9206
9361
|
await fs.writeFile(nitroEntryPath, nitroEntryCode);
|
|
9207
9362
|
const farmNodeServerEntryPath = preset === "node-server" ? path5.join(ssrOutputDir, "farm-node-server-entry.mjs") : null;
|
|
9208
|
-
if (farmNodeServerEntryPath) {
|
|
9363
|
+
if (farmNodeServerEntryPath && nodeAdapterModule) {
|
|
9209
9364
|
await fs.writeFile(
|
|
9210
9365
|
farmNodeServerEntryPath,
|
|
9211
9366
|
createFarmNodeServerEntry({
|
|
9212
9367
|
nitroEntryFile: path5.basename(nitroEntryPath),
|
|
9213
|
-
nodeAdapterModule
|
|
9368
|
+
nodeAdapterModule,
|
|
9214
9369
|
server: config.server,
|
|
9215
9370
|
websocketAdapterModule: resolveNitroRuntimeDependency(root, "crossws/adapters/node")
|
|
9216
9371
|
})
|
|
@@ -9301,7 +9456,13 @@ export default async function farmNitroEventHandler(event) {
|
|
|
9301
9456
|
},
|
|
9302
9457
|
rollupConfig: {
|
|
9303
9458
|
external: nitroRollupExternal,
|
|
9304
|
-
plugins:
|
|
9459
|
+
plugins: [
|
|
9460
|
+
...hasGeneratedMetadataImages && !useExternalMetadataImageRuntime ? [createMetadataImageWasmPlugin()] : [],
|
|
9461
|
+
// Workers bundle React here rather than loading it from node_modules.
|
|
9462
|
+
// Unenv rewrites `process` before Nitro's own replacements run, so
|
|
9463
|
+
// React's development builds would otherwise ship next to production.
|
|
9464
|
+
...isCloudflareWorker ? [createReactProductionModePlugin()] : []
|
|
9465
|
+
]
|
|
9305
9466
|
},
|
|
9306
9467
|
// Keep the public Nitro boolean intact for build hooks. Farm replaces
|
|
9307
9468
|
// Nitro's minifier only when no custom OXC transform was requested.
|