@farm.js/core 0.1.36 → 0.1.38
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-mcp-BVExL8rZ.d.mts → agent-mcp-BwKlpnc7.d.mts} +1 -1
- package/dist/{agent-mcp-luzfXK-P.d.ts → agent-mcp-De1imoMS.d.ts} +1 -1
- package/dist/{agent-mcp-handler-SJAHFSPI.cjs → agent-mcp-handler-MRGP3WJ3.cjs} +5 -5
- package/dist/{agent-mcp-handler-LPJ2CADR.mjs → agent-mcp-handler-OLRMZONF.mjs} +4 -4
- package/dist/agent-runtime.cjs +3 -3
- package/dist/agent-runtime.d.mts +1 -1
- package/dist/agent-runtime.d.ts +1 -1
- package/dist/agent-runtime.mjs +2 -2
- package/dist/api/client.cjs +3 -3
- package/dist/api/client.mjs +2 -2
- package/dist/api/route-manager.cjs +6 -6
- package/dist/api/route-manager.d.mts +3 -3
- package/dist/api/route-manager.d.ts +3 -3
- package/dist/api/route-manager.mjs +5 -5
- package/dist/api/runtime.cjs +4 -4
- package/dist/api/runtime.d.mts +2 -2
- package/dist/api/runtime.d.ts +2 -2
- package/dist/api/runtime.mjs +3 -3
- package/dist/api.cjs +9 -8
- package/dist/api.d.mts +3 -3
- package/dist/api.d.ts +3 -3
- package/dist/api.mjs +8 -7
- package/dist/{app-BukwkFIu.d.mts → app-CFZt-srr.d.mts} +21 -3
- package/dist/{app-Yfa2dsFy.d.ts → app-kT_QXTdx.d.ts} +21 -3
- package/dist/app-markdown.cjs +6 -4
- package/dist/app-markdown.d.mts +3 -3
- package/dist/app-markdown.d.ts +3 -3
- package/dist/app-markdown.mjs +5 -3
- package/dist/{chunk-ADEA7PN3.cjs → chunk-2DD4JMQC.cjs} +113 -22
- package/dist/chunk-2ZYGC6SS.cjs +576 -0
- package/dist/{chunk-JZVADIOD.cjs → chunk-34UCJRQO.cjs} +2 -2
- package/dist/{chunk-D2BB47NB.cjs → chunk-3LOLJTFV.cjs} +6 -6
- package/dist/{chunk-KXWRO25S.cjs → chunk-472NCAZ7.cjs} +3 -3
- package/dist/chunk-4E5QXOCL.cjs +109 -0
- package/dist/{chunk-Z2HLU4IX.cjs → chunk-4GWRFP22.cjs} +23 -2
- package/dist/{chunk-VQLJWDVW.cjs → chunk-4IE345DM.cjs} +37 -19
- package/dist/{chunk-O6WAEAX3.mjs → chunk-5BWWFHR2.mjs} +70 -15
- package/dist/{chunk-JNUWCDTF.cjs → chunk-5D2JIPLH.cjs} +2 -2
- package/dist/{chunk-BO36SELV.cjs → chunk-5OKBARDN.cjs} +2 -2
- package/dist/{chunk-AO6RYU5N.cjs → chunk-5PWXMJOH.cjs} +30 -22
- package/dist/{chunk-AHGECQEW.mjs → chunk-666CKENS.mjs} +1 -1
- package/dist/chunk-6BK3K2GB.mjs +318 -0
- package/dist/{chunk-O6I6VWKK.mjs → chunk-6HB6V3R7.mjs} +1 -1
- package/dist/{chunk-UXFQ3UDA.cjs → chunk-6XWDE2P2.cjs} +61 -4
- package/dist/{chunk-VILIPRS6.mjs → chunk-7FPTZLKH.mjs} +1 -1
- package/dist/{chunk-SC2WYWPF.mjs → chunk-7PEP3BUT.mjs} +3 -3
- package/dist/{chunk-4E5AEDKY.mjs → chunk-A3EAIURZ.mjs} +25 -7
- package/dist/{chunk-YDQZGSDS.mjs → chunk-ARC7I3O2.mjs} +1 -1
- package/dist/{chunk-LSZAVSGY.mjs → chunk-B6G5CKMC.mjs} +101 -10
- package/dist/{chunk-3KZS4SUS.mjs → chunk-BZHXGVMA.mjs} +1 -1
- package/dist/{chunk-KN7K4VQN.mjs → chunk-CNNOLE4O.mjs} +1 -1
- package/dist/{chunk-4GLOOWKE.mjs → chunk-CQMVIOYP.mjs} +1 -1
- package/dist/{chunk-2ELDTQRN.mjs → chunk-CUM5NYL5.mjs} +1 -1
- package/dist/{chunk-HITLGIAO.cjs → chunk-CY2ZQ5C6.cjs} +7 -6
- package/dist/{chunk-PZNL3WEG.mjs → chunk-DMEPTZTI.mjs} +22 -11
- package/dist/{chunk-QORUJDIV.mjs → chunk-DRLKAXDM.mjs} +2 -2
- package/dist/{chunk-DQQOKWYA.cjs → chunk-EIPC3FDA.cjs} +12 -4
- package/dist/{chunk-HOXTWRGB.mjs → chunk-EKF7KDFD.mjs} +5 -2
- package/dist/{chunk-42NHY7HW.cjs → chunk-EKN7NSZO.cjs} +62 -14
- package/dist/{chunk-YKX5BK66.cjs → chunk-EMO6K4YY.cjs} +7 -7
- package/dist/{chunk-6SJ2KJTA.mjs → chunk-EPYU2EBL.mjs} +1 -1
- package/dist/{chunk-D227TIEN.cjs → chunk-FWE7LEQC.cjs} +13 -13
- package/dist/{chunk-PTZ2TVNE.cjs → chunk-H5CLOUZS.cjs} +5 -5
- package/dist/{chunk-DTSROJ5J.mjs → chunk-HD5CF3OE.mjs} +1 -1
- package/dist/{chunk-35GKZR22.mjs → chunk-HXRYZWTA.mjs} +1 -1
- package/dist/{chunk-JG6DJF5A.mjs → chunk-HZFM2LWQ.mjs} +22 -1
- package/dist/{chunk-MKYBIIAQ.mjs → chunk-IBUQWVYA.mjs} +17 -1
- package/dist/{chunk-F2SE2VDO.mjs → chunk-IHQIOZLC.mjs} +1 -1
- package/dist/{chunk-W7LF2J2S.mjs → chunk-INL3THCU.mjs} +1 -1
- package/dist/{chunk-WZ77PUAM.mjs → chunk-IVLZZZEI.mjs} +1 -1
- package/dist/{chunk-ENLZ4R3Y.mjs → chunk-J7K2NZD6.mjs} +7 -6
- package/dist/{chunk-BPOF5U4N.mjs → chunk-JCKYH4LG.mjs} +10 -7
- package/dist/{chunk-77GNHH2Z.cjs → chunk-JCYYXBAJ.cjs} +3 -3
- package/dist/{chunk-C4SPBWFM.cjs → chunk-JEZO6VUR.cjs} +10 -1
- package/dist/{chunk-ZWM5KGAA.cjs → chunk-KCQBAKIY.cjs} +23 -20
- package/dist/{chunk-OTC5BDGO.mjs → chunk-KHKLMNI5.mjs} +12 -7
- package/dist/{chunk-DZ5ZVB2K.cjs → chunk-KKSTAEMY.cjs} +1 -1
- package/dist/{chunk-N2NAS2AM.cjs → chunk-L4DD7ODZ.cjs} +2 -2
- package/dist/{chunk-YSCV4SJF.cjs → chunk-L5H2GSUC.cjs} +4 -4
- package/dist/{chunk-OO7GXVSR.mjs → chunk-LI2F57NI.mjs} +1 -1
- package/dist/{chunk-NRSN7G7E.mjs → chunk-MLY2RP5R.mjs} +10 -2
- package/dist/{chunk-BPMATOP2.cjs → chunk-N32CC42M.cjs} +25 -20
- package/dist/{chunk-FNO7A7CM.cjs → chunk-NBBEQLOK.cjs} +34 -16
- package/dist/{chunk-XCMCS4DA.mjs → chunk-ND2CWPOD.mjs} +2 -2
- package/dist/{chunk-GQRWBCWK.mjs → chunk-OAHTRMIC.mjs} +13 -5
- package/dist/{chunk-35WV46VL.mjs → chunk-OCIEZME4.mjs} +876 -685
- package/dist/{chunk-UH6QN5NL.mjs → chunk-P664ZVTV.mjs} +2 -2
- package/dist/{chunk-TE2G5ION.cjs → chunk-PGZDEPTM.cjs} +88 -33
- package/dist/{chunk-FDR64H6B.mjs → chunk-POSPE3IO.mjs} +59 -2
- package/dist/{chunk-UVW64BCB.cjs → chunk-Q3NXS4MU.cjs} +16 -14
- package/dist/{chunk-4WCZJQUO.mjs → chunk-QFW2IH5E.mjs} +57 -9
- package/dist/{chunk-5SJWVY6R.mjs → chunk-QHSH7IH4.mjs} +9 -0
- package/dist/chunk-QRKIMN7T.mjs +48 -0
- package/dist/chunk-QTXBII4Z.cjs +632 -0
- package/dist/{chunk-CI6E3UOH.cjs → chunk-RG4A6LB2.cjs} +7 -7
- package/dist/{chunk-BJPBQNIE.cjs → chunk-RW63BOV7.cjs} +2 -2
- package/dist/{chunk-FO427P6I.cjs → chunk-RWFLWR5J.cjs} +10 -10
- package/dist/{chunk-FFFW3OQ7.cjs → chunk-S6FJO323.cjs} +2 -2
- package/dist/{chunk-EUV4YR3V.cjs → chunk-SGBJ247Q.cjs} +18 -2
- package/dist/chunk-SGBZPZUW.mjs +75 -0
- package/dist/{chunk-2NNMOPDN.mjs → chunk-SKVTP5PR.mjs} +4 -1
- package/dist/{chunk-2YTDKNH3.cjs → chunk-TGFQVLLF.cjs} +956 -765
- package/dist/{chunk-IHNIDL6H.cjs → chunk-TO4GJ56K.cjs} +22 -11
- package/dist/{chunk-276VJSM6.mjs → chunk-TUBTR2OP.mjs} +250 -118
- package/dist/{chunk-GQ3Z3IZI.cjs → chunk-TYJALEHQ.cjs} +18 -18
- package/dist/chunk-TYMMBFN2.mjs +109 -0
- package/dist/chunk-U6QLDL3G.mjs +576 -0
- package/dist/{chunk-U4KT7QP3.cjs → chunk-ULASELLA.cjs} +26 -1
- package/dist/chunk-UXHS27O6.cjs +75 -0
- package/dist/{chunk-WWIKMBRN.mjs → chunk-VNGH5MLF.mjs} +17 -1
- package/dist/{chunk-EZDQRNQ7.mjs → chunk-VT4WFRHA.mjs} +23 -5
- package/dist/{chunk-CBJJH36A.cjs → chunk-VU6AAZVY.cjs} +20 -4
- package/dist/{chunk-27ZWSI3W.cjs → chunk-VXEEATVD.cjs} +2 -2
- package/dist/{chunk-EWET4D2Y.mjs → chunk-W36M2BQ4.mjs} +3 -3
- package/dist/{chunk-4WQ6PGSJ.cjs → chunk-WEW2JVA4.cjs} +4 -4
- package/dist/{chunk-4E5WBPEG.mjs → chunk-WFRT7JPX.mjs} +8 -533
- package/dist/{chunk-T4OGRVNS.mjs → chunk-WLL43JMO.mjs} +2 -2
- package/dist/chunk-WW46B6HA.cjs +318 -0
- package/dist/{chunk-TKSCR644.cjs → chunk-WXJLNP33.cjs} +2 -2
- package/dist/{chunk-S6VYG6XU.cjs → chunk-XKG2BLFN.cjs} +2 -2
- package/dist/{chunk-4NU4GGTC.cjs → chunk-XKVVMZP5.cjs} +6 -3
- package/dist/{chunk-NMHWYWDR.cjs → chunk-YR2VBEMO.cjs} +658 -526
- package/dist/{chunk-OHLSEQ57.mjs → chunk-ZJD2PN6Z.mjs} +10 -8
- package/dist/{chunk-3BU22U3M.cjs → chunk-ZXH4TS3F.cjs} +5 -2
- package/dist/{client-plugins-r1mOtSC1.d.ts → client-plugins-BvlNhGEB.d.ts} +54 -7
- package/dist/{client-plugins-C3mK9Pol.d.mts → client-plugins-DUrIYX9B.d.mts} +54 -7
- package/dist/client-plugins.d.mts +1 -1
- package/dist/client-plugins.d.ts +1 -1
- package/dist/client.cjs +8 -8
- package/dist/client.d.mts +5 -5
- package/dist/client.d.ts +5 -5
- package/dist/client.mjs +7 -7
- package/dist/config.d.mts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/{devtools-ERIKFEXX.mjs → devtools-JYJNOLPQ.mjs} +8 -6
- package/dist/{devtools-JZJJY5CK.cjs → devtools-VQWJANJV.cjs} +9 -7
- package/dist/docs.cjs +12 -10
- package/dist/docs.d.mts +20 -2
- package/dist/docs.d.ts +20 -2
- package/dist/docs.mjs +11 -9
- package/dist/headers.cjs +6 -4
- package/dist/headers.d.mts +11 -1
- package/dist/headers.d.ts +11 -1
- package/dist/headers.mjs +5 -3
- package/dist/i18n/client.cjs +11 -11
- package/dist/i18n/client.mjs +3 -3
- package/dist/index.cjs +62 -46
- package/dist/index.d.mts +16 -16
- package/dist/index.d.ts +16 -16
- package/dist/index.mjs +62 -46
- package/dist/integrations.cjs +5 -3
- package/dist/integrations.d.mts +1 -1
- package/dist/integrations.d.ts +1 -1
- package/dist/integrations.mjs +4 -2
- package/dist/internal/app-markdown-runtime.cjs +5 -3
- package/dist/internal/app-markdown-runtime.d.mts +19 -5
- package/dist/internal/app-markdown-runtime.d.ts +19 -5
- package/dist/internal/app-markdown-runtime.mjs +4 -2
- package/dist/internal/build-runtime.cjs +33 -30
- package/dist/internal/build-runtime.d.mts +3 -3
- package/dist/internal/build-runtime.d.ts +3 -3
- package/dist/internal/build-runtime.mjs +32 -29
- package/dist/internal/cli-runtime.cjs +14 -12
- package/dist/internal/cli-runtime.mjs +13 -11
- package/dist/internal/client-error-overlay.cjs +4 -4
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.cjs +2 -2
- package/dist/internal/client-runtime.mjs +1 -1
- package/dist/internal/compression-runtime.d.mts +1 -1
- package/dist/internal/compression-runtime.d.ts +1 -1
- package/dist/internal/config-runtime.cjs +9 -7
- package/dist/internal/config-runtime.d.mts +2 -2
- package/dist/internal/config-runtime.d.ts +2 -2
- package/dist/internal/config-runtime.mjs +8 -6
- package/dist/internal/docs-precompiled-runtime.cjs +19 -13
- package/dist/internal/docs-precompiled-runtime.d.mts +5 -0
- package/dist/internal/docs-precompiled-runtime.d.ts +5 -0
- package/dist/internal/docs-precompiled-runtime.mjs +14 -8
- package/dist/internal/infra-analytics-runtime.cjs +5 -5
- package/dist/internal/infra-analytics-runtime.mjs +3 -3
- package/dist/internal/product-telemetry-runtime.cjs +2 -2
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-node-env.cjs +6 -2
- package/dist/internal/production-node-env.d.mts +10 -1
- package/dist/internal/production-node-env.d.ts +10 -1
- package/dist/internal/production-node-env.mjs +5 -1
- package/dist/internal/production-runtime.cjs +39 -54
- package/dist/internal/production-runtime.d.mts +51 -11
- package/dist/internal/production-runtime.d.ts +51 -11
- package/dist/internal/production-runtime.mjs +39 -54
- package/dist/markdown.cjs +8 -2
- package/dist/markdown.d.mts +1 -1
- package/dist/markdown.d.ts +1 -1
- package/dist/markdown.mjs +7 -1
- package/dist/middleware.cjs +10 -8
- package/dist/middleware.d.mts +27 -5
- package/dist/middleware.d.ts +27 -5
- package/dist/middleware.mjs +10 -8
- package/dist/navigation.cjs +7 -7
- package/dist/navigation.d.mts +4 -4
- package/dist/navigation.d.ts +4 -4
- package/dist/navigation.mjs +6 -6
- package/dist/plugin.cjs +25 -23
- package/dist/plugin.d.mts +1 -1
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.mjs +24 -22
- package/dist/{production-runtime-CCeVZXst.d.mts → production-runtime-BQ4_WLwQ.d.mts} +1 -1
- package/dist/{production-runtime-DPnsggY3.d.ts → production-runtime-D2aMyzjr.d.ts} +1 -1
- package/dist/query/client.cjs +9 -9
- package/dist/query/client.mjs +4 -4
- package/dist/{render-plan-Cw4f5E_R.d.ts → render-plan-25p4hrj4.d.ts} +1 -1
- package/dist/{render-plan-BuGaPFe6.d.mts → render-plan-DtkXMN8D.d.mts} +1 -1
- package/dist/renderer-client.cjs +12 -12
- package/dist/renderer-client.d.mts +3 -3
- package/dist/renderer-client.d.ts +3 -3
- package/dist/renderer-client.mjs +4 -4
- package/dist/renderer.d.mts +13 -4
- package/dist/renderer.d.ts +13 -4
- package/dist/{request-CsGARcAw.d.mts → request-DgCkIdcn.d.mts} +4 -2
- package/dist/{request-Bkg-hERy.d.ts → request-jF4jwx8f.d.ts} +4 -2
- package/dist/request.cjs +3 -3
- package/dist/request.d.mts +2 -2
- package/dist/request.d.ts +2 -2
- package/dist/request.mjs +2 -2
- package/dist/{route-rendering-BUZMH_64.d.ts → route-rendering-Bji6S6a_.d.ts} +1 -1
- package/dist/{route-rendering-f11yh5dp.d.mts → route-rendering-CSBF78Ya.d.mts} +1 -1
- package/dist/{router-Cp6yRE8A.d.mts → router-B09Ui3Qm.d.mts} +1 -1
- package/dist/{router-B8CR9GbD.d.ts → router-CPB9cXtG.d.ts} +1 -1
- package/dist/routes.cjs +2 -2
- package/dist/routes.d.mts +1 -1
- package/dist/routes.d.ts +1 -1
- package/dist/routes.mjs +1 -1
- package/dist/{runtime-CAEv36S_.d.mts → runtime-CM6E6yuI.d.mts} +1 -1
- package/dist/{runtime-CQVsT330.d.ts → runtime-EDMwLdjv.d.ts} +1 -1
- package/dist/server-fn.cjs +3 -3
- package/dist/server-fn.mjs +2 -2
- package/dist/server-plugins.cjs +5 -5
- package/dist/server-plugins.d.mts +2 -2
- package/dist/server-plugins.d.ts +2 -2
- package/dist/server-plugins.mjs +4 -4
- package/dist/server-query.cjs +4 -4
- package/dist/server-query.mjs +3 -3
- package/dist/server.cjs +51 -49
- package/dist/server.d.mts +7 -7
- package/dist/server.d.ts +7 -7
- package/dist/server.mjs +29 -27
- package/dist/{spa-router-BuciWGCZ.d.ts → spa-router-B_N8XgVu.d.ts} +2 -2
- package/dist/{spa-router-DwbqGkGj.d.mts → spa-router-Cgimzfbi.d.mts} +2 -2
- package/dist/testing.cjs +8 -8
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.mjs +6 -6
- package/dist/theme/server.cjs +4 -4
- package/dist/theme/server.mjs +3 -3
- package/dist/{utils-CaoWKtYM.d.ts → utils-BNxAKAuT.d.ts} +1 -1
- package/dist/{utils-B9V0S_yL.d.mts → utils-DZciYXYl.d.mts} +1 -1
- package/dist/version.cjs +2 -2
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +25 -23
- package/dist/vite.d.mts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.mjs +24 -22
- package/package.json +1 -1
- package/types/middleware.d.ts +5 -1
- package/dist/chunk-655RLQQL.mjs +0 -43
- package/dist/chunk-FXEF4PPL.mjs +0 -47
- package/dist/chunk-IZY3V5XW.mjs +0 -23
- package/dist/chunk-MRMI32SN.cjs +0 -1157
- package/dist/chunk-MT763TDW.cjs +0 -43
- package/dist/chunk-XD32KALF.cjs +0 -47
- /package/dist/{chunk-SJNMVDDF.cjs → chunk-FUCSUGDM.cjs} +0 -0
- /package/dist/{chunk-UDNPLXW7.mjs → chunk-MYIZXDZA.mjs} +0 -0
|
@@ -2,25 +2,32 @@ import {
|
|
|
2
2
|
loadFarmProductionVite
|
|
3
3
|
} from "./chunk-S3FNNQHR.mjs";
|
|
4
4
|
import {
|
|
5
|
+
FARM_NODE_ENV_MODULE_FILE,
|
|
6
|
+
FARM_NODE_ENV_MODULE_SOURCE,
|
|
7
|
+
createFarmNodeServerEntry,
|
|
5
8
|
withProductionNodeEnv
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6BK3K2GB.mjs";
|
|
7
10
|
import {
|
|
8
|
-
generateNativeMCPPluginSource
|
|
9
|
-
|
|
11
|
+
generateNativeMCPPluginSource,
|
|
12
|
+
layoutsCanCoverSamePage
|
|
13
|
+
} from "./chunk-TYMMBFN2.mjs";
|
|
10
14
|
import {
|
|
15
|
+
assertFarmDocsAdapterServesNoGuardedPages,
|
|
11
16
|
compileFarmDocsAdapterEdgeManifest,
|
|
12
|
-
createFarmDocsAPIHandler
|
|
13
|
-
|
|
17
|
+
createFarmDocsAPIHandler,
|
|
18
|
+
hasFarmDocsRuntimeAdapter
|
|
19
|
+
} from "./chunk-A3EAIURZ.mjs";
|
|
14
20
|
import {
|
|
15
21
|
FARM_DOCS_LAST_MODIFIED_MANIFEST,
|
|
16
22
|
createFarmDocsHandler,
|
|
17
23
|
createFarmDocsLastModifiedManifest,
|
|
18
24
|
discoverFarmDocsPages,
|
|
25
|
+
getFarmDocsMarkdownPath,
|
|
19
26
|
getFarmDocsRouteTypeEntries,
|
|
20
27
|
loadFarmDocsPage,
|
|
21
28
|
resolveFarmDocsContentDir,
|
|
22
29
|
toFarmDocsMarkdownPage
|
|
23
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5BWWFHR2.mjs";
|
|
24
31
|
import {
|
|
25
32
|
generateFarmDocsSearchClientRuntime,
|
|
26
33
|
isFarmDocsSearchEnabled,
|
|
@@ -28,7 +35,7 @@ import {
|
|
|
28
35
|
} from "./chunk-UP4CW6WP.mjs";
|
|
29
36
|
import {
|
|
30
37
|
FARM_PRERENDER_ENV
|
|
31
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-BZHXGVMA.mjs";
|
|
32
39
|
import {
|
|
33
40
|
loadFarmDocsEngine
|
|
34
41
|
} from "./chunk-2VQKKQ6D.mjs";
|
|
@@ -37,7 +44,7 @@ import {
|
|
|
37
44
|
getDeployTargetForPreset,
|
|
38
45
|
hasCustomFarmRouteContext,
|
|
39
46
|
resolveDeployOutputPath
|
|
40
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-ZJD2PN6Z.mjs";
|
|
41
48
|
import {
|
|
42
49
|
resolveFarmInstrumentationFile
|
|
43
50
|
} from "./chunk-ZZSRYEYU.mjs";
|
|
@@ -76,30 +83,34 @@ import {
|
|
|
76
83
|
resolveFarmIsolatedClientHydrationMode,
|
|
77
84
|
resolveFarmNotFoundComponentPath,
|
|
78
85
|
usesFarmServerTree
|
|
79
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-TUBTR2OP.mjs";
|
|
80
87
|
import {
|
|
81
88
|
findRequestBoundSourceBlockers,
|
|
82
89
|
generateFarmTypeArtifacts,
|
|
83
90
|
parseRouteRenderingDirective,
|
|
84
91
|
resolveRouteRenderingConfigFromFile
|
|
85
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-CQMVIOYP.mjs";
|
|
86
93
|
import {
|
|
87
94
|
FARM_API_CATALOG_PATH,
|
|
88
95
|
FARM_APP_MANIFEST_LEGACY_PATH,
|
|
89
96
|
FARM_APP_MANIFEST_PATH,
|
|
90
97
|
HOISTED_HEAD_ELEMENT,
|
|
98
|
+
appMiddlewareMayHandlePath,
|
|
99
|
+
configMiddlewareMayHandlePath,
|
|
100
|
+
farmPathGuardCoversPage,
|
|
91
101
|
getRouteDirectoryDepth,
|
|
92
102
|
getRouteGroupScope,
|
|
103
|
+
hasFarmMiddlewareConfig,
|
|
93
104
|
resolveFarmApiCatalogInput,
|
|
94
105
|
resolveFarmAppManifestInput,
|
|
95
106
|
routeBoundaryCoversDirectory,
|
|
96
107
|
stripRouteGroups
|
|
97
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-B6G5CKMC.mjs";
|
|
98
109
|
import {
|
|
99
110
|
FARM_DEFAULT_MCP_PATH,
|
|
100
111
|
createFarmDefaultMCPServer,
|
|
101
112
|
farmConfigMountsMCP
|
|
102
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-P664ZVTV.mjs";
|
|
103
114
|
import {
|
|
104
115
|
isFarmPreviewDeploymentEnvironment
|
|
105
116
|
} from "./chunk-BOYNDCZL.mjs";
|
|
@@ -109,7 +120,7 @@ import {
|
|
|
109
120
|
import {
|
|
110
121
|
generateFarmDocsAdapterClientRuntime,
|
|
111
122
|
getFarmDocsAdapterConfigModule
|
|
112
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-J7K2NZD6.mjs";
|
|
113
124
|
import {
|
|
114
125
|
resolveFarmDocsFontAssets,
|
|
115
126
|
toFarmDocsPublicFontAssets
|
|
@@ -130,8 +141,9 @@ import {
|
|
|
130
141
|
resolveFarmRendererAppSetup
|
|
131
142
|
} from "./chunk-DAATZTKJ.mjs";
|
|
132
143
|
import {
|
|
133
|
-
applyFarmCspHashesToHtml
|
|
134
|
-
|
|
144
|
+
applyFarmCspHashesToHtml,
|
|
145
|
+
createFarmCspNonce
|
|
146
|
+
} from "./chunk-U6QLDL3G.mjs";
|
|
135
147
|
import {
|
|
136
148
|
applyFarmCronVercelCrons,
|
|
137
149
|
createFarmCronCloudflareConfig,
|
|
@@ -143,14 +155,14 @@ import {
|
|
|
143
155
|
} from "./chunk-4OOBRCJX.mjs";
|
|
144
156
|
import {
|
|
145
157
|
isFarmMarkdownPageFile
|
|
146
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-QFW2IH5E.mjs";
|
|
147
159
|
import {
|
|
148
160
|
resolveFarmMdxComponentsModulePath,
|
|
149
161
|
resolveMdxConfig
|
|
150
162
|
} from "./chunk-FA2W42OV.mjs";
|
|
151
163
|
import {
|
|
152
164
|
getFarmMarkdownAlternatePath
|
|
153
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-VNGH5MLF.mjs";
|
|
154
166
|
import {
|
|
155
167
|
applyFarmWorkflowVercelCrons,
|
|
156
168
|
prepareFarmWorkflowsForNitro
|
|
@@ -159,20 +171,15 @@ import {
|
|
|
159
171
|
FARM_INTEGRATION_API_BASE_PATH_KEY,
|
|
160
172
|
getFarmIntegrationPluginServerRuntime,
|
|
161
173
|
getIntegrationProviders
|
|
162
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-IBUQWVYA.mjs";
|
|
163
175
|
import {
|
|
164
176
|
appendMiddlewareDirectory,
|
|
165
177
|
appendMiddlewareRoutePath,
|
|
166
178
|
compareMiddlewareRouteLocations
|
|
167
|
-
} from "./chunk-
|
|
168
|
-
import {
|
|
169
|
-
compileMiddlewareConfig,
|
|
170
|
-
matchesCompiledMiddlewareConfig,
|
|
171
|
-
matchesMiddlewareRoute
|
|
172
|
-
} from "./chunk-JG6DJF5A.mjs";
|
|
179
|
+
} from "./chunk-JCKYH4LG.mjs";
|
|
173
180
|
import {
|
|
174
181
|
APIRouteManager
|
|
175
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-WLL43JMO.mjs";
|
|
176
183
|
import {
|
|
177
184
|
readFarmI18nCatalogs
|
|
178
185
|
} from "./chunk-QCFBDFRS.mjs";
|
|
@@ -199,10 +206,13 @@ import {
|
|
|
199
206
|
} from "./chunk-BTHHUD7Q.mjs";
|
|
200
207
|
import {
|
|
201
208
|
FARM_VERSION
|
|
202
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-LI2F57NI.mjs";
|
|
203
210
|
import {
|
|
204
211
|
getFarmPresetRuntime
|
|
205
212
|
} from "./chunk-2A3EQHXX.mjs";
|
|
213
|
+
import {
|
|
214
|
+
_runWithFarmCspNonce
|
|
215
|
+
} from "./chunk-POSPE3IO.mjs";
|
|
206
216
|
import {
|
|
207
217
|
compareRoutePatternSpecificity
|
|
208
218
|
} from "./chunk-55YI3RRB.mjs";
|
|
@@ -211,7 +221,7 @@ import {
|
|
|
211
221
|
} from "./chunk-LPEX4YW6.mjs";
|
|
212
222
|
|
|
213
223
|
// src/build/index.ts
|
|
214
|
-
import
|
|
224
|
+
import path9 from "path";
|
|
215
225
|
import { existsSync as existsSync3 } from "fs";
|
|
216
226
|
|
|
217
227
|
// src/nitro/client-css-href.ts
|
|
@@ -219,15 +229,15 @@ import path from "path";
|
|
|
219
229
|
var FARM_CLIENT_CSS_HREF_PLACEHOLDER = "/__farm_client_css_href__";
|
|
220
230
|
var FARM_CLIENT_JS_SRC_PLACEHOLDER = "/__farm_client_js_src__";
|
|
221
231
|
async function hashAndCopy(sourcePath, destinationDir, hashedName) {
|
|
222
|
-
const
|
|
232
|
+
const fs3 = await import("fs/promises");
|
|
223
233
|
try {
|
|
224
|
-
const bytes = await
|
|
234
|
+
const bytes = await fs3.readFile(sourcePath);
|
|
225
235
|
if (bytes.length === 0) return null;
|
|
226
236
|
const { createHash } = await import("crypto");
|
|
227
237
|
const hash = createHash("sha256").update(bytes).digest("hex").slice(0, 8);
|
|
228
238
|
const name = hashedName(hash);
|
|
229
|
-
await
|
|
230
|
-
await
|
|
239
|
+
await fs3.mkdir(destinationDir, { recursive: true });
|
|
240
|
+
await fs3.writeFile(path.join(destinationDir, name), bytes);
|
|
231
241
|
return name;
|
|
232
242
|
} catch {
|
|
233
243
|
return null;
|
|
@@ -244,9 +254,9 @@ async function resolveHashedClientCssHref(clientOutputDir) {
|
|
|
244
254
|
}
|
|
245
255
|
__name(resolveHashedClientCssHref, "resolveHashedClientCssHref");
|
|
246
256
|
async function findFingerprintedClientEntry(clientOutputDir) {
|
|
247
|
-
const
|
|
257
|
+
const fs3 = await import("fs/promises");
|
|
248
258
|
try {
|
|
249
|
-
const entries = await
|
|
259
|
+
const entries = await fs3.readdir(clientOutputDir);
|
|
250
260
|
return entries.find((name) => /^farm-client-h[0-9a-f]+\.js$/.test(name)) ?? null;
|
|
251
261
|
} catch {
|
|
252
262
|
return null;
|
|
@@ -256,17 +266,17 @@ __name(findFingerprintedClientEntry, "findFingerprintedClientEntry");
|
|
|
256
266
|
async function resolveHashedClientJsSrc(clientOutputDir) {
|
|
257
267
|
const entryName = await findFingerprintedClientEntry(clientOutputDir);
|
|
258
268
|
if (!entryName) return "/farm-client.js";
|
|
259
|
-
const
|
|
269
|
+
const fs3 = await import("fs/promises");
|
|
260
270
|
const shim = `export * from "./${entryName}";
|
|
261
271
|
`;
|
|
262
|
-
await
|
|
272
|
+
await fs3.writeFile(path.join(clientOutputDir, "farm-client.js"), shim);
|
|
263
273
|
return `/${entryName}`;
|
|
264
274
|
}
|
|
265
275
|
__name(resolveHashedClientJsSrc, "resolveHashedClientJsSrc");
|
|
266
276
|
|
|
267
277
|
// src/nitro/universal-build.ts
|
|
268
278
|
import os from "os";
|
|
269
|
-
import
|
|
279
|
+
import path8 from "path";
|
|
270
280
|
import { constants as fsConstants, existsSync as existsSync2, readFileSync, realpathSync, statSync } from "fs";
|
|
271
281
|
import { fileURLToPath } from "url";
|
|
272
282
|
import { builtinModules, createRequire } from "module";
|
|
@@ -342,18 +352,21 @@ async function compileFarmDocsManifest(docs, options) {
|
|
|
342
352
|
clientEntry: options.clientEntry,
|
|
343
353
|
fontAssets: options.fontAssets,
|
|
344
354
|
fontStylesheetHref: options.fontStylesheetHref,
|
|
345
|
-
globalStylesheetHref: options.globalStylesheetHref
|
|
355
|
+
globalStylesheetHref: options.globalStylesheetHref,
|
|
356
|
+
isPathGuarded: options.isPathGuarded
|
|
346
357
|
});
|
|
347
358
|
const apiHandler = createFarmDocsAPIHandler({
|
|
348
359
|
rootDir: options.root,
|
|
349
360
|
srcDir: options.srcDir,
|
|
350
|
-
docs
|
|
361
|
+
docs,
|
|
362
|
+
isPathGuarded: options.isPathGuarded
|
|
351
363
|
});
|
|
364
|
+
const publicPages = pages.filter((page) => !options.isPathGuarded?.(page.href));
|
|
352
365
|
const routes = {};
|
|
353
366
|
const apiMarkdown = {};
|
|
354
367
|
for (const page of pages) {
|
|
355
368
|
const htmlResponse = await addHandlerRoute(routes, page.href, handler, absolutePaths);
|
|
356
|
-
const markdownPath = page.href
|
|
369
|
+
const markdownPath = getFarmDocsMarkdownPath(page.href);
|
|
357
370
|
await addHandlerRoute(routes, markdownPath, handler, absolutePaths);
|
|
358
371
|
if (htmlResponse) {
|
|
359
372
|
const socialImagePath = findSocialImagePath(await htmlResponse.text());
|
|
@@ -361,6 +374,7 @@ async function compileFarmDocsManifest(docs, options) {
|
|
|
361
374
|
await addHandlerRoute(routes, socialImagePath, handler, absolutePaths);
|
|
362
375
|
}
|
|
363
376
|
}
|
|
377
|
+
if (options.isPathGuarded?.(page.href)) continue;
|
|
364
378
|
const apiResponse = await apiHandler(
|
|
365
379
|
new Request(
|
|
366
380
|
`${FARM_DOCS_COMPILED_ORIGIN}/api/docs?format=markdown&path=${encodeURIComponent(page.slug)}`
|
|
@@ -435,7 +449,7 @@ async function compileFarmDocsManifest(docs, options) {
|
|
|
435
449
|
empty: await compileResponse(emptyResponse, absolutePaths),
|
|
436
450
|
post: await compileResponse(postResponse, absolutePaths),
|
|
437
451
|
search: {
|
|
438
|
-
pages:
|
|
452
|
+
pages: publicPages.map((page) => ({
|
|
439
453
|
...toFarmDocsMarkdownPage(page),
|
|
440
454
|
sourcePath: `farm-docs:${page.slug || "index"}`
|
|
441
455
|
})),
|
|
@@ -448,11 +462,179 @@ async function compileFarmDocsManifest(docs, options) {
|
|
|
448
462
|
}
|
|
449
463
|
__name(compileFarmDocsManifest, "compileFarmDocsManifest");
|
|
450
464
|
|
|
451
|
-
// src/
|
|
465
|
+
// src/nitro/client-module-preloads.ts
|
|
466
|
+
import fs from "fs/promises";
|
|
452
467
|
import path3 from "path";
|
|
468
|
+
var FARM_CLIENT_MODULE_PRELOADS_PLACEHOLDER = "__farm_client_module_preloads__";
|
|
469
|
+
var FARM_CLIENT_MODULE_PRELOADS_FILE = "client-module-preloads.json";
|
|
470
|
+
function collectFarmClientModulePreloads(bundle, options) {
|
|
471
|
+
const chunks = Object.values(bundle).filter(
|
|
472
|
+
(output) => output.type === "chunk"
|
|
473
|
+
);
|
|
474
|
+
const entry = chunks.find((chunk) => chunk.isEntry && chunk.name === options.entryName);
|
|
475
|
+
if (!entry) return null;
|
|
476
|
+
const byFile = new Map(chunks.map((chunk) => [chunk.fileName, chunk]));
|
|
477
|
+
const files = [];
|
|
478
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
479
|
+
const index = /* @__PURE__ */ __name((fileName) => {
|
|
480
|
+
let value = indexOf.get(fileName);
|
|
481
|
+
if (value === void 0) {
|
|
482
|
+
value = files.push(fileName) - 1;
|
|
483
|
+
indexOf.set(fileName, value);
|
|
484
|
+
}
|
|
485
|
+
return value;
|
|
486
|
+
}, "index");
|
|
487
|
+
const staticImports = /* @__PURE__ */ __name((chunk, loaded, into) => {
|
|
488
|
+
for (const fileName of chunk.imports ?? []) {
|
|
489
|
+
const imported = byFile.get(fileName);
|
|
490
|
+
if (loaded.has(fileName) || !imported) continue;
|
|
491
|
+
loaded.add(fileName);
|
|
492
|
+
into.push(fileName);
|
|
493
|
+
staticImports(imported, loaded, into);
|
|
494
|
+
}
|
|
495
|
+
return into;
|
|
496
|
+
}, "staticImports");
|
|
497
|
+
const entryFiles = staticImports(entry, /* @__PURE__ */ new Set([entry.fileName]), []);
|
|
498
|
+
const entryLoaded = /* @__PURE__ */ new Set([entry.fileName, ...entryFiles]);
|
|
499
|
+
const modules = {};
|
|
500
|
+
for (const chunk of chunks) {
|
|
501
|
+
if (!chunk.isDynamicEntry || !chunk.facadeModuleId || entryLoaded.has(chunk.fileName)) {
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
const moduleId = chunk.facadeModuleId.split("?")[0];
|
|
505
|
+
if (!path3.isAbsolute(moduleId)) continue;
|
|
506
|
+
const loaded = /* @__PURE__ */ new Set([...entryLoaded, chunk.fileName]);
|
|
507
|
+
modules[toViteModuleId(moduleId, options.root)] = [
|
|
508
|
+
chunk.fileName,
|
|
509
|
+
...staticImports(chunk, loaded, [])
|
|
510
|
+
].map(index);
|
|
511
|
+
}
|
|
512
|
+
return { files, entry: entryFiles.map(index), modules };
|
|
513
|
+
}
|
|
514
|
+
__name(collectFarmClientModulePreloads, "collectFarmClientModulePreloads");
|
|
515
|
+
function createFarmClientModulePreloadPlugin(options) {
|
|
516
|
+
return {
|
|
517
|
+
name: "farm-client-module-preloads",
|
|
518
|
+
async generateBundle(_output, bundle) {
|
|
519
|
+
await fs.mkdir(options.buildDir, { recursive: true });
|
|
520
|
+
await fs.writeFile(
|
|
521
|
+
path3.join(options.buildDir, FARM_CLIENT_MODULE_PRELOADS_FILE),
|
|
522
|
+
JSON.stringify(collectFarmClientModulePreloads(bundle, options))
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
__name(createFarmClientModulePreloadPlugin, "createFarmClientModulePreloadPlugin");
|
|
528
|
+
async function readFarmClientModulePreloads(buildDir) {
|
|
529
|
+
try {
|
|
530
|
+
return JSON.parse(
|
|
531
|
+
await fs.readFile(path3.join(buildDir, FARM_CLIENT_MODULE_PRELOADS_FILE), "utf8")
|
|
532
|
+
);
|
|
533
|
+
} catch {
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
__name(readFarmClientModulePreloads, "readFarmClientModulePreloads");
|
|
538
|
+
function encodeFarmClientModulePreloads(manifest) {
|
|
539
|
+
return JSON.stringify(JSON.stringify(manifest)).slice(1, -1).replace(/'/g, "\\u0027").replace(/`/g, "\\u0060").replace(/\$/g, "\\u0024").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
540
|
+
}
|
|
541
|
+
__name(encodeFarmClientModulePreloads, "encodeFarmClientModulePreloads");
|
|
542
|
+
|
|
543
|
+
// src/docs/module-preloads.ts
|
|
544
|
+
import fs2 from "fs/promises";
|
|
545
|
+
import path4 from "path";
|
|
546
|
+
var FARM_DOCS_MODULE_PRELOADS_PLACEHOLDER = "__farm_docs_module_preloads__";
|
|
547
|
+
var FARM_DOCS_MODULE_PRELOADS_FILE = "docs-module-preloads.json";
|
|
548
|
+
function normalizeModuleId(id) {
|
|
549
|
+
return id.split("?")[0].replace(/\\/g, "/");
|
|
550
|
+
}
|
|
551
|
+
__name(normalizeModuleId, "normalizeModuleId");
|
|
552
|
+
function collectFarmDocsModulePreloads(bundle, options) {
|
|
553
|
+
const chunks = Object.values(bundle).filter(
|
|
554
|
+
(output) => output.type === "chunk"
|
|
555
|
+
);
|
|
556
|
+
const byFile = new Map(chunks.map((chunk) => [chunk.fileName, chunk]));
|
|
557
|
+
const byModule = new Map(
|
|
558
|
+
chunks.filter((chunk) => chunk.facadeModuleId).map((chunk) => [normalizeModuleId(chunk.facadeModuleId), chunk])
|
|
559
|
+
);
|
|
560
|
+
const withStaticImports = /* @__PURE__ */ __name((fileName, into) => {
|
|
561
|
+
if (into.has(fileName) || !byFile.has(fileName)) return into;
|
|
562
|
+
into.add(fileName);
|
|
563
|
+
for (const imported of byFile.get(fileName).imports ?? []) withStaticImports(imported, into);
|
|
564
|
+
return into;
|
|
565
|
+
}, "withStaticImports");
|
|
566
|
+
const runtimeChunks = options.runtimeModuleIds.map((id) => byModule.get(normalizeModuleId(id))).filter((chunk) => Boolean(chunk));
|
|
567
|
+
const entry = chunks.find((chunk) => chunk.isEntry && chunk.name === options.entryName);
|
|
568
|
+
if (!entry || runtimeChunks.length === 0) return null;
|
|
569
|
+
const runtime = withStaticImports(entry.fileName, /* @__PURE__ */ new Set());
|
|
570
|
+
for (const chunk of runtimeChunks) withStaticImports(chunk.fileName, runtime);
|
|
571
|
+
const files = [];
|
|
572
|
+
const indexOf = /* @__PURE__ */ new Map();
|
|
573
|
+
const index = /* @__PURE__ */ __name((fileName) => {
|
|
574
|
+
let value = indexOf.get(fileName);
|
|
575
|
+
if (value === void 0) {
|
|
576
|
+
value = files.push(fileName) - 1;
|
|
577
|
+
indexOf.set(fileName, value);
|
|
578
|
+
}
|
|
579
|
+
return value;
|
|
580
|
+
}, "index");
|
|
581
|
+
const pages = {};
|
|
582
|
+
const root = normalizeModuleId(path4.resolve(options.root));
|
|
583
|
+
for (const [moduleId, chunk] of byModule) {
|
|
584
|
+
if (!/\.mdx?$/.test(moduleId) || !moduleId.startsWith(`${root}/`)) continue;
|
|
585
|
+
const own = [...withStaticImports(chunk.fileName, /* @__PURE__ */ new Set())].filter(
|
|
586
|
+
(fileName) => !runtime.has(fileName)
|
|
587
|
+
);
|
|
588
|
+
pages[moduleId.slice(root.length)] = own.map(index);
|
|
589
|
+
}
|
|
590
|
+
return { files, runtime: [...runtime].map(index), pages };
|
|
591
|
+
}
|
|
592
|
+
__name(collectFarmDocsModulePreloads, "collectFarmDocsModulePreloads");
|
|
593
|
+
function createFarmDocsModulePreloadPlugin(options) {
|
|
594
|
+
let runtimeModuleIds = [];
|
|
595
|
+
return {
|
|
596
|
+
name: "farm-docs-module-preloads",
|
|
597
|
+
async buildStart() {
|
|
598
|
+
const resolved = await Promise.all(
|
|
599
|
+
options.modules.map((specifier) => this.resolve(specifier, options.importer))
|
|
600
|
+
);
|
|
601
|
+
runtimeModuleIds = resolved.filter((value) => value !== null).map((value) => value.id);
|
|
602
|
+
},
|
|
603
|
+
async generateBundle(_output, bundle) {
|
|
604
|
+
const manifest = collectFarmDocsModulePreloads(bundle, {
|
|
605
|
+
root: options.root,
|
|
606
|
+
entryName: options.entryName,
|
|
607
|
+
runtimeModuleIds
|
|
608
|
+
});
|
|
609
|
+
await fs2.mkdir(options.buildDir, { recursive: true });
|
|
610
|
+
await fs2.writeFile(
|
|
611
|
+
path4.join(options.buildDir, FARM_DOCS_MODULE_PRELOADS_FILE),
|
|
612
|
+
JSON.stringify(manifest)
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
__name(createFarmDocsModulePreloadPlugin, "createFarmDocsModulePreloadPlugin");
|
|
618
|
+
async function readFarmDocsModulePreloads(buildDir) {
|
|
619
|
+
try {
|
|
620
|
+
return JSON.parse(
|
|
621
|
+
await fs2.readFile(path4.join(buildDir, FARM_DOCS_MODULE_PRELOADS_FILE), "utf8")
|
|
622
|
+
);
|
|
623
|
+
} catch {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
__name(readFarmDocsModulePreloads, "readFarmDocsModulePreloads");
|
|
628
|
+
function encodeFarmDocsModulePreloads(manifest) {
|
|
629
|
+
return JSON.stringify(JSON.stringify(manifest)).slice(1, -1).replace(/'/g, "\\u0027").replace(/`/g, "\\u0060").replace(/\$/g, "\\u0024").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
630
|
+
}
|
|
631
|
+
__name(encodeFarmDocsModulePreloads, "encodeFarmDocsModulePreloads");
|
|
632
|
+
|
|
633
|
+
// src/route-runtime-manifest.ts
|
|
634
|
+
import path5 from "path";
|
|
453
635
|
var FARM_ROUTE_RUNTIME_MANIFEST = "route-runtime-manifest.json";
|
|
454
636
|
async function createFarmRouteRuntimeManifest(options) {
|
|
455
|
-
const root =
|
|
637
|
+
const root = path5.resolve(options.root || options.config.root || process.cwd());
|
|
456
638
|
const routes = [];
|
|
457
639
|
for (const [pattern, entry] of options.routeManager.getRoutes()) {
|
|
458
640
|
const routeModule = await options.routeManager.loadRouteModule(entry.modulePath);
|
|
@@ -522,10 +704,10 @@ async function createFarmRouteRuntimeManifest(options) {
|
|
|
522
704
|
}
|
|
523
705
|
__name(createFarmRouteRuntimeManifest, "createFarmRouteRuntimeManifest");
|
|
524
706
|
async function writeFarmRouteRuntimeManifest(directory, manifest) {
|
|
525
|
-
const
|
|
526
|
-
const manifestPath =
|
|
527
|
-
await
|
|
528
|
-
await
|
|
707
|
+
const fs3 = await import("fs/promises");
|
|
708
|
+
const manifestPath = path5.join(directory, FARM_ROUTE_RUNTIME_MANIFEST);
|
|
709
|
+
await fs3.mkdir(directory, { recursive: true });
|
|
710
|
+
await fs3.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
529
711
|
`);
|
|
530
712
|
return manifestPath;
|
|
531
713
|
}
|
|
@@ -563,14 +745,14 @@ function normalizeManifestSource(root, modulePath) {
|
|
|
563
745
|
const queryIndex = modulePath.indexOf("?");
|
|
564
746
|
const filePath = queryIndex === -1 ? modulePath : modulePath.slice(0, queryIndex);
|
|
565
747
|
const query = queryIndex === -1 ? "" : modulePath.slice(queryIndex);
|
|
566
|
-
const relativePath =
|
|
748
|
+
const relativePath = path5.isAbsolute(filePath) ? path5.relative(root, filePath) : filePath;
|
|
567
749
|
return `${relativePath.replace(/\\/g, "/")}${query}`;
|
|
568
750
|
}
|
|
569
751
|
__name(normalizeManifestSource, "normalizeManifestSource");
|
|
570
752
|
|
|
571
753
|
// src/nitro/vercel-route-runtime.ts
|
|
572
|
-
import
|
|
573
|
-
async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest,
|
|
754
|
+
import path6 from "path";
|
|
755
|
+
async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs3, basePath = "/") {
|
|
574
756
|
const dynamicRoutes = manifest.routes.filter(
|
|
575
757
|
(route) => route.rendering === "dynamic" && route.runtime !== "edge"
|
|
576
758
|
);
|
|
@@ -589,8 +771,8 @@ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs, ba
|
|
|
589
771
|
group.routes.push(route);
|
|
590
772
|
groups.set(key, group);
|
|
591
773
|
}
|
|
592
|
-
const functionsDir =
|
|
593
|
-
const baseFunctionDir =
|
|
774
|
+
const functionsDir = path6.join(outputDir, "functions");
|
|
775
|
+
const baseFunctionDir = path6.join(functionsDir, "__nitro.func");
|
|
594
776
|
const destinations = /* @__PURE__ */ new Map();
|
|
595
777
|
let groupIndex = 0;
|
|
596
778
|
for (const [key, group] of groups) {
|
|
@@ -600,9 +782,9 @@ async function createFarmVercelRouteRuntimeFunctions(outputDir, manifest, fs, ba
|
|
|
600
782
|
}
|
|
601
783
|
groupIndex += 1;
|
|
602
784
|
const functionName = `__farm_runtime_${groupIndex}`;
|
|
603
|
-
const functionDir =
|
|
604
|
-
await
|
|
605
|
-
await configureVercelFunction(functionDir, group.config,
|
|
785
|
+
const functionDir = path6.join(functionsDir, `${functionName}.func`);
|
|
786
|
+
await fs3.cp(baseFunctionDir, functionDir, { recursive: true, force: true });
|
|
787
|
+
await configureVercelFunction(functionDir, group.config, fs3);
|
|
606
788
|
destinations.set(key, `/${functionName}`);
|
|
607
789
|
}
|
|
608
790
|
const routes = [];
|
|
@@ -651,15 +833,15 @@ function farmRoutePatternToVercelSource(pattern, basePath = "/") {
|
|
|
651
833
|
return source === "/" ? normalizedBasePath : `${normalizedBasePath}${source}`;
|
|
652
834
|
}
|
|
653
835
|
__name(farmRoutePatternToVercelSource, "farmRoutePatternToVercelSource");
|
|
654
|
-
async function configureVercelFunction(functionDir, config,
|
|
655
|
-
const configPath =
|
|
656
|
-
const current = JSON.parse(await
|
|
836
|
+
async function configureVercelFunction(functionDir, config, fs3) {
|
|
837
|
+
const configPath = path6.join(functionDir, ".vc-config.json");
|
|
838
|
+
const current = JSON.parse(await fs3.readFile(configPath, "utf8"));
|
|
657
839
|
const next = {
|
|
658
840
|
...current,
|
|
659
841
|
...config.regions?.length ? { regions: config.regions } : {},
|
|
660
842
|
...config.maxDuration ? { maxDuration: config.maxDuration } : {}
|
|
661
843
|
};
|
|
662
|
-
await
|
|
844
|
+
await fs3.writeFile(configPath, `${JSON.stringify(next, null, 2)}
|
|
663
845
|
`);
|
|
664
846
|
}
|
|
665
847
|
__name(configureVercelFunction, "configureVercelFunction");
|
|
@@ -736,10 +918,10 @@ __name(buildFarmVercelRoutes, "buildFarmVercelRoutes");
|
|
|
736
918
|
|
|
737
919
|
// src/nitro/netlify-entry.ts
|
|
738
920
|
import { existsSync } from "fs";
|
|
739
|
-
import
|
|
921
|
+
import path7 from "path";
|
|
740
922
|
function resolveNitroNetlifyEntry(nitroRuntimeEntry) {
|
|
741
|
-
const entry =
|
|
742
|
-
|
|
923
|
+
const entry = path7.join(
|
|
924
|
+
path7.dirname(nitroRuntimeEntry),
|
|
743
925
|
"..",
|
|
744
926
|
"presets",
|
|
745
927
|
"netlify",
|
|
@@ -751,7 +933,7 @@ function resolveNitroNetlifyEntry(nitroRuntimeEntry) {
|
|
|
751
933
|
`[Farm.js] Could not find Nitro's Netlify function entry at ${entry}. Farm wraps it so private responses are never cached by Netlify's CDN; reinstall dependencies or report the installed Nitro version.`
|
|
752
934
|
);
|
|
753
935
|
}
|
|
754
|
-
return entry.split(
|
|
936
|
+
return entry.split(path7.sep).join("/");
|
|
755
937
|
}
|
|
756
938
|
__name(resolveNitroNetlifyEntry, "resolveNitroNetlifyEntry");
|
|
757
939
|
function createFarmNetlifyEntry(options) {
|
|
@@ -759,15 +941,32 @@ function createFarmNetlifyEntry(options) {
|
|
|
759
941
|
import nitroNetlifyHandler from ${JSON.stringify(options.nitroNetlifyEntry)};
|
|
760
942
|
|
|
761
943
|
const PRIVATE_CACHE_DIRECTIVE = /(?:^|,)\\s*(?:private|no-store)\\s*(?:[,=]|$)/i;
|
|
944
|
+
const CREDENTIAL_VARY = /(?:^|,)\\s*(?:\\*|cookie|authorization)\\s*(?:,|$)/i;
|
|
945
|
+
// What Nitro's entry sets when the response has no Cache-Control of its own.
|
|
946
|
+
const NITRO_DEFAULT_CACHE_CONTROL = "public, max-age=0, must-revalidate";
|
|
947
|
+
|
|
948
|
+
function isSharedCacheable(request, response) {
|
|
949
|
+
return (
|
|
950
|
+
response.status === 200 &&
|
|
951
|
+
!request.headers.has("cookie") &&
|
|
952
|
+
!request.headers.has("authorization") &&
|
|
953
|
+
!response.headers.has("set-cookie") &&
|
|
954
|
+
!PRIVATE_CACHE_DIRECTIVE.test(response.headers.get("cache-control") || "") &&
|
|
955
|
+
!CREDENTIAL_VARY.test(response.headers.get("vary") || "")
|
|
956
|
+
);
|
|
957
|
+
}
|
|
762
958
|
|
|
763
959
|
export default async function farmNetlifyHandler(request, context) {
|
|
764
960
|
const response = await nitroNetlifyHandler(request, context);
|
|
765
961
|
if (
|
|
766
962
|
response &&
|
|
767
963
|
response.headers.has("netlify-cdn-cache-control") &&
|
|
768
|
-
|
|
964
|
+
!isSharedCacheable(request, response)
|
|
769
965
|
) {
|
|
770
966
|
response.headers.delete("netlify-cdn-cache-control");
|
|
967
|
+
if (response.headers.get("cache-control") === NITRO_DEFAULT_CACHE_CONTROL) {
|
|
968
|
+
response.headers.set("cache-control", "private, no-store");
|
|
969
|
+
}
|
|
771
970
|
}
|
|
772
971
|
return response;
|
|
773
972
|
}
|
|
@@ -775,278 +974,6 @@ export default async function farmNetlifyHandler(request, context) {
|
|
|
775
974
|
}
|
|
776
975
|
__name(createFarmNetlifyEntry, "createFarmNetlifyEntry");
|
|
777
976
|
|
|
778
|
-
// src/nitro/node-server-entry.ts
|
|
779
|
-
var FARM_NODE_ENV_MODULE_FILE = "farm-node-env.mjs";
|
|
780
|
-
var FARM_NODE_ENV_MODULE_SOURCE = `if (!process.env.NODE_ENV) process.env.NODE_ENV = "production";
|
|
781
|
-
`;
|
|
782
|
-
function createFarmNodeServerEntry(options) {
|
|
783
|
-
const serverConfig = JSON.stringify(options.server);
|
|
784
|
-
const nitroEntryImport = `./${options.nitroEntryFile.replace(/^\.\//, "")}`;
|
|
785
|
-
return `
|
|
786
|
-
import "./${FARM_NODE_ENV_MODULE_FILE}";
|
|
787
|
-
import "#nitro/virtual/polyfills";
|
|
788
|
-
import { NodeRequest, serve } from ${JSON.stringify(options.nodeAdapterModule)};
|
|
789
|
-
import wsAdapter from ${JSON.stringify(options.websocketAdapterModule)};
|
|
790
|
-
import { resolveWebsocketHooks, useNitroApp, useNitroHooks } from "#nitro/runtime/app";
|
|
791
|
-
import { useRuntimeConfig } from "#nitro/runtime/runtime-config";
|
|
792
|
-
import { trapUnhandledErrors } from "#nitro/runtime/error/hooks";
|
|
793
|
-
import { setupCloseHooks } from "#nitro/runtime/shutdown";
|
|
794
|
-
import { startScheduleRunner } from "#nitro/runtime/task";
|
|
795
|
-
import { tracingSrvxPlugins } from "#nitro/virtual/tracing";
|
|
796
|
-
import { farmProductionLifecycle } from ${JSON.stringify(nitroEntryImport)};
|
|
797
|
-
|
|
798
|
-
const farmServerConfig = ${serverConfig};
|
|
799
|
-
if (!process.env.NITRO_SHUTDOWN_TIMEOUT) {
|
|
800
|
-
process.env.NITRO_SHUTDOWN_TIMEOUT = String(farmServerConfig.gracefulShutdownTimeout);
|
|
801
|
-
}
|
|
802
|
-
const shutdownConfig = {
|
|
803
|
-
disabled: Boolean(process.env.NITRO_SHUTDOWN_DISABLED),
|
|
804
|
-
signals: (process.env.NITRO_SHUTDOWN_SIGNALS || "SIGTERM SIGINT")
|
|
805
|
-
.split(" ")
|
|
806
|
-
.map((signal) => signal.trim())
|
|
807
|
-
.filter(Boolean),
|
|
808
|
-
timeout: Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10) || 30000,
|
|
809
|
-
forceExit: !process.env.NITRO_SHUTDOWN_NO_FORCE_EXIT,
|
|
810
|
-
};
|
|
811
|
-
|
|
812
|
-
const nitroApp = useNitroApp();
|
|
813
|
-
useNitroHooks().hook("close", async () => {
|
|
814
|
-
try {
|
|
815
|
-
await farmProductionLifecycle.close("production-server-closed");
|
|
816
|
-
} catch (error) {
|
|
817
|
-
process.exitCode = 1;
|
|
818
|
-
throw error;
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
|
-
|
|
822
|
-
let startupSignal;
|
|
823
|
-
let resolveStartupSignal;
|
|
824
|
-
const startupSignalPromise = new Promise((resolve) => {
|
|
825
|
-
resolveStartupSignal = resolve;
|
|
826
|
-
});
|
|
827
|
-
const startupSignalListeners = new Map();
|
|
828
|
-
if (!shutdownConfig.disabled) {
|
|
829
|
-
for (const signal of shutdownConfig.signals) {
|
|
830
|
-
const listener = (receivedSignal) => {
|
|
831
|
-
if (!startupSignal) {
|
|
832
|
-
startupSignal = receivedSignal;
|
|
833
|
-
resolveStartupSignal(receivedSignal);
|
|
834
|
-
}
|
|
835
|
-
farmProductionLifecycle.beginDrain(receivedSignal);
|
|
836
|
-
};
|
|
837
|
-
startupSignalListeners.set(signal, listener);
|
|
838
|
-
process.once(signal, listener);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
try {
|
|
843
|
-
await Promise.race([
|
|
844
|
-
Promise.resolve().then(() => farmProductionLifecycle.start()),
|
|
845
|
-
startupSignalPromise,
|
|
846
|
-
]);
|
|
847
|
-
} catch (error) {
|
|
848
|
-
await farmProductionLifecycle.close("production-start-failed").catch((closeError) => {
|
|
849
|
-
console.error("[Farm] Runtime cleanup after startup failure failed:", closeError);
|
|
850
|
-
});
|
|
851
|
-
throw error;
|
|
852
|
-
} finally {
|
|
853
|
-
for (const [signal, listener] of startupSignalListeners) {
|
|
854
|
-
process.removeListener(signal, listener);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (startupSignal) {
|
|
859
|
-
let startupCloseTimer;
|
|
860
|
-
const startupCloseCompleted = await Promise.race([
|
|
861
|
-
Promise.resolve()
|
|
862
|
-
.then(() => farmProductionLifecycle.close(startupSignal))
|
|
863
|
-
.then(
|
|
864
|
-
() => true,
|
|
865
|
-
(error) => {
|
|
866
|
-
console.error("[Farm] Runtime shutdown during startup failed:", error);
|
|
867
|
-
process.exitCode = 1;
|
|
868
|
-
return true;
|
|
869
|
-
},
|
|
870
|
-
),
|
|
871
|
-
new Promise((resolve) => {
|
|
872
|
-
startupCloseTimer = setTimeout(() => resolve(false), farmServerConfig.gracefulShutdownTimeout);
|
|
873
|
-
}),
|
|
874
|
-
]);
|
|
875
|
-
clearTimeout(startupCloseTimer);
|
|
876
|
-
if (!startupCloseCompleted) {
|
|
877
|
-
console.warn("[Farm] Runtime startup did not settle before shutdown; forcing cleanup");
|
|
878
|
-
let forcedCloseTimer;
|
|
879
|
-
const forcedCloseCompleted = await Promise.race([
|
|
880
|
-
Promise.resolve()
|
|
881
|
-
.then(() => farmProductionLifecycle.forceClose(startupSignal))
|
|
882
|
-
.then(
|
|
883
|
-
() => true,
|
|
884
|
-
(error) => {
|
|
885
|
-
console.error("[Farm] Forced runtime shutdown during startup failed:", error);
|
|
886
|
-
process.exitCode = 1;
|
|
887
|
-
return true;
|
|
888
|
-
},
|
|
889
|
-
),
|
|
890
|
-
new Promise((resolve) => {
|
|
891
|
-
forcedCloseTimer = setTimeout(
|
|
892
|
-
() => resolve(false),
|
|
893
|
-
farmServerConfig.gracefulShutdownTimeout,
|
|
894
|
-
);
|
|
895
|
-
}),
|
|
896
|
-
]);
|
|
897
|
-
clearTimeout(forcedCloseTimer);
|
|
898
|
-
if (!forcedCloseCompleted) {
|
|
899
|
-
console.error("[Farm] Forced runtime shutdown during startup timed out");
|
|
900
|
-
process.exitCode = 1;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
process.exit(process.exitCode || 0);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
const cert = process.env.NITRO_SSL_CERT;
|
|
907
|
-
const key = process.env.NITRO_SSL_KEY;
|
|
908
|
-
const configuredPort = Number(process.env.NITRO_PORT || process.env.PORT);
|
|
909
|
-
const port = Number.isFinite(configuredPort) && configuredPort > 0 ? configuredPort : 3000;
|
|
910
|
-
const host = process.env.NITRO_HOST || process.env.HOST;
|
|
911
|
-
const socketPath = process.env.NITRO_UNIX_SOCKET;
|
|
912
|
-
const server = serve({
|
|
913
|
-
manual: true,
|
|
914
|
-
silent: true,
|
|
915
|
-
gracefulShutdown: false,
|
|
916
|
-
port,
|
|
917
|
-
hostname: host,
|
|
918
|
-
node: socketPath ? { path: socketPath } : undefined,
|
|
919
|
-
tls: cert && key ? { cert, key } : undefined,
|
|
920
|
-
fetch: nitroApp.fetch,
|
|
921
|
-
plugins: [...tracingSrvxPlugins],
|
|
922
|
-
});
|
|
923
|
-
const nodeServer = server.node?.server;
|
|
924
|
-
if (!nodeServer) throw new Error("[Farm] Nitro did not create a Node server");
|
|
925
|
-
|
|
926
|
-
nodeServer.headersTimeout = farmServerConfig.headersTimeout;
|
|
927
|
-
nodeServer.requestTimeout = farmServerConfig.requestTimeout;
|
|
928
|
-
nodeServer.keepAliveTimeout = farmServerConfig.keepAliveTimeout;
|
|
929
|
-
|
|
930
|
-
let isShuttingDown = false;
|
|
931
|
-
nodeServer.on("request", (_request, response) => {
|
|
932
|
-
response.once("finish", () => {
|
|
933
|
-
if (isShuttingDown) nodeServer.closeIdleConnections?.();
|
|
934
|
-
});
|
|
935
|
-
});
|
|
936
|
-
|
|
937
|
-
if (import.meta._websocket) {
|
|
938
|
-
const { handleUpgrade } = wsAdapter({ resolve: resolveWebsocketHooks });
|
|
939
|
-
nodeServer.on("upgrade", (request, socket, head) => {
|
|
940
|
-
handleUpgrade(
|
|
941
|
-
request,
|
|
942
|
-
socket,
|
|
943
|
-
head,
|
|
944
|
-
new NodeRequest({ req: request, upgrade: { socket, head } }),
|
|
945
|
-
);
|
|
946
|
-
});
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
setupCloseHooks(server);
|
|
950
|
-
trapUnhandledErrors();
|
|
951
|
-
|
|
952
|
-
let shutdownPromise;
|
|
953
|
-
async function shutdown(signal) {
|
|
954
|
-
isShuttingDown = true;
|
|
955
|
-
farmProductionLifecycle.beginDrain(signal);
|
|
956
|
-
|
|
957
|
-
const gracefulClose = server.close().then(
|
|
958
|
-
() => true,
|
|
959
|
-
(error) => {
|
|
960
|
-
console.error("[Farm] Runtime shutdown failed:", error);
|
|
961
|
-
process.exitCode = 1;
|
|
962
|
-
return true;
|
|
963
|
-
},
|
|
964
|
-
);
|
|
965
|
-
nodeServer.closeIdleConnections?.();
|
|
966
|
-
let gracefulTimer;
|
|
967
|
-
const gracefullyClosed = await Promise.race([
|
|
968
|
-
gracefulClose,
|
|
969
|
-
new Promise((resolve) => {
|
|
970
|
-
gracefulTimer = setTimeout(() => resolve(false), shutdownConfig.timeout);
|
|
971
|
-
}),
|
|
972
|
-
]);
|
|
973
|
-
clearTimeout(gracefulTimer);
|
|
974
|
-
|
|
975
|
-
if (!gracefullyClosed) {
|
|
976
|
-
console.warn("[Farm] Graceful shutdown timed out; forcing cleanup");
|
|
977
|
-
void server.close(true).catch((error) => {
|
|
978
|
-
console.error("[Farm] Forced server shutdown failed:", error);
|
|
979
|
-
process.exitCode = 1;
|
|
980
|
-
});
|
|
981
|
-
|
|
982
|
-
let forceTimer;
|
|
983
|
-
const forceClosed = await Promise.race([
|
|
984
|
-
Promise.resolve()
|
|
985
|
-
.then(() => farmProductionLifecycle.forceClose("production-server-closed"))
|
|
986
|
-
.then(
|
|
987
|
-
() => true,
|
|
988
|
-
(error) => {
|
|
989
|
-
console.error("[Farm] Forced runtime shutdown failed:", error);
|
|
990
|
-
process.exitCode = 1;
|
|
991
|
-
return true;
|
|
992
|
-
},
|
|
993
|
-
),
|
|
994
|
-
new Promise((resolve) => {
|
|
995
|
-
forceTimer = setTimeout(() => resolve(false), shutdownConfig.timeout);
|
|
996
|
-
}),
|
|
997
|
-
]);
|
|
998
|
-
clearTimeout(forceTimer);
|
|
999
|
-
if (!forceClosed) {
|
|
1000
|
-
console.error("[Farm] Forced runtime shutdown timed out");
|
|
1001
|
-
process.exitCode = 1;
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
if (shutdownConfig.forceExit) process.exit(process.exitCode || 0);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
if (!shutdownConfig.disabled) {
|
|
1009
|
-
for (const signal of shutdownConfig.signals) {
|
|
1010
|
-
process.once(signal, (receivedSignal) => {
|
|
1011
|
-
shutdownPromise ||= shutdown(receivedSignal);
|
|
1012
|
-
});
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
try {
|
|
1017
|
-
await server.serve();
|
|
1018
|
-
const protocol = cert && key ? "https" : "http";
|
|
1019
|
-
const addressInfo = nodeServer.address();
|
|
1020
|
-
if (typeof addressInfo === "string") {
|
|
1021
|
-
console.log(\`Listening on unix socket \${addressInfo}\`);
|
|
1022
|
-
} else if (addressInfo) {
|
|
1023
|
-
const configuredBaseURL = useRuntimeConfig().app.baseURL || "";
|
|
1024
|
-
const baseURL = configuredBaseURL.endsWith("/")
|
|
1025
|
-
? configuredBaseURL.slice(0, -1)
|
|
1026
|
-
: configuredBaseURL;
|
|
1027
|
-
const address = addressInfo.family === "IPv6"
|
|
1028
|
-
? \`[\${addressInfo.address}]\`
|
|
1029
|
-
: addressInfo.address;
|
|
1030
|
-
console.log(\`Listening on \${protocol}://\${address}:\${addressInfo.port}\${baseURL}\`);
|
|
1031
|
-
}
|
|
1032
|
-
} catch (error) {
|
|
1033
|
-
console.error(error);
|
|
1034
|
-
process.exitCode = 1;
|
|
1035
|
-
await farmProductionLifecycle.close("production-listen-error").catch((closeError) => {
|
|
1036
|
-
console.error("[Farm] Runtime cleanup after listen failure failed:", closeError);
|
|
1037
|
-
});
|
|
1038
|
-
throw error;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
if (import.meta._tasks) {
|
|
1042
|
-
startScheduleRunner({ waitUntil: server.waitUntil });
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
export default {};
|
|
1046
|
-
`.trim();
|
|
1047
|
-
}
|
|
1048
|
-
__name(createFarmNodeServerEntry, "createFarmNodeServerEntry");
|
|
1049
|
-
|
|
1050
977
|
// src/nitro/universal-build.ts
|
|
1051
978
|
function preloadFarmNitroBuilder() {
|
|
1052
979
|
return import("nitro/builder").then(
|
|
@@ -1056,18 +983,18 @@ function preloadFarmNitroBuilder() {
|
|
|
1056
983
|
}
|
|
1057
984
|
__name(preloadFarmNitroBuilder, "preloadFarmNitroBuilder");
|
|
1058
985
|
var _filename = typeof import.meta.url !== "undefined" ? fileURLToPath(import.meta.url) : "";
|
|
1059
|
-
var _dirname =
|
|
986
|
+
var _dirname = path8.dirname(_filename);
|
|
1060
987
|
function findFarmCoreRoot(from) {
|
|
1061
|
-
let dir =
|
|
1062
|
-
while (dir !==
|
|
1063
|
-
const manifest =
|
|
988
|
+
let dir = path8.dirname(from);
|
|
989
|
+
while (dir !== path8.dirname(dir)) {
|
|
990
|
+
const manifest = path8.join(dir, "package.json");
|
|
1064
991
|
if (existsSync2(manifest)) {
|
|
1065
992
|
try {
|
|
1066
993
|
if (JSON.parse(readFileSync(manifest, "utf8")).name === "@farm.js/core") return dir;
|
|
1067
994
|
} catch {
|
|
1068
995
|
}
|
|
1069
996
|
}
|
|
1070
|
-
dir =
|
|
997
|
+
dir = path8.dirname(dir);
|
|
1071
998
|
}
|
|
1072
999
|
return null;
|
|
1073
1000
|
}
|
|
@@ -1079,16 +1006,16 @@ function toModulePath(file) {
|
|
|
1079
1006
|
}
|
|
1080
1007
|
__name(toModulePath, "toModulePath");
|
|
1081
1008
|
function findInstalledPackageDir(name, from) {
|
|
1082
|
-
for (let dir = from; ; dir =
|
|
1083
|
-
const candidate =
|
|
1084
|
-
if (existsSync2(
|
|
1009
|
+
for (let dir = from; ; dir = path8.dirname(dir)) {
|
|
1010
|
+
const candidate = path8.join(dir, "node_modules", name);
|
|
1011
|
+
if (existsSync2(path8.join(candidate, "package.json"))) {
|
|
1085
1012
|
try {
|
|
1086
1013
|
return realpathSync(candidate);
|
|
1087
1014
|
} catch {
|
|
1088
1015
|
return null;
|
|
1089
1016
|
}
|
|
1090
1017
|
}
|
|
1091
|
-
if (dir ===
|
|
1018
|
+
if (dir === path8.dirname(dir)) return null;
|
|
1092
1019
|
}
|
|
1093
1020
|
}
|
|
1094
1021
|
__name(findInstalledPackageDir, "findInstalledPackageDir");
|
|
@@ -1100,7 +1027,7 @@ function collectFarmDependencyDirs(root) {
|
|
|
1100
1027
|
seen.add(dir);
|
|
1101
1028
|
let manifest;
|
|
1102
1029
|
try {
|
|
1103
|
-
manifest = JSON.parse(readFileSync(
|
|
1030
|
+
manifest = JSON.parse(readFileSync(path8.join(dir, "package.json"), "utf8"));
|
|
1104
1031
|
} catch {
|
|
1105
1032
|
return;
|
|
1106
1033
|
}
|
|
@@ -1111,7 +1038,7 @@ function collectFarmDependencyDirs(root) {
|
|
|
1111
1038
|
if (farmCoreRoot) visit(realpathSync(farmCoreRoot));
|
|
1112
1039
|
queue.push({ name: "@farm.js/core", from: root });
|
|
1113
1040
|
try {
|
|
1114
|
-
const manifest = JSON.parse(readFileSync(
|
|
1041
|
+
const manifest = JSON.parse(readFileSync(path8.join(root, "package.json"), "utf8"));
|
|
1115
1042
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
1116
1043
|
for (const name of Object.keys(manifest[field] ?? {})) {
|
|
1117
1044
|
if (name.startsWith("@farm.js/")) queue.push({ name, from: root });
|
|
@@ -1178,15 +1105,15 @@ var FARM_SSR_PACKAGE_IMPORT = "#farm-ssr-entry";
|
|
|
1178
1105
|
var FARM_SSR_OUTPUT_DIR = "farm-ssr";
|
|
1179
1106
|
var FARM_CLIENT_BUILD_TARGET = ["es2020", "edge88", "firefox78", "chrome87", "safari14"];
|
|
1180
1107
|
function resolveNitroRuntimeDependency(root, specifier) {
|
|
1181
|
-
return createRequire(resolveNitroPackageEntry(root)).resolve(specifier).split(
|
|
1108
|
+
return createRequire(resolveNitroPackageEntry(root)).resolve(specifier).split(path8.sep).join("/");
|
|
1182
1109
|
}
|
|
1183
1110
|
__name(resolveNitroRuntimeDependency, "resolveNitroRuntimeDependency");
|
|
1184
1111
|
function resolveNitroInternalRuntimeAliases(root) {
|
|
1185
|
-
const runtimeDir =
|
|
1112
|
+
const runtimeDir = path8.dirname(resolveNitroPackageEntry(root));
|
|
1186
1113
|
return Object.fromEntries(
|
|
1187
1114
|
["app", "error/hooks", "runtime-config", "shutdown", "task"].map((moduleName) => [
|
|
1188
1115
|
`#nitro/runtime/${moduleName}`,
|
|
1189
|
-
|
|
1116
|
+
path8.join(runtimeDir, "internal", `${moduleName}.mjs`).split(path8.sep).join("/")
|
|
1190
1117
|
])
|
|
1191
1118
|
);
|
|
1192
1119
|
}
|
|
@@ -1197,7 +1124,7 @@ function createPrerenderRuntimeResolverPlugin(root, resolveNitroEntry = resolveN
|
|
|
1197
1124
|
name: "farm-prerender-runtime-resolver",
|
|
1198
1125
|
async resolveId(id, _importer, options) {
|
|
1199
1126
|
if (options.custom?.farmPrerenderRuntimeResolve) return null;
|
|
1200
|
-
if (id.startsWith("\0") || id.startsWith(".") || id.startsWith("#") || id.startsWith("virtual:") ||
|
|
1127
|
+
if (id.startsWith("\0") || id.startsWith(".") || id.startsWith("#") || id.startsWith("virtual:") || path8.isAbsolute(id) || NODE_BUILTIN_MODULES.has(id)) {
|
|
1201
1128
|
return null;
|
|
1202
1129
|
}
|
|
1203
1130
|
if (nitroEntry === void 0) {
|
|
@@ -1218,7 +1145,7 @@ function createPrerenderRuntimeResolverPlugin(root, resolveNitroEntry = resolveN
|
|
|
1218
1145
|
}
|
|
1219
1146
|
__name(createPrerenderRuntimeResolverPlugin, "createPrerenderRuntimeResolverPlugin");
|
|
1220
1147
|
function resolveNitroPackageEntry(root) {
|
|
1221
|
-
const projectRequire = createRequire(
|
|
1148
|
+
const projectRequire = createRequire(path8.join(root, "package.json"));
|
|
1222
1149
|
let runtimeRequire = projectRequire;
|
|
1223
1150
|
try {
|
|
1224
1151
|
runtimeRequire = createRequire(projectRequire.resolve("@farm.js/core"));
|
|
@@ -1293,7 +1220,7 @@ function createFarmReactWebServerAlias(hasEdgeBuild) {
|
|
|
1293
1220
|
__name(createFarmReactWebServerAlias, "createFarmReactWebServerAlias");
|
|
1294
1221
|
function hasReactDomEdgeServerBuild(root) {
|
|
1295
1222
|
try {
|
|
1296
|
-
createRequire(
|
|
1223
|
+
createRequire(path8.join(root, "package.json")).resolve("react-dom/server.edge");
|
|
1297
1224
|
return true;
|
|
1298
1225
|
} catch {
|
|
1299
1226
|
return false;
|
|
@@ -1351,7 +1278,7 @@ function createMetadataImageWasmPlugin() {
|
|
|
1351
1278
|
return null;
|
|
1352
1279
|
}
|
|
1353
1280
|
const requestPath = source.slice(0, -"?module".length);
|
|
1354
|
-
const resolvedPath =
|
|
1281
|
+
const resolvedPath = path8.isAbsolute(requestPath) ? requestPath : path8.resolve(path8.dirname(importer.split("?", 1)[0]), requestPath);
|
|
1355
1282
|
return `${FARM_METADATA_IMAGE_WASM_PREFIX}${resolvedPath}`;
|
|
1356
1283
|
},
|
|
1357
1284
|
load(id) {
|
|
@@ -1377,11 +1304,11 @@ function collectSSRExternalPackages(ssrBundle) {
|
|
|
1377
1304
|
for (const importId of [...output.imports, ...output.dynamicImports]) {
|
|
1378
1305
|
const normalizedImportId = importId.replace(/\\/g, "/");
|
|
1379
1306
|
const normalizedId = normalizedImportId.replace(/^\.\//, "");
|
|
1380
|
-
const resolvedRelativeId = normalizedImportId.startsWith("./") || normalizedImportId.startsWith("../") ?
|
|
1307
|
+
const resolvedRelativeId = normalizedImportId.startsWith("./") || normalizedImportId.startsWith("../") ? path8.posix.normalize(path8.posix.join(path8.posix.dirname(fileName), normalizedImportId)) : null;
|
|
1381
1308
|
if (emittedFiles.has(normalizedId) || resolvedRelativeId !== null && emittedFiles.has(resolvedRelativeId) || NODE_BUILTIN_MODULES.has(importId) || importId.startsWith("node:")) {
|
|
1382
1309
|
continue;
|
|
1383
1310
|
}
|
|
1384
|
-
if (
|
|
1311
|
+
if (path8.isAbsolute(importId) || /^[A-Za-z]:[\\/]/.test(importId) || importId.startsWith("#") || importId.startsWith("\0")) {
|
|
1385
1312
|
externalPackages.add(importId);
|
|
1386
1313
|
continue;
|
|
1387
1314
|
}
|
|
@@ -1394,15 +1321,15 @@ function collectSSRExternalPackages(ssrBundle) {
|
|
|
1394
1321
|
}
|
|
1395
1322
|
__name(collectSSRExternalPackages, "collectSSRExternalPackages");
|
|
1396
1323
|
function createExternalSSRBundlePlugin(nitroEntryPath, ssrOutputDir, ssrEntryFile) {
|
|
1397
|
-
const resolvedNitroEntry =
|
|
1398
|
-
const resolvedSSREntry =
|
|
1324
|
+
const resolvedNitroEntry = path8.resolve(nitroEntryPath);
|
|
1325
|
+
const resolvedSSREntry = path8.resolve(ssrOutputDir, ssrEntryFile);
|
|
1399
1326
|
return {
|
|
1400
1327
|
name: "farm-externalize-prebuilt-ssr",
|
|
1401
1328
|
resolveId(source, importer) {
|
|
1402
|
-
if (!importer ||
|
|
1329
|
+
if (!importer || path8.resolve(importer) !== resolvedNitroEntry) {
|
|
1403
1330
|
return null;
|
|
1404
1331
|
}
|
|
1405
|
-
const resolvedImport =
|
|
1332
|
+
const resolvedImport = path8.resolve(path8.dirname(importer), source);
|
|
1406
1333
|
if (resolvedImport !== resolvedSSREntry) return null;
|
|
1407
1334
|
return { id: FARM_SSR_PACKAGE_IMPORT, external: true };
|
|
1408
1335
|
}
|
|
@@ -1530,13 +1457,13 @@ function resolveBuildDocsContentDir(config, root) {
|
|
|
1530
1457
|
if (!config.docs?.enabled) return null;
|
|
1531
1458
|
const configuredContentDir = config.docs.contentDir || config.docs.config.contentDir;
|
|
1532
1459
|
if (typeof configuredContentDir === "string" && configuredContentDir.trim()) {
|
|
1533
|
-
const contentDir =
|
|
1460
|
+
const contentDir = path8.isAbsolute(configuredContentDir) ? configuredContentDir : path8.join(root, configuredContentDir);
|
|
1534
1461
|
return existsSync2(contentDir) ? contentDir : null;
|
|
1535
1462
|
}
|
|
1536
1463
|
const entryDir = config.docs.config.entry || trimSlashes(config.docs.entry) || "docs";
|
|
1537
|
-
const appDocsDir =
|
|
1464
|
+
const appDocsDir = path8.join(root, config.srcDir || "src", "app", entryDir);
|
|
1538
1465
|
if (existsSync2(appDocsDir)) return appDocsDir;
|
|
1539
|
-
const rootDocsDir =
|
|
1466
|
+
const rootDocsDir = path8.join(root, entryDir);
|
|
1540
1467
|
return existsSync2(rootDocsDir) ? rootDocsDir : null;
|
|
1541
1468
|
}
|
|
1542
1469
|
__name(resolveBuildDocsContentDir, "resolveBuildDocsContentDir");
|
|
@@ -1554,7 +1481,7 @@ function hasProjectPostcssConfig(root) {
|
|
|
1554
1481
|
".postcssrc.mjs",
|
|
1555
1482
|
".postcssrc.ts"
|
|
1556
1483
|
];
|
|
1557
|
-
const projectRequire = createRequire(
|
|
1484
|
+
const projectRequire = createRequire(path8.join(root, "package.json"));
|
|
1558
1485
|
return candidates.some((file) => {
|
|
1559
1486
|
try {
|
|
1560
1487
|
projectRequire.resolve(`./${file}`);
|
|
@@ -1566,7 +1493,7 @@ function hasProjectPostcssConfig(root) {
|
|
|
1566
1493
|
}
|
|
1567
1494
|
__name(hasProjectPostcssConfig, "hasProjectPostcssConfig");
|
|
1568
1495
|
async function findFarmConfigPath(root) {
|
|
1569
|
-
const
|
|
1496
|
+
const fs3 = await import("fs/promises");
|
|
1570
1497
|
const candidates = [
|
|
1571
1498
|
"farm.config.ts",
|
|
1572
1499
|
"farm.config.mts",
|
|
@@ -1578,9 +1505,9 @@ async function findFarmConfigPath(root) {
|
|
|
1578
1505
|
"config.mjs"
|
|
1579
1506
|
];
|
|
1580
1507
|
for (const candidate of candidates) {
|
|
1581
|
-
const resolvedPath =
|
|
1508
|
+
const resolvedPath = path8.join(root, candidate);
|
|
1582
1509
|
try {
|
|
1583
|
-
await
|
|
1510
|
+
await fs3.access(resolvedPath);
|
|
1584
1511
|
return resolvedPath;
|
|
1585
1512
|
} catch {
|
|
1586
1513
|
}
|
|
@@ -1588,15 +1515,6 @@ async function findFarmConfigPath(root) {
|
|
|
1588
1515
|
return null;
|
|
1589
1516
|
}
|
|
1590
1517
|
__name(findFarmConfigPath, "findFarmConfigPath");
|
|
1591
|
-
function hasFarmMiddlewareConfig(config) {
|
|
1592
|
-
if (!config) return false;
|
|
1593
|
-
if (Array.isArray(config)) return config.length > 0;
|
|
1594
|
-
const configRecord = config;
|
|
1595
|
-
return Boolean(
|
|
1596
|
-
configRecord.matcher || configRecord.exclude || configRecord.runtime || configRecord.handler || Array.isArray(configRecord.handlers) && configRecord.handlers.length > 0
|
|
1597
|
-
);
|
|
1598
|
-
}
|
|
1599
|
-
__name(hasFarmMiddlewareConfig, "hasFarmMiddlewareConfig");
|
|
1600
1518
|
function hasFarmServerRuntimePlugins(config) {
|
|
1601
1519
|
return (config.plugins || []).some((plugin) => {
|
|
1602
1520
|
if (getFarmIntegrationPluginServerRuntime(plugin) === false) return false;
|
|
@@ -1617,13 +1535,13 @@ function farmServerRuntimePluginsMayHandlePath(config, pathname) {
|
|
|
1617
1535
|
}
|
|
1618
1536
|
__name(farmServerRuntimePluginsMayHandlePath, "farmServerRuntimePluginsMayHandlePath");
|
|
1619
1537
|
async function discoverMiddlewareRoutes(appDir) {
|
|
1620
|
-
const
|
|
1538
|
+
const fs3 = await import("fs/promises");
|
|
1621
1539
|
const appDirs = Array.isArray(appDir) ? [...appDir] : [appDir];
|
|
1622
1540
|
const routes = /* @__PURE__ */ new Map();
|
|
1623
1541
|
async function walk(dir, routePath, directory, discovered) {
|
|
1624
1542
|
let entries;
|
|
1625
1543
|
try {
|
|
1626
|
-
entries = await
|
|
1544
|
+
entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
1627
1545
|
} catch {
|
|
1628
1546
|
return;
|
|
1629
1547
|
}
|
|
@@ -1634,7 +1552,7 @@ async function discoverMiddlewareRoutes(appDir) {
|
|
|
1634
1552
|
discovered.push({
|
|
1635
1553
|
path: routePath,
|
|
1636
1554
|
directory,
|
|
1637
|
-
filePath:
|
|
1555
|
+
filePath: path8.join(dir, middlewareFile.name)
|
|
1638
1556
|
});
|
|
1639
1557
|
}
|
|
1640
1558
|
for (const entry of entries) {
|
|
@@ -1642,7 +1560,7 @@ async function discoverMiddlewareRoutes(appDir) {
|
|
|
1642
1560
|
continue;
|
|
1643
1561
|
}
|
|
1644
1562
|
await walk(
|
|
1645
|
-
|
|
1563
|
+
path8.join(dir, entry.name),
|
|
1646
1564
|
appendMiddlewareRoutePath(routePath, entry.name),
|
|
1647
1565
|
appendMiddlewareDirectory(directory, entry.name),
|
|
1648
1566
|
discovered
|
|
@@ -1719,21 +1637,21 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
1719
1637
|
})
|
|
1720
1638
|
);
|
|
1721
1639
|
logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes`);
|
|
1722
|
-
const
|
|
1640
|
+
const fs3 = await import("fs/promises");
|
|
1723
1641
|
const layoutRoutes = [];
|
|
1724
|
-
const appDir =
|
|
1642
|
+
const appDir = path8.join(root, srcDir, "app");
|
|
1725
1643
|
async function findLayoutsForClient(dir, routePrefix = "/") {
|
|
1726
1644
|
try {
|
|
1727
|
-
const entries = await
|
|
1645
|
+
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
1728
1646
|
for (const entry of entries) {
|
|
1729
1647
|
if (entry.isFile() && entry.name.match(/^layout\.(tsx?|jsx?|vue|svelte)$/)) {
|
|
1730
1648
|
layoutRoutes.push({
|
|
1731
1649
|
pattern: routePrefix,
|
|
1732
|
-
modulePath:
|
|
1650
|
+
modulePath: path8.join(dir, entry.name)
|
|
1733
1651
|
});
|
|
1734
1652
|
} else if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
|
|
1735
1653
|
const childPrefix = routePrefix === "/" ? `/${entry.name}` : `${routePrefix}/${entry.name}`;
|
|
1736
|
-
await findLayoutsForClient(
|
|
1654
|
+
await findLayoutsForClient(path8.join(dir, entry.name), childPrefix);
|
|
1737
1655
|
}
|
|
1738
1656
|
}
|
|
1739
1657
|
} catch {
|
|
@@ -1750,7 +1668,7 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
1750
1668
|
logger.info(`\u{1F4CB} Found ${pageRoutes.length} page routes and ${layoutRoutes.length} layouts`);
|
|
1751
1669
|
const isolatedClientBoundaryModules = routeManager.getIsolatedClientBoundaryModules(root);
|
|
1752
1670
|
const hydrationPlanCache = /* @__PURE__ */ new Map();
|
|
1753
|
-
const clientOutputDir =
|
|
1671
|
+
const clientOutputDir = path8.join(root, distDir, "client");
|
|
1754
1672
|
const [productionViteResult] = await productionViteResultPromise;
|
|
1755
1673
|
if (productionViteResult.status === "rejected") {
|
|
1756
1674
|
await routeRuntimeManifestResultPromise;
|
|
@@ -1859,10 +1777,10 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
1859
1777
|
lifecyclePluginManager
|
|
1860
1778
|
);
|
|
1861
1779
|
const runtimeManifestPath = await writeFarmRouteRuntimeManifest(
|
|
1862
|
-
|
|
1780
|
+
path8.join(root, distDir),
|
|
1863
1781
|
routeRuntimeManifest
|
|
1864
1782
|
);
|
|
1865
|
-
logger.info(`\u{1F4CB} Route runtime manifest: ${
|
|
1783
|
+
logger.info(`\u{1F4CB} Route runtime manifest: ${path8.relative(root, runtimeManifestPath)}`);
|
|
1866
1784
|
} catch (error) {
|
|
1867
1785
|
if (lifecyclePluginManager) {
|
|
1868
1786
|
await lifecyclePluginManager.runHookParallel("onError", {
|
|
@@ -1882,50 +1800,50 @@ async function buildUniversal(config, routeManager, apiRouteManager, serverRende
|
|
|
1882
1800
|
}
|
|
1883
1801
|
__name(buildUniversal, "buildUniversal");
|
|
1884
1802
|
async function writeSSRAssetsToClient(bundle, outputDir) {
|
|
1885
|
-
const
|
|
1803
|
+
const fs3 = await import("fs/promises");
|
|
1886
1804
|
for (const [fileName, output] of Object.entries(bundle)) {
|
|
1887
1805
|
if (output.type !== "asset") continue;
|
|
1888
1806
|
if (fileName === "farm-fonts.css") {
|
|
1889
1807
|
await mergeBuiltFontCss(outputDir, output.source);
|
|
1890
1808
|
continue;
|
|
1891
1809
|
}
|
|
1892
|
-
const filePath =
|
|
1893
|
-
await
|
|
1894
|
-
await
|
|
1810
|
+
const filePath = path8.join(outputDir, fileName);
|
|
1811
|
+
await fs3.mkdir(path8.dirname(filePath), { recursive: true });
|
|
1812
|
+
await fs3.writeFile(filePath, output.source);
|
|
1895
1813
|
}
|
|
1896
1814
|
}
|
|
1897
1815
|
__name(writeSSRAssetsToClient, "writeSSRAssetsToClient");
|
|
1898
1816
|
async function copyFarmDocsFontAssetsToClient(root, outputDir) {
|
|
1899
|
-
const
|
|
1817
|
+
const fs3 = await import("fs/promises");
|
|
1900
1818
|
await Promise.all(
|
|
1901
1819
|
resolveFarmDocsFontAssets(root).map(async ({ sourcePath, url }) => {
|
|
1902
|
-
const targetPath =
|
|
1903
|
-
await
|
|
1904
|
-
await
|
|
1820
|
+
const targetPath = path8.join(outputDir, url.replace(/^\/+/, ""));
|
|
1821
|
+
await fs3.mkdir(path8.dirname(targetPath), { recursive: true });
|
|
1822
|
+
await fs3.copyFile(sourcePath, targetPath);
|
|
1905
1823
|
})
|
|
1906
1824
|
);
|
|
1907
1825
|
}
|
|
1908
1826
|
__name(copyFarmDocsFontAssetsToClient, "copyFarmDocsFontAssetsToClient");
|
|
1909
1827
|
async function mergeBuiltFontCss(outputDir, fontCssSource) {
|
|
1910
|
-
const
|
|
1911
|
-
const fontCssPath =
|
|
1828
|
+
const fs3 = await import("fs/promises");
|
|
1829
|
+
const fontCssPath = path8.join(outputDir, "farm-fonts.css");
|
|
1912
1830
|
let fontCss = fontCssSource;
|
|
1913
1831
|
if (fontCss === void 0) {
|
|
1914
1832
|
try {
|
|
1915
|
-
fontCss = await
|
|
1833
|
+
fontCss = await fs3.readFile(fontCssPath);
|
|
1916
1834
|
} catch {
|
|
1917
1835
|
return;
|
|
1918
1836
|
}
|
|
1919
1837
|
}
|
|
1920
|
-
const clientCssPath =
|
|
1838
|
+
const clientCssPath = path8.join(outputDir, "farm-client.css");
|
|
1921
1839
|
let clientCss = "";
|
|
1922
1840
|
try {
|
|
1923
|
-
clientCss = await
|
|
1841
|
+
clientCss = await fs3.readFile(clientCssPath, "utf8");
|
|
1924
1842
|
} catch {
|
|
1925
1843
|
}
|
|
1926
1844
|
const normalizedFontCss = typeof fontCss === "string" ? fontCss : Buffer.from(fontCss).toString("utf8");
|
|
1927
|
-
await
|
|
1928
|
-
await
|
|
1845
|
+
await fs3.writeFile(fontCssPath, normalizedFontCss);
|
|
1846
|
+
await fs3.writeFile(clientCssPath, mergeFarmFontCss(clientCss, normalizedFontCss));
|
|
1929
1847
|
}
|
|
1930
1848
|
__name(mergeBuiltFontCss, "mergeBuiltFontCss");
|
|
1931
1849
|
var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError extends Error {
|
|
@@ -1937,28 +1855,28 @@ var _IncompleteClientBuildOutputError = class _IncompleteClientBuildOutputError
|
|
|
1937
1855
|
__name(_IncompleteClientBuildOutputError, "IncompleteClientBuildOutputError");
|
|
1938
1856
|
var IncompleteClientBuildOutputError = _IncompleteClientBuildOutputError;
|
|
1939
1857
|
async function validateClientBuildOutput(root, srcDir, outputDir) {
|
|
1940
|
-
const
|
|
1858
|
+
const fs3 = await import("fs/promises");
|
|
1941
1859
|
const fingerprinted = await findFingerprintedClientEntry(outputDir);
|
|
1942
|
-
const clientEntryPath =
|
|
1860
|
+
const clientEntryPath = path8.join(outputDir, fingerprinted ?? "farm-client.js");
|
|
1943
1861
|
let clientEntrySize = 0;
|
|
1944
1862
|
try {
|
|
1945
|
-
const clientEntry = await
|
|
1863
|
+
const clientEntry = await fs3.stat(clientEntryPath);
|
|
1946
1864
|
if (clientEntry.isFile()) clientEntrySize = clientEntry.size;
|
|
1947
1865
|
} catch {
|
|
1948
1866
|
}
|
|
1949
1867
|
if (clientEntrySize === 0) {
|
|
1950
1868
|
throw new IncompleteClientBuildOutputError("farm-client.js is missing or empty");
|
|
1951
1869
|
}
|
|
1952
|
-
const clientCssPath =
|
|
1953
|
-
const globalsCssPath =
|
|
1870
|
+
const clientCssPath = path8.join(outputDir, "farm-client.css");
|
|
1871
|
+
const globalsCssPath = path8.join(root, srcDir, "app", "globals.css");
|
|
1954
1872
|
let expectsCss = false;
|
|
1955
1873
|
try {
|
|
1956
|
-
const globalsCss = await
|
|
1874
|
+
const globalsCss = await fs3.readFile(globalsCssPath, "utf8");
|
|
1957
1875
|
expectsCss = globalsCss.replace(/\/\*[\s\S]*?\*\//g, "").trim().length > 0;
|
|
1958
1876
|
} catch {
|
|
1959
1877
|
}
|
|
1960
1878
|
try {
|
|
1961
|
-
const clientCss = await
|
|
1879
|
+
const clientCss = await fs3.stat(clientCssPath);
|
|
1962
1880
|
if (expectsCss && (!clientCss.isFile() || clientCss.size === 0)) {
|
|
1963
1881
|
throw new IncompleteClientBuildOutputError("farm-client.css is empty");
|
|
1964
1882
|
}
|
|
@@ -1967,12 +1885,12 @@ async function validateClientBuildOutput(root, srcDir, outputDir) {
|
|
|
1967
1885
|
if (expectsCss) {
|
|
1968
1886
|
throw new IncompleteClientBuildOutputError("farm-client.css is missing");
|
|
1969
1887
|
}
|
|
1970
|
-
await
|
|
1888
|
+
await fs3.writeFile(clientCssPath, "");
|
|
1971
1889
|
}
|
|
1972
1890
|
}
|
|
1973
1891
|
__name(validateClientBuildOutput, "validateClientBuildOutput");
|
|
1974
1892
|
function getCachedClientModuleHydrationPlan(modulePath, root, mode, cache, options = {}) {
|
|
1975
|
-
const key = `${
|
|
1893
|
+
const key = `${path8.resolve(root)}\0${mode}\0${options.asyncOwnerIslands === true}\0${path8.resolve(modulePath)}`;
|
|
1976
1894
|
let plan = cache.get(key);
|
|
1977
1895
|
if (!plan) {
|
|
1978
1896
|
plan = getClientModuleHydrationPlan(modulePath, root, mode, options);
|
|
@@ -1985,7 +1903,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
1985
1903
|
const viteBuild = productionVite.build;
|
|
1986
1904
|
const { farmPlugin, farmServerOnlyEntriesPlugin } = await import("./vite.mjs");
|
|
1987
1905
|
const { PluginManager: PluginManager2 } = await import("./plugin.mjs");
|
|
1988
|
-
const
|
|
1906
|
+
const fs3 = await import("fs/promises");
|
|
1989
1907
|
const pluginManager = new PluginManager2({
|
|
1990
1908
|
config,
|
|
1991
1909
|
isDev: false,
|
|
@@ -2211,10 +2129,10 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2211
2129
|
logger.info(
|
|
2212
2130
|
`\u{1F4F1} Total hydratable routes detected: ${clientPages.length} pages, ${clientLayouts.filter((layout) => layout.shouldHydrate || layout.hasIsolatedClientBoundaries).length} layouts, and ${clientRouteSlots.length} slots`
|
|
2213
2131
|
);
|
|
2214
|
-
const clientEntryRoot =
|
|
2215
|
-
await
|
|
2216
|
-
const clientEntryDir = await
|
|
2217
|
-
const clientEntryPath =
|
|
2132
|
+
const clientEntryRoot = path8.join(root, ".farm", "tmp");
|
|
2133
|
+
await fs3.mkdir(clientEntryRoot, { recursive: true });
|
|
2134
|
+
const clientEntryDir = await fs3.mkdtemp(path8.join(clientEntryRoot, "client-entry-"));
|
|
2135
|
+
const clientEntryPath = path8.join(clientEntryDir, "farm-client-entry.tsx");
|
|
2218
2136
|
const clientHydrationCode = generateClientHydrationEntry(
|
|
2219
2137
|
clientPages,
|
|
2220
2138
|
clientLayouts,
|
|
@@ -2235,7 +2153,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2235
2153
|
generateClientCachePersistenceCode(resolveFarmClientCacheAdapterEntry(root, config.cache)),
|
|
2236
2154
|
adapterOwnsDocsRuntime ? getFarmDocsAdapterConfigModule(config.docs) : void 0
|
|
2237
2155
|
);
|
|
2238
|
-
await
|
|
2156
|
+
await fs3.writeFile(clientEntryPath, clientHydrationCode);
|
|
2239
2157
|
const hasScopedPostcssConfig = hasProjectPostcssConfig(root);
|
|
2240
2158
|
let postcssSearchPath;
|
|
2241
2159
|
let tailwindVitePlugin = void 0;
|
|
@@ -2246,8 +2164,8 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2246
2164
|
if (hasScopedPostcssConfig) {
|
|
2247
2165
|
logger.info("\u{1F4E6} Using project PostCSS/Tailwind configuration");
|
|
2248
2166
|
} else {
|
|
2249
|
-
const postcssConfigPath =
|
|
2250
|
-
await
|
|
2167
|
+
const postcssConfigPath = path8.join(clientEntryDir, "postcss.config.cjs");
|
|
2168
|
+
await fs3.writeFile(postcssConfigPath, "module.exports = { plugins: [] };\n");
|
|
2251
2169
|
postcssSearchPath = clientEntryDir;
|
|
2252
2170
|
tailwindVitePlugin = await loadTailwindVitePlugin({
|
|
2253
2171
|
builder: productionVite.builder,
|
|
@@ -2319,6 +2237,23 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2319
2237
|
},
|
|
2320
2238
|
plugins: [
|
|
2321
2239
|
createFarmThemeCssPlugin(config.theme, config.basePath),
|
|
2240
|
+
createFarmClientModulePreloadPlugin({
|
|
2241
|
+
root,
|
|
2242
|
+
buildDir: path8.dirname(outputDir),
|
|
2243
|
+
entryName: "farm-client"
|
|
2244
|
+
}),
|
|
2245
|
+
...adapterOwnsDocsRuntime ? [
|
|
2246
|
+
createFarmDocsModulePreloadPlugin({
|
|
2247
|
+
root,
|
|
2248
|
+
buildDir: path8.dirname(outputDir),
|
|
2249
|
+
importer: clientEntryPath,
|
|
2250
|
+
entryName: "farm-client",
|
|
2251
|
+
modules: [
|
|
2252
|
+
config.docs.adapter.react,
|
|
2253
|
+
getFarmDocsAdapterConfigModule(config.docs)
|
|
2254
|
+
].filter((specifier) => Boolean(specifier))
|
|
2255
|
+
})
|
|
2256
|
+
] : [],
|
|
2322
2257
|
...tailwindVitePlugin ? [tailwindVitePlugin] : [],
|
|
2323
2258
|
...rendererVitePlugins,
|
|
2324
2259
|
...config.vite.plugins || [],
|
|
@@ -2400,7 +2335,7 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2400
2335
|
await validateClientBuildOutput(root, srcDir, outputDir);
|
|
2401
2336
|
} finally {
|
|
2402
2337
|
try {
|
|
2403
|
-
await
|
|
2338
|
+
await fs3.rm(clientEntryDir, { recursive: true, force: true });
|
|
2404
2339
|
} catch {
|
|
2405
2340
|
}
|
|
2406
2341
|
}
|
|
@@ -2408,12 +2343,12 @@ async function buildClient(productionVite, config, root, srcDir, outputDir, page
|
|
|
2408
2343
|
__name(buildClient, "buildClient");
|
|
2409
2344
|
function toBakedMarkdownSourcePath(root, filePath) {
|
|
2410
2345
|
if (!filePath) return "";
|
|
2411
|
-
if (!
|
|
2412
|
-
const relative =
|
|
2413
|
-
if (!relative || relative.startsWith("..") ||
|
|
2414
|
-
return
|
|
2346
|
+
if (!path8.isAbsolute(filePath)) return filePath.split(path8.sep).join("/");
|
|
2347
|
+
const relative = path8.relative(root, filePath);
|
|
2348
|
+
if (!relative || relative.startsWith("..") || path8.isAbsolute(relative)) {
|
|
2349
|
+
return path8.basename(filePath);
|
|
2415
2350
|
}
|
|
2416
|
-
return relative.split(
|
|
2351
|
+
return relative.split(path8.sep).join("/");
|
|
2417
2352
|
}
|
|
2418
2353
|
__name(toBakedMarkdownSourcePath, "toBakedMarkdownSourcePath");
|
|
2419
2354
|
function generateUniversalRouterStateRuntime() {
|
|
@@ -3170,19 +3105,21 @@ __farmConfigureApp(__farmAppSetup);` : `import React, { createRoot, hydrateRoot
|
|
|
3170
3105
|
root,
|
|
3171
3106
|
renderer.componentExtensions ?? []
|
|
3172
3107
|
);
|
|
3173
|
-
const globalsCssPath =
|
|
3108
|
+
const globalsCssPath = path8.join(root, srcDir, "app", "globals.css");
|
|
3174
3109
|
const cssImport = existsSync2(globalsCssPath) ? `import ${JSON.stringify(toImportPath(globalsCssPath))};` : "";
|
|
3175
3110
|
const layoutImportStatements = [];
|
|
3176
3111
|
const layoutRegistrations = [];
|
|
3112
|
+
const hydratingLayoutPatterns = layoutRoutes.filter((layout) => layout.shouldHydrate).map((layout) => layout.pattern);
|
|
3177
3113
|
layoutRoutes.forEach((layout, index) => {
|
|
3178
3114
|
const relativePath = toImportPath(layout.modulePath);
|
|
3179
|
-
|
|
3115
|
+
const rendersOnClient = !layout.hasIsolatedClientBoundaries && hydratingLayoutPatterns.some((pattern) => layoutsCanCoverSamePage(layout.pattern, pattern));
|
|
3116
|
+
if (rendersOnClient) {
|
|
3180
3117
|
layoutImportStatements.push(`import Layout${index} from "${relativePath}";`);
|
|
3181
3118
|
}
|
|
3182
3119
|
const groupScope = getRouteGroupScope(layout.pattern);
|
|
3183
3120
|
const groupFields = groupScope ? `, urlPattern: ${JSON.stringify(stripRouteGroups(layout.pattern))}, groupScope: ${JSON.stringify(groupScope)}` : "";
|
|
3184
3121
|
layoutRegistrations.push(
|
|
3185
|
-
` { pattern: ${JSON.stringify(layout.pattern)}${groupFields}, Component: ${
|
|
3122
|
+
` { pattern: ${JSON.stringify(layout.pattern)}${groupFields}, Component: ${rendersOnClient ? `Layout${index}` : "null"}, shouldHydrate: ${JSON.stringify(layout.shouldHydrate)}, islandStrategy: ${JSON.stringify(layout.islandStrategy)} }`
|
|
3186
3123
|
);
|
|
3187
3124
|
});
|
|
3188
3125
|
const layoutImports = layoutImportStatements.join("\n");
|
|
@@ -4642,7 +4579,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
4642
4579
|
const viteBuild = productionVite.build;
|
|
4643
4580
|
const { farmPlugin, farmServerOnlyEntriesPlugin } = await import("./vite.mjs");
|
|
4644
4581
|
const { PluginManager: PluginManager2 } = await import("./plugin.mjs");
|
|
4645
|
-
const
|
|
4582
|
+
const fs3 = await import("fs/promises");
|
|
4646
4583
|
const pluginManager = new PluginManager2({
|
|
4647
4584
|
config,
|
|
4648
4585
|
isDev: false,
|
|
@@ -4657,9 +4594,9 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
4657
4594
|
buildLifetime: rendererBuildLifetime
|
|
4658
4595
|
});
|
|
4659
4596
|
if (!hasScopedPostcssConfig) {
|
|
4660
|
-
postcssConfigDir = await
|
|
4661
|
-
await
|
|
4662
|
-
|
|
4597
|
+
postcssConfigDir = await fs3.mkdtemp(path8.join(os.tmpdir(), "farm-postcss-"));
|
|
4598
|
+
await fs3.writeFile(
|
|
4599
|
+
path8.join(postcssConfigDir, "postcss.config.cjs"),
|
|
4663
4600
|
"module.exports = { plugins: [] };\n"
|
|
4664
4601
|
);
|
|
4665
4602
|
tailwindVitePlugin = await loadTailwindVitePlugin({
|
|
@@ -4684,7 +4621,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
4684
4621
|
fileName: entry.fileName,
|
|
4685
4622
|
sourceType: "static",
|
|
4686
4623
|
staticInfo: entry.staticInfo,
|
|
4687
|
-
data: (await
|
|
4624
|
+
data: (await fs3.readFile(entry.modulePath)).toString("base64")
|
|
4688
4625
|
});
|
|
4689
4626
|
continue;
|
|
4690
4627
|
}
|
|
@@ -4791,20 +4728,39 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
4791
4728
|
const hasConfiguredRuntimePlugins = Boolean(
|
|
4792
4729
|
hasRuntimeConfigModule && (config.plugins || []).length > 0
|
|
4793
4730
|
);
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4731
|
+
if (hasFarmDocsRuntimeAdapter(config.docs)) {
|
|
4732
|
+
const adapterGuardedPaths = new Set(getFarmDocsGuardedPaths(config, middlewareRoutes));
|
|
4733
|
+
assertFarmDocsAdapterServesNoGuardedPages(
|
|
4734
|
+
config.docs,
|
|
4735
|
+
{ root, srcDir: config.srcDir },
|
|
4736
|
+
(pathname) => adapterGuardedPaths.has(pathname)
|
|
4737
|
+
);
|
|
4738
|
+
}
|
|
4739
|
+
const farmDocsCspNonceMarker = createFarmCspNonce(config.security);
|
|
4740
|
+
const farmDocsPrecompiledManifest = config.docs?.enabled && getFarmPresetRuntime(preset) === "edge" ? await _runWithFarmCspNonce(
|
|
4741
|
+
farmDocsCspNonceMarker,
|
|
4742
|
+
async () => config.docs.adapter?.server ? await compileFarmDocsAdapterEdgeManifest(config.docs, {
|
|
4743
|
+
root,
|
|
4744
|
+
srcDir: config.srcDir,
|
|
4745
|
+
clientEntry: FARM_CLIENT_JS_SRC_PLACEHOLDER,
|
|
4746
|
+
fontStylesheetHref: "/farm-fonts.css",
|
|
4747
|
+
globalStylesheetHref: "/assets/globals.css"
|
|
4748
|
+
}) : await (async () => {
|
|
4749
|
+
const guardedPaths = new Set(getFarmDocsGuardedPaths(config, middlewareRoutes));
|
|
4750
|
+
return compileFarmDocsManifest(config.docs, {
|
|
4751
|
+
root,
|
|
4752
|
+
srcDir: config.srcDir,
|
|
4753
|
+
clientEntry: FARM_CLIENT_JS_SRC_PLACEHOLDER,
|
|
4754
|
+
fontAssets: toFarmDocsPublicFontAssets(resolveFarmDocsFontAssets(root)),
|
|
4755
|
+
fontStylesheetHref: "/farm-fonts.css",
|
|
4756
|
+
globalStylesheetHref: "/assets/globals.css",
|
|
4757
|
+
isPathGuarded: /* @__PURE__ */ __name((pathname) => guardedPaths.has(pathname), "isPathGuarded")
|
|
4758
|
+
});
|
|
4759
|
+
})()
|
|
4760
|
+
) : null;
|
|
4761
|
+
if (farmDocsPrecompiledManifest && farmDocsCspNonceMarker) {
|
|
4762
|
+
farmDocsPrecompiledManifest.cspNonceMarker = farmDocsCspNonceMarker;
|
|
4763
|
+
}
|
|
4808
4764
|
const virtualEntryCode = generateVirtualEntryCode(
|
|
4809
4765
|
apiRoutes,
|
|
4810
4766
|
pageRoutes,
|
|
@@ -5000,7 +4956,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
5000
4956
|
} finally {
|
|
5001
4957
|
if (postcssConfigDir) {
|
|
5002
4958
|
try {
|
|
5003
|
-
await
|
|
4959
|
+
await fs3.rm(postcssConfigDir, { recursive: true, force: true });
|
|
5004
4960
|
} catch {
|
|
5005
4961
|
}
|
|
5006
4962
|
}
|
|
@@ -5014,7 +4970,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
5014
4970
|
__name(buildSSRInMemory, "buildSSRInMemory");
|
|
5015
4971
|
function readFarmAppPackageIdentity(root) {
|
|
5016
4972
|
try {
|
|
5017
|
-
return JSON.parse(readFileSync(
|
|
4973
|
+
return JSON.parse(readFileSync(path8.join(root, "package.json"), "utf8"));
|
|
5018
4974
|
} catch {
|
|
5019
4975
|
return {};
|
|
5020
4976
|
}
|
|
@@ -5034,6 +4990,19 @@ function readFarmPageLastModified(pageRoutes) {
|
|
|
5034
4990
|
return lastModified;
|
|
5035
4991
|
}
|
|
5036
4992
|
__name(readFarmPageLastModified, "readFarmPageLastModified");
|
|
4993
|
+
function getFarmDocsGuardedPaths(config, middlewareRoutes) {
|
|
4994
|
+
if (!config.docs?.enabled) return [];
|
|
4995
|
+
const contentDir = resolveFarmDocsContentDir(config.docs, {
|
|
4996
|
+
root: config.root,
|
|
4997
|
+
srcDir: config.srcDir
|
|
4998
|
+
});
|
|
4999
|
+
const guards = {
|
|
5000
|
+
config: { middleware: config.middleware, integrations: config.integrations },
|
|
5001
|
+
middlewareRoutes
|
|
5002
|
+
};
|
|
5003
|
+
return discoverFarmDocsPages(contentDir, config.docs).flatMap((page) => [page.href, getFarmDocsMarkdownPath(page.href)]).filter((pathname) => farmPathGuardCoversPage(guards, pathname));
|
|
5004
|
+
}
|
|
5005
|
+
__name(getFarmDocsGuardedPaths, "getFarmDocsGuardedPaths");
|
|
5037
5006
|
function getFarmAppOwnedDocsEnginePaths(agent, applicationMetadataRoutes) {
|
|
5038
5007
|
const llmsTxt = agent?.llmsTxt;
|
|
5039
5008
|
const ownedByFile = /* @__PURE__ */ __name((kind) => applicationMetadataRoutes.some(
|
|
@@ -5582,7 +5551,8 @@ function renderFarmRouteServerTree(element) { return element; }`;
|
|
|
5582
5551
|
pattern: ${JSON.stringify(route.pattern)},${route.directory ? `
|
|
5583
5552
|
directory: ${JSON.stringify(route.directory)},` : ""}
|
|
5584
5553
|
module: ${varName},
|
|
5585
|
-
shouldHydrate: ${JSON.stringify(clientMetadata.shouldHydrate)}
|
|
5554
|
+
shouldHydrate: ${JSON.stringify(clientMetadata.shouldHydrate)},${clientMetadata.shouldHydrate ? `
|
|
5555
|
+
clientModule: ${JSON.stringify(toViteModuleId(route.modulePath, config.root))},` : ""}
|
|
5586
5556
|
islandStrategy: ${JSON.stringify(clientMetadata.islandStrategy)},${usesFarmServerTree(clientMetadata) ? "\n serverTree: true," : ""}${renderingDirective ? `
|
|
5587
5557
|
rendering: ${JSON.stringify(renderingDirective)},` : ""}
|
|
5588
5558
|
${route.source !== void 0 ? `markdownSource: {
|
|
@@ -5703,7 +5673,9 @@ function renderFarmRouteServerTree(element) { return element; }`;
|
|
|
5703
5673
|
const productionRuntimeImport = `import {
|
|
5704
5674
|
_getRequestReadCount,
|
|
5705
5675
|
_runWithAfterRequest,
|
|
5676
|
+
_resolveCurrentCspNonce,
|
|
5706
5677
|
_runWithCurrentRequest,
|
|
5678
|
+
_runWithFarmCspNonce,
|
|
5707
5679
|
_runWithAPIRequestRuntime,
|
|
5708
5680
|
_runWithMiddlewareContext,
|
|
5709
5681
|
_runWithMiddlewareData,
|
|
@@ -5713,6 +5685,8 @@ function renderFarmRouteServerTree(element) { return element; }`;
|
|
|
5713
5685
|
appendFarmRedirectQuery,
|
|
5714
5686
|
applyFarmBasePath,
|
|
5715
5687
|
applyFarmCspNonceToResponse,
|
|
5688
|
+
createFarmCspNonce,
|
|
5689
|
+
stampFarmCspNonce,
|
|
5716
5690
|
applyFarmPreviewRobotsTag,
|
|
5717
5691
|
applyFarmThemeDocument,
|
|
5718
5692
|
appendFarmLinkHeader,
|
|
@@ -5734,6 +5708,7 @@ function renderFarmRouteServerTree(element) { return element; }`;
|
|
|
5734
5708
|
createFarmAiCatalogResponse,
|
|
5735
5709
|
createFarmApiCatalogResponse,
|
|
5736
5710
|
createFarmAppManifestResponse,
|
|
5711
|
+
farmPathGuardCoversEndpoint,
|
|
5737
5712
|
collectFarmLlmsTxtPages,
|
|
5738
5713
|
createFarmDefaultLlmsTxt,
|
|
5739
5714
|
createFarmLlmsMarkdownReader,
|
|
@@ -5807,9 +5782,9 @@ import * as farmDocsConfigModule from ${toVirtualEntryImportSpecifier(docsConfig
|
|
|
5807
5782
|
import { dirname as farmDocsDirname, join as farmDocsJoin } from "node:path";
|
|
5808
5783
|
import { fileURLToPath as farmDocsFileURLToPath } from "node:url";` : "";
|
|
5809
5784
|
const markdownHandlerImport = config.md?.enabled ? `import { applyMarkdownNegotiationHeaders, createMarkdownMirrorResponse, getFarmMarkdownAlternatePath } from "@farm.js/core/markdown";` : "";
|
|
5810
|
-
const appMarkdownImport = hasMarkdownPages ? `import { createFarmMarkdownRouteModule, createFarmMarkdownSourceResponse, isFarmMarkdownPublicSourceResponse } from "@farm.js/core/internal/app-markdown-runtime";` : "const createFarmMarkdownSourceResponse = null;\nconst isFarmMarkdownPublicSourceResponse = null;";
|
|
5811
|
-
const markdownErrorImport = `import { FARM_MARKDOWN_CONTENT_TYPE, createFarmMarkdownErrorBody, farmRequestWantsMarkdown } from "@farm.js/core/markdown";`;
|
|
5812
|
-
const mdxComponentsPath = typeof config.mdx?.components === "string" ?
|
|
5785
|
+
const appMarkdownImport = hasMarkdownPages ? `import { FARM_MARKDOWN_ANONYMOUS_CLIENT_ADDRESS, createFarmMarkdownRouteModule, createFarmMarkdownSourceResponse, isFarmMarkdownPublicSourceResponse } from "@farm.js/core/internal/app-markdown-runtime";` : "const createFarmMarkdownSourceResponse = null;\nconst isFarmMarkdownPublicSourceResponse = null;";
|
|
5786
|
+
const markdownErrorImport = `import { FARM_MARKDOWN_CONTENT_TYPE, FARM_MARKDOWN_PAGE_CHECK_HEADER, _isFarmMarkdownPageCheck, createFarmMarkdownErrorBody, farmRequestWantsMarkdown } from "@farm.js/core/markdown";`;
|
|
5787
|
+
const mdxComponentsPath = typeof config.mdx?.components === "string" ? path8.isAbsolute(config.mdx.components) ? config.mdx.components : path8.join(config.root, config.mdx.components) : null;
|
|
5813
5788
|
const mdxComponentsImport = mdxComponentsPath ? `import * as FarmMdxComponentsModule from ${toVirtualEntryImportSpecifier(mdxComponentsPath)};` : "";
|
|
5814
5789
|
const layerConfigPaths = (config.layers || []).map((layer) => layer.configFile).filter((configFile) => Boolean(configFile)).filter((configFile) => configFile !== configModulePath);
|
|
5815
5790
|
const layerConfigImports = layerConfigPaths.map(
|
|
@@ -6213,12 +6188,41 @@ const farmDocsBundledContentDir = ${config.docs?.enabled && !hasPrecompiledDocs
|
|
|
6213
6188
|
})()` : "null"};
|
|
6214
6189
|
const farmDocsResolvedConfig = ${generateFarmDocsRuntimeConfigExpression(config.docs, hasPrecompiledDocs)};
|
|
6215
6190
|
const farmDocsRuntimeRoot = ${hasPrecompiledDocs ? '"."' : `farmDocsBundledContentDir || ${JSON.stringify(config.root)}`};
|
|
6191
|
+
// Docs pages a path-specific guard covers, decided at build time. The docs API and the
|
|
6192
|
+
// root llms/sitemap files answer anyone, so they leave these pages out.
|
|
6193
|
+
const farmDocsGuardedPaths = ${JSON.stringify(
|
|
6194
|
+
hasPrecompiledDocs ? [] : getFarmDocsGuardedPaths(config, middlewareRoutes)
|
|
6195
|
+
)};
|
|
6196
|
+
const farmDocsGuardedPathSet = new Set(farmDocsGuardedPaths);
|
|
6197
|
+
const isFarmDocsPathGuarded = (pathname) => farmDocsGuardedPathSet.has(pathname);
|
|
6216
6198
|
globalThis.__FARM_DOCS_RUNTIME_CONFIG__ = {
|
|
6217
6199
|
root: farmDocsRuntimeRoot,
|
|
6218
6200
|
srcDir: ${JSON.stringify(config.srcDir)},
|
|
6219
6201
|
docs: farmDocsResolvedConfig,
|
|
6202
|
+
guardedPaths: farmDocsGuardedPaths,
|
|
6220
6203
|
};
|
|
6221
6204
|
const farmDocsPrecompiledRuntime = ${hasPrecompiledDocs ? `createFarmDocsPrecompiledRuntime(${JSON.stringify(farmDocsPrecompiledManifest)})` : "null"};
|
|
6205
|
+
// Filled in from the client build once it has finished (see buildNitroUniversal).
|
|
6206
|
+
const farmDocsModulePreloads = (() => {
|
|
6207
|
+
try {
|
|
6208
|
+
return JSON.parse("${FARM_DOCS_MODULE_PRELOADS_PLACEHOLDER}");
|
|
6209
|
+
} catch {
|
|
6210
|
+
return null;
|
|
6211
|
+
}
|
|
6212
|
+
})();
|
|
6213
|
+
// Paths the adapter matches against a page's source path the way the browser
|
|
6214
|
+
// finds the page's module.
|
|
6215
|
+
const farmDocsModulePreloadPaths = farmDocsModulePreloads
|
|
6216
|
+
? {
|
|
6217
|
+
runtime: farmDocsModulePreloads.runtime.map((index) => "/" + farmDocsModulePreloads.files[index]),
|
|
6218
|
+
pages: Object.fromEntries(
|
|
6219
|
+
Object.entries(farmDocsModulePreloads.pages).map(([sourcePath, indexes]) => [
|
|
6220
|
+
sourcePath,
|
|
6221
|
+
indexes.map((index) => "/" + farmDocsModulePreloads.files[index]),
|
|
6222
|
+
]),
|
|
6223
|
+
),
|
|
6224
|
+
}
|
|
6225
|
+
: undefined;
|
|
6222
6226
|
const farmDocsHandler = ${config.docs?.enabled ? hasPrecompiledDocs ? "farmDocsPrecompiledRuntime.handleDocsRequest" : adapterOwnsDocsRuntime ? `createFarmDocsAdapterRuntimeHandler({
|
|
6223
6227
|
${docsConfigModulePath ? "...(farmDocsConfigModule.default || farmDocsConfigModule),\n ...farmDocsResolvedConfig.configOverrides," : "...farmDocsResolvedConfig.config,"}
|
|
6224
6228
|
entry: farmDocsResolvedConfig.config?.entry || String(farmDocsResolvedConfig.entry || "/docs").replace(/^\\/+|\\/+$/g, "") || "docs",
|
|
@@ -6229,6 +6233,9 @@ const farmDocsHandler = ${config.docs?.enabled ? hasPrecompiledDocs ? "farmDocsP
|
|
|
6229
6233
|
// A production build's content cannot change, so the adapter reads its
|
|
6230
6234
|
// navigation once instead of scanning the content directory per request.
|
|
6231
6235
|
immutableContent: true,
|
|
6236
|
+
// List the chunks a page needs, so the browser fetches them alongside the
|
|
6237
|
+
// client entry instead of discovering them one import at a time.
|
|
6238
|
+
modulePreloads: farmDocsModulePreloadPaths,
|
|
6232
6239
|
clientEntry: "/__farm_client_js_src__",
|
|
6233
6240
|
// Font CSS is merged into the client stylesheet; farm-fonts.css only exists when the
|
|
6234
6241
|
// app has fonts, so linking it separately 404'd for apps without them.
|
|
@@ -6251,18 +6258,30 @@ const farmDocsHandler = ${config.docs?.enabled ? hasPrecompiledDocs ? "farmDocsP
|
|
|
6251
6258
|
),
|
|
6252
6259
|
fontStylesheetHref: "/farm-fonts.css",
|
|
6253
6260
|
globalStylesheetHref: "/assets/globals.css",
|
|
6261
|
+
isPathGuarded: isFarmDocsPathGuarded,
|
|
6254
6262
|
})` : "null"};
|
|
6255
|
-
const farmDocsAPIHandler = ${config.docs?.enabled ? hasPrecompiledDocs ? "farmDocsPrecompiledRuntime.handleAPIRequest" : adapterOwnsDocsRuntime ? "null" : `createFarmDocsAPIHandler({ rootDir: farmDocsRuntimeRoot, srcDir: ${JSON.stringify(config.srcDir)}, docs: farmDocsResolvedConfig })` : "null"};
|
|
6263
|
+
const farmDocsAPIHandler = ${config.docs?.enabled ? hasPrecompiledDocs ? "farmDocsPrecompiledRuntime.handleAPIRequest" : adapterOwnsDocsRuntime ? "null" : `createFarmDocsAPIHandler({ rootDir: farmDocsRuntimeRoot, srcDir: ${JSON.stringify(config.srcDir)}, docs: farmDocsResolvedConfig, isPathGuarded: isFarmDocsPathGuarded })` : "null"};
|
|
6256
6264
|
|
|
6257
6265
|
// API routes bundled at build time
|
|
6258
6266
|
const apiRoutes = ${apiRoutes.length > 0 ? "mergePluginAPIRoutes(" : ""}[${apiRegistrations.join(",")}
|
|
6259
|
-
]${apiRoutes.length > 0 ? `, configuredPlugins, ${JSON.stringify(apiRoutes.map(({ path:
|
|
6267
|
+
]${apiRoutes.length > 0 ? `, configuredPlugins, ${JSON.stringify(apiRoutes.map(({ path: path10, methods }) => ({ path: path10, methods })))}, { bodySizeLimit: ${JSON.stringify(config.server.bodySizeLimit)}, dispatch: dispatchFarmPluginAPIRequest })` : ""};
|
|
6260
6268
|
// A plugin calling an app endpoint (an MCP tool, say) goes through the whole
|
|
6261
6269
|
// pipeline, so the endpoint's middleware and integration guards run for it.
|
|
6262
6270
|
function dispatchFarmPluginAPIRequest(request) {
|
|
6263
6271
|
const url = new URL(request.url);
|
|
6264
6272
|
url.pathname = applyFarmBasePath(url.pathname);
|
|
6265
|
-
return
|
|
6273
|
+
return fetchFarmInnerRequest(url.href === request.url ? request : new Request(url, request));
|
|
6274
|
+
}
|
|
6275
|
+
// A request the app makes to itself (a Markdown page check, a plugin's endpoint call) enters
|
|
6276
|
+
// through this module's outer \`fetch\`, as a direct request does: plugin runtime hooks run and
|
|
6277
|
+
// it gets its own request context, so \`cookies()\` and \`headers()\` are its own, never the
|
|
6278
|
+
// caller's. It asks for an identity body: the caller reads it, and the outer response is
|
|
6279
|
+
// compressed once.
|
|
6280
|
+
function fetchFarmInnerRequest(request, context) {
|
|
6281
|
+
if (!request.headers.has("accept-encoding")) return fetch(request, context);
|
|
6282
|
+
const headers = new Headers(request.headers);
|
|
6283
|
+
headers.delete("accept-encoding");
|
|
6284
|
+
return fetch(new Request(request, { headers }), context);
|
|
6266
6285
|
}
|
|
6267
6286
|
const farmLocalAPIBasePath = ${JSON.stringify(resolveFarmAPIServerBasePath(config.api))};
|
|
6268
6287
|
const farmOpenAPIReference = ${JSON.stringify(openAPIReference)};
|
|
@@ -6274,7 +6293,17 @@ ${config.agent?.apiCatalog ? `const farmApiCatalogInput = ${JSON.stringify(resol
|
|
|
6274
6293
|
webmcpTools: config.plugins.some(({ name }) => name === "farm:webmcp") ? collectFarmWebMCPTools(config.root, config.srcDir) : []
|
|
6275
6294
|
})
|
|
6276
6295
|
)};
|
|
6277
|
-
${servesDefaultMCP ? "farmAppManifestInput.defaultMCP = getFarmDefaultMCPServer;\n" : ""}
|
|
6296
|
+
${servesDefaultMCP ? "farmAppManifestInput.defaultMCP = getFarmDefaultMCPServer;\n" : ""}// A guard written for an MCP server's path keeps its tools out of the public view.
|
|
6297
|
+
farmAppManifestInput.guardCoversPath = (path) =>
|
|
6298
|
+
farmPathGuardCoversEndpoint(
|
|
6299
|
+
{
|
|
6300
|
+
config: { middleware: farmMiddlewareConfig, integrations: serverRuntimeIntegrations },
|
|
6301
|
+
middlewareRoutes: fileMiddlewareModules,
|
|
6302
|
+
},
|
|
6303
|
+
path,
|
|
6304
|
+
farmLocalAPIBasePath,
|
|
6305
|
+
);
|
|
6306
|
+
` : ""}
|
|
6278
6307
|
function isFarmLocalAPIPathname(pathname) {
|
|
6279
6308
|
return farmLocalAPIBasePath !== "/" &&
|
|
6280
6309
|
(pathname === farmLocalAPIBasePath ||
|
|
@@ -6374,15 +6403,26 @@ function renderFarmClientBootstrapScript(canonicalPath, selectedRouteSlots, page
|
|
|
6374
6403
|
}
|
|
6375
6404
|
return '<script id="__farm_route_slots_data__" type="application/json">' +
|
|
6376
6405
|
serializedRouteSlots +
|
|
6377
|
-
'</script
|
|
6406
|
+
'</script>' + stampFarmCspNonce('<script>' + source + '</script>');
|
|
6378
6407
|
}
|
|
6379
6408
|
|
|
6380
6409
|
function renderFarmRendererHydrationScript() {
|
|
6381
6410
|
return typeof ReactDOMServer.generateHydrationScript === "function"
|
|
6382
|
-
? ReactDOMServer.generateHydrationScript()
|
|
6411
|
+
? stampFarmCspNonce(ReactDOMServer.generateHydrationScript())
|
|
6383
6412
|
: "";
|
|
6384
6413
|
}
|
|
6385
6414
|
|
|
6415
|
+
function renderFarmClientEntryScript() {
|
|
6416
|
+
return stampFarmCspNonce('<script type="module" src="/__farm_client_js_src__"></script>');
|
|
6417
|
+
}
|
|
6418
|
+
|
|
6419
|
+
// Renderer options for the response being rendered: its CSP nonce, which the
|
|
6420
|
+
// renderer puts on the inline scripts it emits.
|
|
6421
|
+
function getFarmRendererRenderOptions() {
|
|
6422
|
+
const nonce = _resolveCurrentCspNonce();
|
|
6423
|
+
return nonce ? { nonce } : undefined;
|
|
6424
|
+
}
|
|
6425
|
+
|
|
6386
6426
|
function escapeFarmHtmlAttribute(value) {
|
|
6387
6427
|
return String(value)
|
|
6388
6428
|
.replace(/&/g, "&")
|
|
@@ -6424,6 +6464,7 @@ async function renderFarmElement(ReactDOMServer, element, routeKey) {
|
|
|
6424
6464
|
if (farmRendererStreamingCapabilities.web &&
|
|
6425
6465
|
typeof ReactDOMServer.renderToReadableStream === "function") {
|
|
6426
6466
|
const stream = await ReactDOMServer.renderToReadableStream(element, {
|
|
6467
|
+
nonce: _resolveCurrentCspNonce(),
|
|
6427
6468
|
onError(error) {
|
|
6428
6469
|
// redirect()/notFound() are control flow, not render failures: the
|
|
6429
6470
|
// request handler must still receive them to map the response status,
|
|
@@ -6556,6 +6597,7 @@ async function renderFarmElement(ReactDOMServer, element, routeKey) {
|
|
|
6556
6597
|
},
|
|
6557
6598
|
};
|
|
6558
6599
|
pipeableStream = ReactDOMServer.renderToPipeableStream(element, {
|
|
6600
|
+
nonce: _resolveCurrentCspNonce(),
|
|
6559
6601
|
onShellReady() {
|
|
6560
6602
|
try {
|
|
6561
6603
|
pipeableStream.pipe(destination);
|
|
@@ -6618,7 +6660,10 @@ async function renderFarmElement(ReactDOMServer, element, routeKey) {
|
|
|
6618
6660
|
}
|
|
6619
6661
|
|
|
6620
6662
|
if (ReactDOMServer.renderToStringWithHead) {
|
|
6621
|
-
const rendered = await ReactDOMServer.renderToStringWithHead(
|
|
6663
|
+
const rendered = await ReactDOMServer.renderToStringWithHead(
|
|
6664
|
+
element,
|
|
6665
|
+
getFarmRendererRenderOptions(),
|
|
6666
|
+
);
|
|
6622
6667
|
return {
|
|
6623
6668
|
html: rendered.html,
|
|
6624
6669
|
head: rendered.head || "",
|
|
@@ -6626,7 +6671,7 @@ async function renderFarmElement(ReactDOMServer, element, routeKey) {
|
|
|
6626
6671
|
streamErrors,
|
|
6627
6672
|
};
|
|
6628
6673
|
}
|
|
6629
|
-
const html = await ReactDOMServer.renderToString(element);
|
|
6674
|
+
const html = await ReactDOMServer.renderToString(element, getFarmRendererRenderOptions());
|
|
6630
6675
|
return { html, head: "", shellHtml: html, streamErrors };
|
|
6631
6676
|
}
|
|
6632
6677
|
|
|
@@ -6665,7 +6710,7 @@ function renderFarmElementSync(ReactDOMServer, element, routeKey) {
|
|
|
6665
6710
|
if (typeof ReactDOMServer.renderToString !== "function") return undefined;
|
|
6666
6711
|
let html;
|
|
6667
6712
|
try {
|
|
6668
|
-
html = ReactDOMServer.renderToString(element);
|
|
6713
|
+
html = ReactDOMServer.renderToString(element, getFarmRendererRenderOptions());
|
|
6669
6714
|
} catch {
|
|
6670
6715
|
html = undefined;
|
|
6671
6716
|
}
|
|
@@ -6680,6 +6725,8 @@ function renderFarmElementSync(ReactDOMServer, element, routeKey) {
|
|
|
6680
6725
|
function createFarmDocumentStream(contentStream, prefix, suffix, onComplete) {
|
|
6681
6726
|
const encoder = new TextEncoder();
|
|
6682
6727
|
const reader = contentStream.getReader();
|
|
6728
|
+
// The suffix renders after the handler returned, outside its async scope.
|
|
6729
|
+
const cspNonce = _resolveCurrentCspNonce();
|
|
6683
6730
|
return new ReadableStream({
|
|
6684
6731
|
start(controller) {
|
|
6685
6732
|
controller.enqueue(encoder.encode(prefix));
|
|
@@ -6688,7 +6735,9 @@ function createFarmDocumentStream(contentStream, prefix, suffix, onComplete) {
|
|
|
6688
6735
|
try {
|
|
6689
6736
|
const result = await reader.read();
|
|
6690
6737
|
if (result.done) {
|
|
6691
|
-
const tail = typeof suffix === "function"
|
|
6738
|
+
const tail = typeof suffix === "function"
|
|
6739
|
+
? await _runWithFarmCspNonce(cspNonce, suffix)
|
|
6740
|
+
: suffix;
|
|
6692
6741
|
controller.enqueue(encoder.encode(tail));
|
|
6693
6742
|
if (onComplete) onComplete();
|
|
6694
6743
|
controller.close();
|
|
@@ -6810,18 +6859,18 @@ function createFarmErrorDocument(html, title) {
|
|
|
6810
6859
|
' <meta name="viewport" content="width=device-width, initial-scale=1">\\n' +
|
|
6811
6860
|
' <link rel="icon" href="data:,">\\n' +
|
|
6812
6861
|
' <title>' + escapedTitle + '</title>\\n' +
|
|
6813
|
-
' <link rel="stylesheet" href="/__farm_client_css_href__"
|
|
6862
|
+
' <link rel="stylesheet" href="/__farm_client_css_href__">' + renderFarmClientModulePreloads(html) + '\\n' +
|
|
6814
6863
|
renderFarmRendererHydrationScript() + '\\n' +
|
|
6815
6864
|
'</head>\\n<body>\\n' +
|
|
6816
6865
|
' <div id="root">' + html + '</div>\\n' +
|
|
6817
6866
|
' ' + renderFarmClientBootstrapScript() + '\\n' +
|
|
6818
|
-
'
|
|
6867
|
+
' ' + renderFarmClientEntryScript() + '\\n' +
|
|
6819
6868
|
'</body>\\n</html>';
|
|
6820
6869
|
}
|
|
6821
6870
|
|
|
6822
6871
|
let fullHtml = ensureFarmDocumentRoot(ensureFarmDocumentHead(fullDocument));
|
|
6823
6872
|
fullHtml = fullHtml
|
|
6824
|
-
.replace(/<head([^>]*)>/i, '<head
|
|
6873
|
+
.replace(/<head([^>]*)>/i, function(match, attrs) { return '<head' + attrs + '>\\n <link rel="stylesheet" href="/__farm_client_css_href__">' + renderFarmClientModulePreloads(fullDocument); })
|
|
6825
6874
|
// Function replacements: dynamic markup may contain $-sequences ($&, $', $$)
|
|
6826
6875
|
// that a string replacement would expand, corrupting the document.
|
|
6827
6876
|
.replace(/<\\/head>/i, function() { return renderFarmRendererHydrationScript() + '\\n</head>'; })
|
|
@@ -6834,7 +6883,7 @@ function createFarmErrorDocument(html, title) {
|
|
|
6834
6883
|
/<\\/body>/i,
|
|
6835
6884
|
function() {
|
|
6836
6885
|
return ' ' + renderFarmClientBootstrapScript() + '\\n' +
|
|
6837
|
-
'
|
|
6886
|
+
' ' + renderFarmClientEntryScript() + '\\n</body>';
|
|
6838
6887
|
},
|
|
6839
6888
|
);
|
|
6840
6889
|
return fullHtml.trim().startsWith("<!DOCTYPE")
|
|
@@ -6842,6 +6891,53 @@ function createFarmErrorDocument(html, title) {
|
|
|
6842
6891
|
: "<!DOCTYPE html>\\n" + fullHtml;
|
|
6843
6892
|
}
|
|
6844
6893
|
|
|
6894
|
+
// The client modules a page needs before it hydrates, filled in from the client
|
|
6895
|
+
// build once it has finished (see buildNitroUniversal).
|
|
6896
|
+
const farmClientModulePreloads = (() => {
|
|
6897
|
+
try {
|
|
6898
|
+
return JSON.parse("${FARM_CLIENT_MODULE_PRELOADS_PLACEHOLDER}");
|
|
6899
|
+
} catch {
|
|
6900
|
+
return null;
|
|
6901
|
+
}
|
|
6902
|
+
})();
|
|
6903
|
+
const farmClientEntryPreloadTags = farmClientModulePreloads
|
|
6904
|
+
? farmClientModulePreloads.entry.map(renderFarmClientModulePreload).join("")
|
|
6905
|
+
: "";
|
|
6906
|
+
// The client modules a document's markup loads: its islands' boundaries and the
|
|
6907
|
+
// client references of its server tree.
|
|
6908
|
+
const FARM_CLIENT_MODULE_REFERENCE_PATTERN = /data-farm-client-boundary="([^"]+)"|"r":"(\\/[^"]+)"/g;
|
|
6909
|
+
|
|
6910
|
+
function renderFarmClientModulePreload(index) {
|
|
6911
|
+
return '\\n <link rel="modulepreload" href="/' +
|
|
6912
|
+
escapeFarmHtmlAttribute(farmClientModulePreloads.files[index]) +
|
|
6913
|
+
'" fetchpriority="low">';
|
|
6914
|
+
}
|
|
6915
|
+
|
|
6916
|
+
// The modulepreload links for a document: the entry's static imports, then the
|
|
6917
|
+
// modules its hydrating page and its markup load.
|
|
6918
|
+
function renderFarmClientModulePreloads(markup, pageModule) {
|
|
6919
|
+
// A nonce policy blocks parser-inserted links without the nonce, and the
|
|
6920
|
+
// response filter manages nonces on script elements only, so CSP nonce mode
|
|
6921
|
+
// keeps the documents it had.
|
|
6922
|
+
if (!farmClientModulePreloads || (farmSecurityConfig.csp && farmSecurityConfig.csp.nonce)) return "";
|
|
6923
|
+
const modules = farmClientModulePreloads.modules;
|
|
6924
|
+
const listed = new Set();
|
|
6925
|
+
let tags = farmClientEntryPreloadTags;
|
|
6926
|
+
const add = (moduleId) => {
|
|
6927
|
+
if (!moduleId || !Object.prototype.hasOwnProperty.call(modules, moduleId)) return;
|
|
6928
|
+
for (const index of modules[moduleId]) {
|
|
6929
|
+
if (listed.has(index)) continue;
|
|
6930
|
+
listed.add(index);
|
|
6931
|
+
tags += renderFarmClientModulePreload(index);
|
|
6932
|
+
}
|
|
6933
|
+
};
|
|
6934
|
+
add(pageModule);
|
|
6935
|
+
if (typeof markup === "string") {
|
|
6936
|
+
for (const match of markup.matchAll(FARM_CLIENT_MODULE_REFERENCE_PATTERN)) add(match[1] || match[2]);
|
|
6937
|
+
}
|
|
6938
|
+
return tags;
|
|
6939
|
+
}
|
|
6940
|
+
|
|
6845
6941
|
// The origin hreflang alternates resolve against when the route sets no
|
|
6846
6942
|
// metadataBase. Forwarded authority counts only under server.trustProxy, the
|
|
6847
6943
|
// same rule the development server applies.
|
|
@@ -6874,7 +6970,7 @@ function applyFarmI18nDocument(html, requestPath, snapshot, request, metadata) {
|
|
|
6874
6970
|
});
|
|
6875
6971
|
const runtimeMarkup =
|
|
6876
6972
|
renderFarmI18nAlternateLinks(requestPath, snapshot, request, metadata) +
|
|
6877
|
-
'<script>window.__FARM_I18N__ = ' + serializeFarmInlineValue(snapshot) + ';</script>';
|
|
6973
|
+
stampFarmCspNonce('<script>window.__FARM_I18N__ = ' + serializeFarmInlineValue(snapshot) + ';</script>');
|
|
6878
6974
|
nextHtml = nextHtml.replace(/<head([^>]*)>/i, function(_match, attributes) {
|
|
6879
6975
|
// Function replacement: runtimeMarkup may contain $-sequences ($&, $', $$).
|
|
6880
6976
|
return '<head' + attributes + '>' + runtimeMarkup;
|
|
@@ -6944,6 +7040,26 @@ function hasPrivateFarmRequestHeaders(request, farmLocaleResolution) {
|
|
|
6944
7040
|
);
|
|
6945
7041
|
}
|
|
6946
7042
|
|
|
7043
|
+
// A docs response a guard let this visitor read is theirs, as for pages: one for a
|
|
7044
|
+
// request with credentials, or with middleware request data, never fills a shared cache.
|
|
7045
|
+
// Middleware headers cannot do this, since they never replace a response's own.
|
|
7046
|
+
function withFarmDocsRequestCache(response, request, farmLocaleResolution, middlewareData, middlewareContext) {
|
|
7047
|
+
if (
|
|
7048
|
+
!hasPrivateFarmRequestHeaders(request, farmLocaleResolution) &&
|
|
7049
|
+
!middlewareData?.size &&
|
|
7050
|
+
!middlewareContext?.size
|
|
7051
|
+
) {
|
|
7052
|
+
return response;
|
|
7053
|
+
}
|
|
7054
|
+
const headers = new Headers(response.headers);
|
|
7055
|
+
headers.set("Cache-Control", "private, no-store");
|
|
7056
|
+
return farmOwnedResponse(response.body, {
|
|
7057
|
+
status: response.status,
|
|
7058
|
+
statusText: response.statusText,
|
|
7059
|
+
headers,
|
|
7060
|
+
});
|
|
7061
|
+
}
|
|
7062
|
+
|
|
6947
7063
|
${generateRuntimePathMatcherSource()}
|
|
6948
7064
|
|
|
6949
7065
|
function getMatchingErrorBoundary(pathname) {
|
|
@@ -7174,6 +7290,27 @@ function createFarmAgentRobotsResponse(request) {
|
|
|
7174
7290
|
);
|
|
7175
7291
|
}
|
|
7176
7292
|
` : ""}
|
|
7293
|
+
// Static pages a path-specific guard covers (non-root middleware.ts, a config or
|
|
7294
|
+
// integration middleware matcher naming the path), decided at build time.
|
|
7295
|
+
// sitemap.xml, llms.txt and the default MCP server never list them, nor a page behind
|
|
7296
|
+
// a route guard.
|
|
7297
|
+
const farmAgentGuardedPages = new Set(${JSON.stringify(
|
|
7298
|
+
pageRoutes.map((route) => route.pattern).filter(
|
|
7299
|
+
(pattern) => !pattern.includes("[") && farmPathGuardCoversPage(
|
|
7300
|
+
{
|
|
7301
|
+
config: { middleware: config.middleware, integrations: config.integrations },
|
|
7302
|
+
middlewareRoutes
|
|
7303
|
+
},
|
|
7304
|
+
pattern
|
|
7305
|
+
)
|
|
7306
|
+
)
|
|
7307
|
+
)});
|
|
7308
|
+
function getFarmAgentListedPageRoutes() {
|
|
7309
|
+
return pageRoutes.filter(
|
|
7310
|
+
(route) =>
|
|
7311
|
+
!farmAgentGuardedPages.has(route.pattern) && !(route.module && route.module.__farmRouteGuard),
|
|
7312
|
+
);
|
|
7313
|
+
}
|
|
7177
7314
|
${servesAgentSitemap ? `// sitemap.xml from agent.sitemap, built the same way as in development. Each page's
|
|
7178
7315
|
// lastmod is its file's modification time, read at build time.
|
|
7179
7316
|
const farmAgentSitemapConfig = ${JSON.stringify(config.agent.sitemap)};
|
|
@@ -7183,7 +7320,7 @@ function createFarmAgentSitemapResponse(request) {
|
|
|
7183
7320
|
return createFarmMetadataRouteResponse(
|
|
7184
7321
|
"sitemap",
|
|
7185
7322
|
createFarmDefaultSitemap(
|
|
7186
|
-
|
|
7323
|
+
getFarmAgentListedPageRoutes().map((route) => ({
|
|
7187
7324
|
pattern: route.pattern,
|
|
7188
7325
|
module: route.module,
|
|
7189
7326
|
lastModified: farmAgentSitemapLastModified[route.pattern],
|
|
@@ -7222,7 +7359,7 @@ async function handleFarmDefaultMCP(request) {
|
|
|
7222
7359
|
basePath: ${JSON.stringify(config.basePath)},
|
|
7223
7360
|
listPages: () =>
|
|
7224
7361
|
collectFarmDefaultMCPPages(
|
|
7225
|
-
|
|
7362
|
+
getFarmAgentListedPageRoutes().map((route) => ({ pattern: route.pattern, module: route.module })),
|
|
7226
7363
|
{ origin, basePath: ${JSON.stringify(config.basePath)}, markdown: farmMarkdownConfig },
|
|
7227
7364
|
),
|
|
7228
7365
|
// A fresh request through this handler, so the caller's cookies never shape a page.
|
|
@@ -7234,13 +7371,15 @@ async function handleFarmDefaultMCP(request) {
|
|
|
7234
7371
|
},
|
|
7235
7372
|
});
|
|
7236
7373
|
}
|
|
7237
|
-
|
|
7374
|
+
// \`fetch\` is this module's outer request entry: plugin runtime hooks run and the page
|
|
7375
|
+
// gets its own request context, as for a direct request.
|
|
7376
|
+
const farmDefaultMCPReadMarkdown = createFarmLlmsMarkdownReader((page) => fetch(page));
|
|
7238
7377
|
` : ""}
|
|
7239
7378
|
// Static pages and root metadata for llms.txt, built the same way as in development.
|
|
7240
7379
|
function createFarmLlmsTxtContext(request, full) {
|
|
7241
7380
|
const origin = new URL(request.url).origin;
|
|
7242
7381
|
const pages = collectFarmLlmsTxtPages(
|
|
7243
|
-
|
|
7382
|
+
getFarmAgentListedPageRoutes().map((route) => ({ pattern: route.pattern, metadata: route.module && route.module.metadata })),
|
|
7244
7383
|
{
|
|
7245
7384
|
origin,
|
|
7246
7385
|
markdown: farmMarkdownConfig,
|
|
@@ -7261,14 +7400,15 @@ function createFarmLlmsTxtContext(request, full) {
|
|
|
7261
7400
|
apiServerBasePath: farmLocalAPIBasePath,${servesDefaultMCP ? "\n defaultMCP: getFarmDefaultMCPServer," : ""}
|
|
7262
7401
|
}),` : ""}
|
|
7263
7402
|
}),
|
|
7264
|
-
// llms-full.txt reads each page's .md mirror through this
|
|
7265
|
-
//
|
|
7266
|
-
//
|
|
7403
|
+
// llms-full.txt reads each page's .md mirror through this module's outer
|
|
7404
|
+
// request entry, so plugin runtime hooks run and each read has a fresh request
|
|
7405
|
+
// context: the caller's cookies never shape its content. HEAD discards the
|
|
7406
|
+
// body, so it reads nothing.
|
|
7267
7407
|
...(full
|
|
7268
7408
|
? {
|
|
7269
7409
|
markdown: request.method.toUpperCase() === "HEAD"
|
|
7270
7410
|
? async () => null
|
|
7271
|
-
: createFarmLlmsMarkdownReader((page) =>
|
|
7411
|
+
: createFarmLlmsMarkdownReader((page) => fetch(page)),
|
|
7272
7412
|
}
|
|
7273
7413
|
: {}),
|
|
7274
7414
|
};
|
|
@@ -7716,7 +7856,7 @@ ${config.docs?.enabled ? `async function wrapFarmDocsResponseWithLayouts(request
|
|
|
7716
7856
|
if (!html.includes('src="/__farm_client_js_src__"')) {
|
|
7717
7857
|
html = html.replace(
|
|
7718
7858
|
/<[/]body>/i,
|
|
7719
|
-
'
|
|
7859
|
+
function() { return ' ' + renderFarmClientEntryScript() + '\\n</body>'; },
|
|
7720
7860
|
);
|
|
7721
7861
|
}
|
|
7722
7862
|
if (!html.includes('window._$HY')) {
|
|
@@ -7753,6 +7893,9 @@ function resolvePPRConfig(route) {
|
|
|
7753
7893
|
}
|
|
7754
7894
|
|
|
7755
7895
|
function getPPRShellBypassReason(request, middlewareData, middlewareContext) {
|
|
7896
|
+
// A shared shell would carry one response's nonce to every visitor, where
|
|
7897
|
+
// the nonce filter strips it and Farm's scripts stop running.
|
|
7898
|
+
if (farmSecurityConfig.csp && farmSecurityConfig.csp.nonce) return "csp-nonce";
|
|
7756
7899
|
const method = request.method.toUpperCase();
|
|
7757
7900
|
if (method !== "GET" && method !== "HEAD") return "method";
|
|
7758
7901
|
if (request.headers.get("cookie")) return "cookie";
|
|
@@ -8030,11 +8173,17 @@ async function handleFarmRequestInContext(
|
|
|
8030
8173
|
const docsResponse = await farmDocsHandler(cloneFarmRequestWithContext(request));
|
|
8031
8174
|
if (docsResponse) {
|
|
8032
8175
|
if (!docsResponse.headers.get("content-type")?.toLowerCase().includes("text/html")) {
|
|
8033
|
-
return applyProductionMiddlewareHeaders(
|
|
8176
|
+
return applyProductionMiddlewareHeaders(
|
|
8177
|
+
withFarmDocsRequestCache(docsResponse, request, farmLocaleResolution, middlewareData, middlewareContext),
|
|
8178
|
+
middlewareHeaders,
|
|
8179
|
+
);
|
|
8034
8180
|
}
|
|
8035
|
-
const wrappedDocsResponse =
|
|
8181
|
+
const wrappedDocsResponse = withFarmDocsRequestCache(
|
|
8182
|
+
await wrapFarmDocsResponseWithLayouts(request, docsResponse),
|
|
8036
8183
|
request,
|
|
8037
|
-
|
|
8184
|
+
farmLocaleResolution,
|
|
8185
|
+
middlewareData,
|
|
8186
|
+
middlewareContext,
|
|
8038
8187
|
);
|
|
8039
8188
|
const docsHeaders = new Headers(wrappedDocsResponse.headers);
|
|
8040
8189
|
docsHeaders.set("x-farm-preload-buffered", "1");
|
|
@@ -8058,7 +8207,13 @@ async function handleFarmRequestInContext(
|
|
|
8058
8207
|
const match = matchPageRoute(getFarmRoutePathname(targetPathname));
|
|
8059
8208
|
return match?.route?.markdownSource || null;
|
|
8060
8209
|
},
|
|
8061
|
-
|
|
8210
|
+
clientAddress: adapterContext?.clientAddress,
|
|
8211
|
+
// An anonymous visitor's request: guards never see the caller's address.
|
|
8212
|
+
renderPage: (targetRequest) =>
|
|
8213
|
+
fetchFarmInnerRequest(targetRequest, {
|
|
8214
|
+
...adapterContext,
|
|
8215
|
+
clientAddress: FARM_MARKDOWN_ANONYMOUS_CLIENT_ADDRESS,
|
|
8216
|
+
}),
|
|
8062
8217
|
});
|
|
8063
8218
|
if (markdownSourceResponse) {
|
|
8064
8219
|
return isFarmMarkdownPublicSourceResponse(markdownSourceResponse)
|
|
@@ -8078,7 +8233,7 @@ async function handleFarmRequestInContext(
|
|
|
8078
8233
|
config: farmMarkdownConfig,
|
|
8079
8234
|
routeExists: (targetPathname) =>
|
|
8080
8235
|
Boolean(matchPageRoute(getFarmRoutePathname(targetPathname))),
|
|
8081
|
-
renderPage: (targetRequest) =>
|
|
8236
|
+
renderPage: (targetRequest) => fetchFarmInnerRequest(targetRequest, adapterContext),
|
|
8082
8237
|
apiServerBasePath: farmLocalAPIBasePath,
|
|
8083
8238
|
});
|
|
8084
8239
|
if (markdownResponse) {
|
|
@@ -8129,7 +8284,7 @@ async function handleFarmRequestInContext(
|
|
|
8129
8284
|
) {
|
|
8130
8285
|
const method = request.method.toUpperCase();
|
|
8131
8286
|
const response = method === "GET" || method === "HEAD"
|
|
8132
|
-
? farmOwnedResponse(method === "HEAD" ? null : farmOpenAPIReference.html, {
|
|
8287
|
+
? farmOwnedResponse(method === "HEAD" ? null : stampFarmCspNonce(farmOpenAPIReference.html), {
|
|
8133
8288
|
status: 200,
|
|
8134
8289
|
headers: {
|
|
8135
8290
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -8249,7 +8404,10 @@ async function handleFarmRequestInContext(
|
|
|
8249
8404
|
${config.docs?.enabled ? `if (farmDocsAPIHandler && isFarmDocsAPIRequest(pathname)) {
|
|
8250
8405
|
const docsAPIResponse = await farmDocsAPIHandler(cloneFarmRequestWithContext(request));
|
|
8251
8406
|
if (docsAPIResponse) {
|
|
8252
|
-
return applyProductionMiddlewareHeaders(
|
|
8407
|
+
return applyProductionMiddlewareHeaders(
|
|
8408
|
+
withFarmDocsRequestCache(docsAPIResponse, request, farmLocaleResolution, middlewareData, middlewareContext),
|
|
8409
|
+
middlewareHeaders,
|
|
8410
|
+
);
|
|
8253
8411
|
}
|
|
8254
8412
|
}` : ""}
|
|
8255
8413
|
|
|
@@ -8763,13 +8921,16 @@ async function handleFarmRequestInContext(
|
|
|
8763
8921
|
|
|
8764
8922
|
// Stream a suspended body as soon as React's shell is ready. Full-document
|
|
8765
8923
|
// layouts, localized documents, and cacheable PPR shells still use the
|
|
8766
|
-
// buffered path because they require whole-document transformation
|
|
8924
|
+
// buffered path because they require whole-document transformation, and so
|
|
8925
|
+
// does the anonymous check behind a page's Markdown source: there, a
|
|
8926
|
+
// redirect() under a loading boundary must still decide the status.
|
|
8767
8927
|
if (
|
|
8768
8928
|
pageStatus === 200 &&
|
|
8769
8929
|
renderedPage.stream &&
|
|
8770
8930
|
!hasFullDocument &&
|
|
8771
8931
|
!farmI18nSnapshot &&
|
|
8772
|
-
!pprCacheKey
|
|
8932
|
+
!pprCacheKey &&
|
|
8933
|
+
!_isFarmMarkdownPageCheck(request.headers.get(FARM_MARKDOWN_PAGE_CHECK_HEADER))
|
|
8773
8934
|
) {
|
|
8774
8935
|
const farmThemeDocument = createFarmThemeDocumentParts(
|
|
8775
8936
|
farmThemeConfig,
|
|
@@ -8783,7 +8944,7 @@ async function handleFarmRequestInContext(
|
|
|
8783
8944
|
(hasFavicon ? '' : ' <link rel="icon" href="data:,">\\n') +
|
|
8784
8945
|
' <title>' + title + '</title>' + metaTags + '\\n' +
|
|
8785
8946
|
' <link rel="stylesheet" href="/__farm_client_css_href__">\\n' +
|
|
8786
|
-
' <link rel="modulepreload" href="/__farm_client_js_src__"
|
|
8947
|
+
' <link rel="modulepreload" href="/__farm_client_js_src__">' + renderFarmClientModulePreloads(null, route.clientModule) + '\\n' +
|
|
8787
8948
|
renderFarmRendererHydrationScript() + '\\n' +
|
|
8788
8949
|
'</head>\\n<body>\\n <div id="root">';
|
|
8789
8950
|
const streamSuffix = '</div>\\n' +
|
|
@@ -8792,7 +8953,7 @@ async function handleFarmRequestInContext(
|
|
|
8792
8953
|
routeSlotPayload,
|
|
8793
8954
|
clientPageProps
|
|
8794
8955
|
) + '\\n' +
|
|
8795
|
-
'
|
|
8956
|
+
' ' + renderFarmClientEntryScript() + '\\n' +
|
|
8796
8957
|
'</body>\\n</html>';
|
|
8797
8958
|
const themedStreamPrefix = streamPrefix.replace(
|
|
8798
8959
|
'<html lang="en">',
|
|
@@ -8816,7 +8977,8 @@ async function handleFarmRequestInContext(
|
|
|
8816
8977
|
try {
|
|
8817
8978
|
return createLateNotFoundRecovery(
|
|
8818
8979
|
await ReactDOMServer.renderToString(
|
|
8819
|
-
wrapWithFarmIntegrationProviders(createFarmNotFoundElement(pathname))
|
|
8980
|
+
wrapWithFarmIntegrationProviders(createFarmNotFoundElement(pathname)),
|
|
8981
|
+
getFarmRendererRenderOptions()
|
|
8820
8982
|
)
|
|
8821
8983
|
) + streamSuffix;
|
|
8822
8984
|
} catch (error) {
|
|
@@ -8824,7 +8986,10 @@ async function handleFarmRequestInContext(
|
|
|
8824
8986
|
// needs their context cannot render alone, so use Farm's.
|
|
8825
8987
|
console.warn("not-found page could not render outside its layout, using Farm's:", error);
|
|
8826
8988
|
return createLateNotFoundRecovery(
|
|
8827
|
-
await ReactDOMServer.renderToString(
|
|
8989
|
+
await ReactDOMServer.renderToString(
|
|
8990
|
+
React.createElement(FarmDefault404Page),
|
|
8991
|
+
getFarmRendererRenderOptions()
|
|
8992
|
+
)
|
|
8828
8993
|
) + streamSuffix;
|
|
8829
8994
|
}
|
|
8830
8995
|
},
|
|
@@ -8873,7 +9038,7 @@ async function handleFarmRequestInContext(
|
|
|
8873
9038
|
);
|
|
8874
9039
|
fullHtml = html
|
|
8875
9040
|
// Inject CSS link after opening head tag or first meta tag
|
|
8876
|
-
.replace(/<head([^>]*)>/i, '<head
|
|
9041
|
+
.replace(/<head([^>]*)>/i, function(match, attrs) { return '<head' + attrs + '>\\n <link rel="stylesheet" href="/__farm_client_css_href__">' + renderFarmClientModulePreloads(html, route.clientModule); })
|
|
8877
9042
|
.replace(/<\\/head>/i, () => renderFarmRendererHydrationScript() + '\\n</head>')
|
|
8878
9043
|
// Explicit metadata wins over renderer and layout titles. Without
|
|
8879
9044
|
// explicit metadata, a renderer title wins over the layout title.
|
|
@@ -8907,7 +9072,7 @@ async function handleFarmRequestInContext(
|
|
|
8907
9072
|
routeSlotPayload,
|
|
8908
9073
|
clientPageProps
|
|
8909
9074
|
) + '\\n' +
|
|
8910
|
-
'
|
|
9075
|
+
' ' + renderFarmClientEntryScript() + '\\n</body>',
|
|
8911
9076
|
);
|
|
8912
9077
|
|
|
8913
9078
|
// Last, so the charset (and the viewport, unless the layout wrote one) open the head.
|
|
@@ -8926,13 +9091,13 @@ async function handleFarmRequestInContext(
|
|
|
8926
9091
|
\${viewportTags}
|
|
8927
9092
|
\${hasFavicon ? "" : '<link rel="icon" href="data:,">'}
|
|
8928
9093
|
\${suppressDefaultTitle ? "" : "<title>" + title + "</title>"}\${metaTags}\${rendererHead ? "\\n " + rendererHead : ""}
|
|
8929
|
-
<link rel="stylesheet" href="/__farm_client_css_href__"
|
|
9094
|
+
<link rel="stylesheet" href="/__farm_client_css_href__">\${renderFarmClientModulePreloads(html, route.clientModule)}
|
|
8930
9095
|
\${renderFarmRendererHydrationScript()}
|
|
8931
9096
|
</head>
|
|
8932
9097
|
<body>
|
|
8933
9098
|
<div id="root">\${html}</div>
|
|
8934
9099
|
\${renderFarmClientBootstrapScript(pageProps.__farmCanonicalPath, routeSlotPayload, clientPageProps)}
|
|
8935
|
-
|
|
9100
|
+
\${renderFarmClientEntryScript()}
|
|
8936
9101
|
</body>
|
|
8937
9102
|
</html>\`;
|
|
8938
9103
|
}
|
|
@@ -9104,14 +9269,14 @@ async function handleFarmRequestInContext(
|
|
|
9104
9269
|
}
|
|
9105
9270
|
}
|
|
9106
9271
|
|
|
9107
|
-
const fallbackHtml = createDefaultErrorMarkup({
|
|
9272
|
+
const fallbackHtml = stampFarmCspNonce(createDefaultErrorMarkup({
|
|
9108
9273
|
statusCode: errorStatus,
|
|
9109
9274
|
statusText: errorStatusText,
|
|
9110
9275
|
requestPath: pathname,
|
|
9111
9276
|
method: request.method,
|
|
9112
9277
|
development: false,
|
|
9113
9278
|
mode: "production",
|
|
9114
|
-
});
|
|
9279
|
+
}));
|
|
9115
9280
|
const fallbackDocument = applyFarmThemeDocument(
|
|
9116
9281
|
applyFarmI18nDocument(
|
|
9117
9282
|
createFarmErrorDocument(
|
|
@@ -9198,7 +9363,7 @@ ${servesDefaultMCP ? `
|
|
|
9198
9363
|
}
|
|
9199
9364
|
notFoundElement = wrapWithFarmIntegrationProviders(notFoundElement);
|
|
9200
9365
|
|
|
9201
|
-
const html = await ReactDOMServer.renderToString(notFoundElement);
|
|
9366
|
+
const html = await ReactDOMServer.renderToString(notFoundElement, getFarmRendererRenderOptions());
|
|
9202
9367
|
// The layouts' and the not-found page's metadata, as the development renderer uses it.
|
|
9203
9368
|
const notFoundMetadata = renderMetadataHead(
|
|
9204
9369
|
await resolveFarmNotFoundMetadata(
|
|
@@ -9223,12 +9388,12 @@ ${servesDefaultMCP ? `
|
|
|
9223
9388
|
"<head" + attrs + ">" +
|
|
9224
9389
|
headContent.replace(/<title\\b[^>]*>[\\s\\S]*?<\\/title>\\s*/gi, "") +
|
|
9225
9390
|
"\\n <title>" + notFoundMetadata.title + "</title>" + notFoundMetadata.tags + "\\n</head>")
|
|
9226
|
-
.replace(/<head([^>]*)>/i, '<head
|
|
9391
|
+
.replace(/<head([^>]*)>/i, function(match, attrs) { return '<head' + attrs + '>\\n <link rel="stylesheet" href="/__farm_client_css_href__">' + renderFarmClientModulePreloads(fullDocument); })
|
|
9227
9392
|
.replace(/<\\/head>/i, () => renderFarmRendererHydrationScript() + '\\n</head>')
|
|
9228
9393
|
.replace(
|
|
9229
9394
|
/<\\/body>/i,
|
|
9230
9395
|
() => ' ' + renderFarmClientBootstrapScript() + '\\n' +
|
|
9231
|
-
'
|
|
9396
|
+
' ' + renderFarmClientEntryScript() + '\\n</body>',
|
|
9232
9397
|
);
|
|
9233
9398
|
fullHtml = ensureFarmDocumentMeta(fullHtml, notFoundMetadata.viewport);
|
|
9234
9399
|
if (!fullHtml.trim().startsWith('<!DOCTYPE')) {
|
|
@@ -9241,14 +9406,14 @@ ${servesDefaultMCP ? `
|
|
|
9241
9406
|
<meta charset="UTF-8">
|
|
9242
9407
|
\${notFoundMetadata.viewport}
|
|
9243
9408
|
\${notFoundMetadata.hasFavicon ? "" : '<link rel="icon" href="data:,">'}
|
|
9244
|
-
<link rel="stylesheet" href="/__farm_client_css_href__"
|
|
9409
|
+
<link rel="stylesheet" href="/__farm_client_css_href__">\${renderFarmClientModulePreloads(html)}
|
|
9245
9410
|
<title>\${notFoundMetadata.title}</title>\${notFoundMetadata.tags}
|
|
9246
9411
|
\${renderFarmRendererHydrationScript()}
|
|
9247
9412
|
</head>
|
|
9248
9413
|
<body>
|
|
9249
9414
|
<div id="root">\${html}</div>
|
|
9250
9415
|
\${renderFarmClientBootstrapScript()}
|
|
9251
|
-
|
|
9416
|
+
\${renderFarmClientEntryScript()}
|
|
9252
9417
|
</body>
|
|
9253
9418
|
</html>\`;
|
|
9254
9419
|
}
|
|
@@ -9382,6 +9547,9 @@ async function handleFarmFetch(request, context) {
|
|
|
9382
9547
|
() =>
|
|
9383
9548
|
runWithFarmRequestSpan(request, async () => {
|
|
9384
9549
|
const runtimeOptions = farmPluginRuntime ? getFarmPluginRequestOptions(request) : null;
|
|
9550
|
+
// Created before rendering so only scripts Farm, the renderer, or the
|
|
9551
|
+
// app (through getCspNonce()) give it carry the response nonce.
|
|
9552
|
+
const cspNonce = createFarmCspNonce(farmSecurityConfig);
|
|
9385
9553
|
const prepareResponse = async (runtimeRequest, responsePromise) => {
|
|
9386
9554
|
const response = await responsePromise;
|
|
9387
9555
|
// Headers need the path eagerly; preload reporting needs it only for
|
|
@@ -9393,6 +9561,7 @@ async function handleFarmFetch(request, context) {
|
|
|
9393
9561
|
applyFarmCspNonceToResponse(
|
|
9394
9562
|
applyConfiguredResponseHeaders(response, routePathname),
|
|
9395
9563
|
farmSecurityConfig,
|
|
9564
|
+
cspNonce,
|
|
9396
9565
|
),
|
|
9397
9566
|
routePathname,
|
|
9398
9567
|
runtimeRequest,
|
|
@@ -9425,7 +9594,7 @@ async function handleFarmFetch(request, context) {
|
|
|
9425
9594
|
: ` : ""}prepareResponse(request, handleFarmRequest(request, context));
|
|
9426
9595
|
|
|
9427
9596
|
const response = await _runWithCurrentRequest(request, () =>
|
|
9428
|
-
_runWithAfterRequest(request, runRequest, context),
|
|
9597
|
+
_runWithFarmCspNonce(cspNonce, () => _runWithAfterRequest(request, runRequest, context)),
|
|
9429
9598
|
);
|
|
9430
9599
|
return ${hasCompressionRuntime && !hasPluginRuntime ? "compressFarmResponse(request, response, getFarmOwnedBufferedHtml(response), farmLazyBufferedHtml.has(response))" : "response"};
|
|
9431
9600
|
}),
|
|
@@ -9500,26 +9669,6 @@ function middlewarePatternMatches(pattern, pathname) {
|
|
|
9500
9669
|
return new RegExp(`^${expression}/?$`).test(pathname);
|
|
9501
9670
|
}
|
|
9502
9671
|
__name(middlewarePatternMatches, "middlewarePatternMatches");
|
|
9503
|
-
function configMiddlewareMayHandlePath(config, pathname) {
|
|
9504
|
-
if (!hasFarmMiddlewareConfig(config)) return false;
|
|
9505
|
-
const entries = Array.isArray(config) ? config : [config];
|
|
9506
|
-
return entries.some((entry) => {
|
|
9507
|
-
if (!entry.matcher && !entry.exclude) return true;
|
|
9508
|
-
const matchers = entry.matcher ? (Array.isArray(entry.matcher) ? entry.matcher : [entry.matcher]).map(
|
|
9509
|
-
(matcher) => (
|
|
9510
|
-
// A request-aware matcher cannot be proven safe at build time.
|
|
9511
|
-
typeof matcher === "function" ? () => true : matcher
|
|
9512
|
-
)
|
|
9513
|
-
) : void 0;
|
|
9514
|
-
const compiled = compileMiddlewareConfig({ matcher: matchers, exclude: entry.exclude });
|
|
9515
|
-
return matchesCompiledMiddlewareConfig(pathname, compiled, {}).matched;
|
|
9516
|
-
});
|
|
9517
|
-
}
|
|
9518
|
-
__name(configMiddlewareMayHandlePath, "configMiddlewareMayHandlePath");
|
|
9519
|
-
function appMiddlewareMayHandlePath(middlewareRoutes, pathname) {
|
|
9520
|
-
return middlewareRoutes.some((route) => matchesMiddlewareRoute(pathname, route).matched);
|
|
9521
|
-
}
|
|
9522
|
-
__name(appMiddlewareMayHandlePath, "appMiddlewareMayHandlePath");
|
|
9523
9672
|
function routePatternSpecificity(pattern) {
|
|
9524
9673
|
return pattern.split("/").filter(Boolean).reduce((score, segment) => {
|
|
9525
9674
|
if (segment === "**" || segment.startsWith("[[...")) return score + 1;
|
|
@@ -9575,7 +9724,7 @@ function getPhysicalPrerenderBypassReason(options) {
|
|
|
9575
9724
|
}
|
|
9576
9725
|
__name(getPhysicalPrerenderBypassReason, "getPhysicalPrerenderBypassReason");
|
|
9577
9726
|
async function buildNitroUniversal(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, ssrBundle, ssrEntryFile, clientOutputDir, routeRuntimeManifest, configuredHeaderRoutes, nitroBuilderResultPromise, pluginManager) {
|
|
9578
|
-
const [
|
|
9727
|
+
const [fs3, nitroBuilderResult] = await Promise.all([
|
|
9579
9728
|
import("fs/promises"),
|
|
9580
9729
|
nitroBuilderResultPromise
|
|
9581
9730
|
]);
|
|
@@ -9584,8 +9733,8 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
9584
9733
|
const isVercel = preset === "vercel" || preset === "vercel-edge";
|
|
9585
9734
|
const isCloudflareWorker = preset === "cloudflare-module";
|
|
9586
9735
|
const outputDir = resolveDeployOutputPath(root, config.deploy.outputDir);
|
|
9587
|
-
const runtimeServerOutputDir = isVercel ?
|
|
9588
|
-
const ssrOutputDir =
|
|
9736
|
+
const runtimeServerOutputDir = isVercel ? path8.join(outputDir, "functions", "__nitro.func") : path8.join(outputDir, "server");
|
|
9737
|
+
const ssrOutputDir = path8.join(root, distDir, "ssr");
|
|
9589
9738
|
const imageRuntime = resolveImageRuntime(config, preset);
|
|
9590
9739
|
const hasGeneratedMetadataImages = Array.from(routeManager.getMetadataImages().values()).some(
|
|
9591
9740
|
(image) => image.sourceType === "module"
|
|
@@ -9654,12 +9803,22 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
9654
9803
|
}
|
|
9655
9804
|
const scheduledTasks = mergeScheduledTasks(farmWorkflows.scheduledTasks, farmCron.scheduledTasks);
|
|
9656
9805
|
const cloudflareCronConfig = createFarmCronCloudflareConfig(farmCron.jobs);
|
|
9657
|
-
const [clientCssHref, clientJsSrc] = await Promise.all([
|
|
9806
|
+
const [clientCssHref, clientJsSrc, docsModulePreloads, clientModulePreloads] = await Promise.all([
|
|
9658
9807
|
resolveHashedClientCssHref(clientOutputDir),
|
|
9659
|
-
resolveHashedClientJsSrc(clientOutputDir)
|
|
9808
|
+
resolveHashedClientJsSrc(clientOutputDir),
|
|
9809
|
+
readFarmDocsModulePreloads(path8.join(root, distDir)),
|
|
9810
|
+
readFarmClientModulePreloads(path8.join(root, distDir))
|
|
9660
9811
|
]);
|
|
9812
|
+
const encodedDocsModulePreloads = encodeFarmDocsModulePreloads(docsModulePreloads);
|
|
9813
|
+
const encodedClientModulePreloads = encodeFarmClientModulePreloads(clientModulePreloads);
|
|
9661
9814
|
for (const output of Object.values(ssrBundle)) {
|
|
9662
9815
|
if (output.type !== "chunk") continue;
|
|
9816
|
+
if (output.code.includes(FARM_DOCS_MODULE_PRELOADS_PLACEHOLDER)) {
|
|
9817
|
+
output.code = output.code.split(FARM_DOCS_MODULE_PRELOADS_PLACEHOLDER).join(encodedDocsModulePreloads);
|
|
9818
|
+
}
|
|
9819
|
+
if (output.code.includes(FARM_CLIENT_MODULE_PRELOADS_PLACEHOLDER)) {
|
|
9820
|
+
output.code = output.code.split(FARM_CLIENT_MODULE_PRELOADS_PLACEHOLDER).join(encodedClientModulePreloads);
|
|
9821
|
+
}
|
|
9663
9822
|
if (output.code.includes(FARM_CLIENT_CSS_HREF_PLACEHOLDER)) {
|
|
9664
9823
|
output.code = output.code.split(FARM_CLIENT_CSS_HREF_PLACEHOLDER).join(clientCssHref);
|
|
9665
9824
|
}
|
|
@@ -9667,13 +9826,13 @@ async function buildNitroUniversal(config, routeManager, apiRouteManager, server
|
|
|
9667
9826
|
output.code = output.code.split(FARM_CLIENT_JS_SRC_PLACEHOLDER).join(clientJsSrc);
|
|
9668
9827
|
}
|
|
9669
9828
|
}
|
|
9670
|
-
await
|
|
9829
|
+
await fs3.mkdir(ssrOutputDir, { recursive: true });
|
|
9671
9830
|
for (const [fileName, output] of Object.entries(ssrBundle)) {
|
|
9672
|
-
const filePath =
|
|
9673
|
-
await
|
|
9674
|
-
await
|
|
9831
|
+
const filePath = path8.join(ssrOutputDir, fileName);
|
|
9832
|
+
await fs3.mkdir(path8.dirname(filePath), { recursive: true });
|
|
9833
|
+
await fs3.writeFile(filePath, output.type === "chunk" ? output.code : output.source);
|
|
9675
9834
|
}
|
|
9676
|
-
const nitroEntryPath =
|
|
9835
|
+
const nitroEntryPath = path8.join(ssrOutputDir, "nitro-entry.mjs");
|
|
9677
9836
|
const nodeAdapterModule = preset === "node-server" ? resolveNitroRuntimeDependency(root, "srvx/node") : null;
|
|
9678
9837
|
const nitroEntryCode = `
|
|
9679
9838
|
// Farm.js Nitro Entry
|
|
@@ -9825,26 +9984,26 @@ function toFarmNodeResponse(request, response) {
|
|
|
9825
9984
|
})
|
|
9826
9985
|
}` : ""}
|
|
9827
9986
|
`.trim();
|
|
9828
|
-
await
|
|
9829
|
-
const farmNodeServerEntryPath = preset === "node-server" ?
|
|
9987
|
+
await fs3.writeFile(nitroEntryPath, nitroEntryCode);
|
|
9988
|
+
const farmNodeServerEntryPath = preset === "node-server" ? path8.join(ssrOutputDir, "farm-node-server-entry.mjs") : null;
|
|
9830
9989
|
if (farmNodeServerEntryPath && nodeAdapterModule) {
|
|
9831
|
-
await
|
|
9832
|
-
|
|
9990
|
+
await fs3.writeFile(
|
|
9991
|
+
path8.join(ssrOutputDir, FARM_NODE_ENV_MODULE_FILE),
|
|
9833
9992
|
FARM_NODE_ENV_MODULE_SOURCE
|
|
9834
9993
|
);
|
|
9835
|
-
await
|
|
9994
|
+
await fs3.writeFile(
|
|
9836
9995
|
farmNodeServerEntryPath,
|
|
9837
9996
|
createFarmNodeServerEntry({
|
|
9838
|
-
nitroEntryFile:
|
|
9997
|
+
nitroEntryFile: path8.basename(nitroEntryPath),
|
|
9839
9998
|
nodeAdapterModule,
|
|
9840
9999
|
server: config.server,
|
|
9841
10000
|
websocketAdapterModule: resolveNitroRuntimeDependency(root, "crossws/adapters/node")
|
|
9842
10001
|
})
|
|
9843
10002
|
);
|
|
9844
10003
|
}
|
|
9845
|
-
const farmNetlifyEntryPath = preset === "netlify" ?
|
|
10004
|
+
const farmNetlifyEntryPath = preset === "netlify" ? path8.join(ssrOutputDir, "farm-netlify-entry.mjs") : null;
|
|
9846
10005
|
if (farmNetlifyEntryPath) {
|
|
9847
|
-
await
|
|
10006
|
+
await fs3.writeFile(
|
|
9848
10007
|
farmNetlifyEntryPath,
|
|
9849
10008
|
createFarmNetlifyEntry({
|
|
9850
10009
|
nitroNetlifyEntry: resolveNitroNetlifyEntry(resolveNitroPackageEntry(root))
|
|
@@ -9884,7 +10043,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
9884
10043
|
// `src` directory), as Nitro handlers outside Farm's aliases.
|
|
9885
10044
|
serverDir: false,
|
|
9886
10045
|
serverEntry: false,
|
|
9887
|
-
buildDir:
|
|
10046
|
+
buildDir: path8.join(root, distDir, ".nitro"),
|
|
9888
10047
|
alias: resolveNitroInternalRuntimeAliases(root),
|
|
9889
10048
|
compatibilityDate: "2024-12-01",
|
|
9890
10049
|
output: resolveFarmNitroOutputConfig(preset, outputDir),
|
|
@@ -9960,7 +10119,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
9960
10119
|
if (pluginManager) {
|
|
9961
10120
|
nitroConfig = await pluginManager.runHookSerial("beforeNitroBuild", nitroConfig);
|
|
9962
10121
|
}
|
|
9963
|
-
const expectedServerDir =
|
|
10122
|
+
const expectedServerDir = path8.join(outputDir, "server");
|
|
9964
10123
|
const customRollupKeys = Object.keys(nitroConfig.rollupConfig || {}).filter(
|
|
9965
10124
|
(key) => key !== "external" && key !== "plugins"
|
|
9966
10125
|
);
|
|
@@ -9973,9 +10132,9 @@ function toFarmNodeResponse(request, response) {
|
|
|
9973
10132
|
snapshotSSRRebundleOptions(nitroConfig)
|
|
9974
10133
|
);
|
|
9975
10134
|
const requestedBuilder = nitroConfig.builder ?? process.env.NITRO_BUILDER;
|
|
9976
|
-
const canReusePrebuiltSSR = isPrebuiltSSRCandidate && nitroConfig.preset === "node-server" && (requestedBuilder === void 0 || requestedBuilder === "rollup" || requestedBuilder === "rolldown") && nitroConfig.sourcemap === false && !hasCustomOxcOptions && !hasLateBuildMutationConfig && !hasUnsupportedSSRRebundleOverrides && nitroConfig.rollupConfig?.external === nitroRollupExternal && !hasRollupPlugins(nitroConfig.rollupConfig?.plugins) && customRollupKeys.length === 0 &&
|
|
10135
|
+
const canReusePrebuiltSSR = isPrebuiltSSRCandidate && nitroConfig.preset === "node-server" && (requestedBuilder === void 0 || requestedBuilder === "rollup" || requestedBuilder === "rolldown") && nitroConfig.sourcemap === false && !hasCustomOxcOptions && !hasLateBuildMutationConfig && !hasUnsupportedSSRRebundleOverrides && nitroConfig.rollupConfig?.external === nitroRollupExternal && !hasRollupPlugins(nitroConfig.rollupConfig?.plugins) && customRollupKeys.length === 0 && path8.resolve(nitroConfig.output?.serverDir || "") === path8.resolve(expectedServerDir) && Boolean(
|
|
9977
10136
|
nitroConfig.handlers?.some(
|
|
9978
|
-
(handler) =>
|
|
10137
|
+
(handler) => path8.resolve(handler?.handler || "") === nitroEntryPath
|
|
9979
10138
|
)
|
|
9980
10139
|
);
|
|
9981
10140
|
const selectRolldownBuilder = canReusePrebuiltSSR && requestedBuilder === void 0 && await canUseRolldownBuilder();
|
|
@@ -10062,14 +10221,14 @@ function toFarmNodeResponse(request, response) {
|
|
|
10062
10221
|
});
|
|
10063
10222
|
}
|
|
10064
10223
|
prerenderer.hooks.hook("compiled", async () => {
|
|
10065
|
-
const prerenderServerDir =
|
|
10224
|
+
const prerenderServerDir = path8.join(outputDir, "server");
|
|
10066
10225
|
await copyPrebuiltSSRBundle(
|
|
10067
10226
|
ssrBundle,
|
|
10068
|
-
|
|
10227
|
+
path8.join(prerenderServerDir, FARM_SSR_OUTPUT_DIR),
|
|
10069
10228
|
null,
|
|
10070
|
-
|
|
10229
|
+
fs3
|
|
10071
10230
|
);
|
|
10072
|
-
await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile,
|
|
10231
|
+
await registerPrebuiltSSRPackageImport(prerenderServerDir, ssrEntryFile, fs3);
|
|
10073
10232
|
});
|
|
10074
10233
|
});
|
|
10075
10234
|
}
|
|
@@ -10100,7 +10259,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
10100
10259
|
else process.env[FARM_PRERENDER_ENV] = previousPrerender;
|
|
10101
10260
|
}
|
|
10102
10261
|
}
|
|
10103
|
-
const sharpRuntimeStagePromise = imageRuntime === "node" ? stageSharpRuntime(config, root, distDir,
|
|
10262
|
+
const sharpRuntimeStagePromise = imageRuntime === "node" ? stageSharpRuntime(config, root, distDir, fs3, preset) : Promise.resolve(null);
|
|
10104
10263
|
const prebuiltSSRFilesPromise = canReusePrebuiltSSR ? prepareSSRBundleFiles(
|
|
10105
10264
|
ssrBundle,
|
|
10106
10265
|
shouldMinify ? { keepNames: keepServerNames, target: "node18" } : null
|
|
@@ -10113,7 +10272,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
10113
10272
|
await nitroInstance.close();
|
|
10114
10273
|
if (nitroBuildResult.status === "rejected") {
|
|
10115
10274
|
if (sharpRuntimeStageResult.status === "fulfilled" && sharpRuntimeStageResult.value) {
|
|
10116
|
-
await
|
|
10275
|
+
await fs3.rm(sharpRuntimeStageResult.value.stageDir, {
|
|
10117
10276
|
recursive: true,
|
|
10118
10277
|
force: true
|
|
10119
10278
|
});
|
|
@@ -10126,20 +10285,20 @@ function toFarmNodeResponse(request, response) {
|
|
|
10126
10285
|
if (prebuiltSSRFilesResult.status === "rejected") {
|
|
10127
10286
|
throw prebuiltSSRFilesResult.reason;
|
|
10128
10287
|
}
|
|
10129
|
-
const stagedSharpRuntime = sharpRuntimeStageResult.value ?? (imageRuntime === "node" ? await stageSharpRuntime(config, root, distDir,
|
|
10288
|
+
const stagedSharpRuntime = sharpRuntimeStageResult.value ?? (imageRuntime === "node" ? await stageSharpRuntime(config, root, distDir, fs3, preset) : null);
|
|
10130
10289
|
const runtimeCopyPromise = (async () => {
|
|
10131
10290
|
if (stagedSharpRuntime) {
|
|
10132
|
-
await installStagedSharpRuntime(stagedSharpRuntime, runtimeServerOutputDir,
|
|
10291
|
+
await installStagedSharpRuntime(stagedSharpRuntime, runtimeServerOutputDir, fs3);
|
|
10133
10292
|
}
|
|
10134
10293
|
if (useExternalMetadataImageRuntime) {
|
|
10135
|
-
await copyMetadataImageRuntime(root, runtimeServerOutputDir,
|
|
10294
|
+
await copyMetadataImageRuntime(root, runtimeServerOutputDir, fs3);
|
|
10136
10295
|
}
|
|
10137
10296
|
})();
|
|
10138
10297
|
const copyResults = await Promise.allSettled([
|
|
10139
10298
|
prebuiltSSRFilesResult.value ? writeSSRBundleFiles(
|
|
10140
10299
|
prebuiltSSRFilesResult.value,
|
|
10141
|
-
|
|
10142
|
-
|
|
10300
|
+
path8.join(outputDir, "server", FARM_SSR_OUTPUT_DIR),
|
|
10301
|
+
fs3
|
|
10143
10302
|
) : Promise.resolve(),
|
|
10144
10303
|
runtimeCopyPromise
|
|
10145
10304
|
]);
|
|
@@ -10148,7 +10307,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
10148
10307
|
);
|
|
10149
10308
|
if (failedCopy) throw failedCopy.reason;
|
|
10150
10309
|
if (canReusePrebuiltSSR) {
|
|
10151
|
-
await registerPrebuiltSSRPackageImport(
|
|
10310
|
+
await registerPrebuiltSSRPackageImport(path8.join(outputDir, "server"), ssrEntryFile, fs3);
|
|
10152
10311
|
logger.info("\u26A1 Reused Farm's prebuilt SSR bundle for the Node output");
|
|
10153
10312
|
}
|
|
10154
10313
|
if (useRolldownBuilder) {
|
|
@@ -10163,7 +10322,7 @@ function toFarmNodeResponse(request, response) {
|
|
|
10163
10322
|
});
|
|
10164
10323
|
}
|
|
10165
10324
|
if (isVercel) {
|
|
10166
|
-
await postProcessVercelOutput(root, outputDir,
|
|
10325
|
+
await postProcessVercelOutput(root, outputDir, fs3, config, farmWorkflows, routeRuntimeManifest);
|
|
10167
10326
|
}
|
|
10168
10327
|
logger.success(`\u2705 Nitro build completed with preset: ${preset}`);
|
|
10169
10328
|
}
|
|
@@ -10173,11 +10332,11 @@ function resolveFarmNitroOutputConfig(preset, outputDir) {
|
|
|
10173
10332
|
return {
|
|
10174
10333
|
dir: outputDir,
|
|
10175
10334
|
...preset === "node-server" ? {
|
|
10176
|
-
serverDir:
|
|
10177
|
-
publicDir:
|
|
10335
|
+
serverDir: path8.join(outputDir, "server"),
|
|
10336
|
+
publicDir: path8.join(outputDir, "public")
|
|
10178
10337
|
} : isVercel ? {
|
|
10179
|
-
serverDir:
|
|
10180
|
-
publicDir:
|
|
10338
|
+
serverDir: path8.join(outputDir, "functions", "__nitro.func"),
|
|
10339
|
+
publicDir: path8.join(outputDir, "static")
|
|
10181
10340
|
} : {}
|
|
10182
10341
|
};
|
|
10183
10342
|
}
|
|
@@ -10191,24 +10350,24 @@ function prepareSSRBundleFiles(ssrBundle, minifyOptions) {
|
|
|
10191
10350
|
);
|
|
10192
10351
|
}
|
|
10193
10352
|
__name(prepareSSRBundleFiles, "prepareSSRBundleFiles");
|
|
10194
|
-
async function writeSSRBundleFiles(files, targetDir,
|
|
10195
|
-
await
|
|
10353
|
+
async function writeSSRBundleFiles(files, targetDir, fs3) {
|
|
10354
|
+
await fs3.rm(targetDir, { recursive: true, force: true });
|
|
10196
10355
|
await Promise.all(
|
|
10197
10356
|
files.map(async ({ fileName, contents }) => {
|
|
10198
|
-
const targetPath =
|
|
10199
|
-
await
|
|
10200
|
-
await
|
|
10357
|
+
const targetPath = path8.join(targetDir, fileName);
|
|
10358
|
+
await fs3.mkdir(path8.dirname(targetPath), { recursive: true });
|
|
10359
|
+
await fs3.writeFile(targetPath, contents);
|
|
10201
10360
|
})
|
|
10202
10361
|
);
|
|
10203
10362
|
}
|
|
10204
10363
|
__name(writeSSRBundleFiles, "writeSSRBundleFiles");
|
|
10205
|
-
async function copyPrebuiltSSRBundle(ssrBundle, targetDir, minifyOptions,
|
|
10206
|
-
await writeSSRBundleFiles(await prepareSSRBundleFiles(ssrBundle, minifyOptions), targetDir,
|
|
10364
|
+
async function copyPrebuiltSSRBundle(ssrBundle, targetDir, minifyOptions, fs3) {
|
|
10365
|
+
await writeSSRBundleFiles(await prepareSSRBundleFiles(ssrBundle, minifyOptions), targetDir, fs3);
|
|
10207
10366
|
}
|
|
10208
10367
|
__name(copyPrebuiltSSRBundle, "copyPrebuiltSSRBundle");
|
|
10209
|
-
async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile,
|
|
10210
|
-
const packagePath =
|
|
10211
|
-
const packageJSON = await
|
|
10368
|
+
async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs3) {
|
|
10369
|
+
const packagePath = path8.join(serverDir, "package.json");
|
|
10370
|
+
const packageJSON = await fs3.readFile(packagePath, "utf8").then((contents) => JSON.parse(contents)).catch((error) => {
|
|
10212
10371
|
if (error.code === "ENOENT") return { type: "module" };
|
|
10213
10372
|
throw error;
|
|
10214
10373
|
});
|
|
@@ -10218,14 +10377,14 @@ async function registerPrebuiltSSRPackageImport(serverDir, ssrEntryFile, fs) {
|
|
|
10218
10377
|
...existingImports,
|
|
10219
10378
|
[FARM_SSR_PACKAGE_IMPORT]: `./${outputEntry}`
|
|
10220
10379
|
};
|
|
10221
|
-
await
|
|
10222
|
-
await
|
|
10380
|
+
await fs3.mkdir(serverDir, { recursive: true });
|
|
10381
|
+
await fs3.writeFile(packagePath, `${JSON.stringify(packageJSON, null, 2)}
|
|
10223
10382
|
`);
|
|
10224
10383
|
}
|
|
10225
10384
|
__name(registerPrebuiltSSRPackageImport, "registerPrebuiltSSRPackageImport");
|
|
10226
|
-
async function moveVercelOutputPath(src, dest,
|
|
10385
|
+
async function moveVercelOutputPath(src, dest, fs3) {
|
|
10227
10386
|
try {
|
|
10228
|
-
await
|
|
10387
|
+
await fs3.rename(src, dest);
|
|
10229
10388
|
return;
|
|
10230
10389
|
} catch (error) {
|
|
10231
10390
|
const code = error?.code;
|
|
@@ -10233,39 +10392,39 @@ async function moveVercelOutputPath(src, dest, fs) {
|
|
|
10233
10392
|
throw error;
|
|
10234
10393
|
}
|
|
10235
10394
|
}
|
|
10236
|
-
await
|
|
10237
|
-
await
|
|
10395
|
+
await fs3.cp(src, dest, { recursive: true, force: true });
|
|
10396
|
+
await fs3.rm(src, { recursive: true, force: true });
|
|
10238
10397
|
}
|
|
10239
10398
|
__name(moveVercelOutputPath, "moveVercelOutputPath");
|
|
10240
|
-
async function postProcessVercelOutput(root, outputDir,
|
|
10241
|
-
const serverDir =
|
|
10242
|
-
const functionsDir =
|
|
10243
|
-
const nitroFuncDir =
|
|
10244
|
-
const staticDir =
|
|
10245
|
-
const publicDir =
|
|
10246
|
-
await
|
|
10247
|
-
const serverContents = await
|
|
10399
|
+
async function postProcessVercelOutput(root, outputDir, fs3, config, farmWorkflows, routeRuntimeManifest) {
|
|
10400
|
+
const serverDir = path8.join(outputDir, "server");
|
|
10401
|
+
const functionsDir = path8.join(outputDir, "functions");
|
|
10402
|
+
const nitroFuncDir = path8.join(functionsDir, "__nitro.func");
|
|
10403
|
+
const staticDir = path8.join(outputDir, "static");
|
|
10404
|
+
const publicDir = path8.join(outputDir, "public");
|
|
10405
|
+
await fs3.mkdir(nitroFuncDir, { recursive: true });
|
|
10406
|
+
const serverContents = await fs3.readdir(serverDir).catch((error) => {
|
|
10248
10407
|
if (error.code === "ENOENT") return [];
|
|
10249
10408
|
throw error;
|
|
10250
10409
|
});
|
|
10251
10410
|
for (const file of serverContents) {
|
|
10252
|
-
await moveVercelOutputPath(
|
|
10411
|
+
await moveVercelOutputPath(path8.join(serverDir, file), path8.join(nitroFuncDir, file), fs3);
|
|
10253
10412
|
}
|
|
10254
|
-
if (serverContents.length > 0) await
|
|
10413
|
+
if (serverContents.length > 0) await fs3.rm(serverDir, { recursive: true, force: true });
|
|
10255
10414
|
try {
|
|
10256
|
-
await moveVercelOutputPath(publicDir, staticDir,
|
|
10415
|
+
await moveVercelOutputPath(publicDir, staticDir, fs3);
|
|
10257
10416
|
} catch (error) {
|
|
10258
10417
|
if (error?.code !== "ENOENT") throw error;
|
|
10259
10418
|
}
|
|
10260
|
-
await copyFarmDocsContentForVercel(config, root, nitroFuncDir,
|
|
10261
|
-
await copyPrismaClientForVercel(root, nitroFuncDir,
|
|
10262
|
-
const configPath =
|
|
10263
|
-
const configContent = await
|
|
10419
|
+
await copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs3);
|
|
10420
|
+
await copyPrismaClientForVercel(root, nitroFuncDir, fs3);
|
|
10421
|
+
const configPath = path8.join(outputDir, "config.json");
|
|
10422
|
+
const configContent = await fs3.readFile(configPath, "utf-8");
|
|
10264
10423
|
const vercelConfig = JSON.parse(configContent);
|
|
10265
10424
|
const runtimeRoutes = await createFarmVercelRouteRuntimeFunctions(
|
|
10266
10425
|
outputDir,
|
|
10267
10426
|
routeRuntimeManifest,
|
|
10268
|
-
|
|
10427
|
+
fs3,
|
|
10269
10428
|
config.basePath
|
|
10270
10429
|
);
|
|
10271
10430
|
vercelConfig.routes = buildFarmVercelRoutes({
|
|
@@ -10280,29 +10439,29 @@ async function postProcessVercelOutput(root, outputDir, fs, config, farmWorkflow
|
|
|
10280
10439
|
vercelConfigWithWorkflowCrons,
|
|
10281
10440
|
config.cron.jobs
|
|
10282
10441
|
);
|
|
10283
|
-
await
|
|
10442
|
+
await fs3.writeFile(configPath, JSON.stringify(vercelConfigWithCrons, null, 2));
|
|
10284
10443
|
logger.info("\u2705 Post-processed Vercel output for Build Output API v3");
|
|
10285
10444
|
}
|
|
10286
10445
|
__name(postProcessVercelOutput, "postProcessVercelOutput");
|
|
10287
|
-
async function copyFarmDocsContentForVercel(config, root, nitroFuncDir,
|
|
10446
|
+
async function copyFarmDocsContentForVercel(config, root, nitroFuncDir, fs3) {
|
|
10288
10447
|
const docsContentDir = resolveBuildDocsContentDir(config, root);
|
|
10289
10448
|
if (!docsContentDir) return;
|
|
10290
|
-
const bundledContentDir =
|
|
10449
|
+
const bundledContentDir = path8.join(nitroFuncDir, "farm-docs-content");
|
|
10291
10450
|
const lastModifiedManifest = createFarmDocsLastModifiedManifest(docsContentDir, {
|
|
10292
10451
|
fallback: "now"
|
|
10293
10452
|
});
|
|
10294
|
-
await
|
|
10295
|
-
await
|
|
10296
|
-
await
|
|
10453
|
+
await fs3.rm(bundledContentDir, { recursive: true, force: true });
|
|
10454
|
+
await fs3.mkdir(path8.dirname(bundledContentDir), { recursive: true });
|
|
10455
|
+
await fs3.cp(docsContentDir, bundledContentDir, {
|
|
10297
10456
|
recursive: true,
|
|
10298
10457
|
force: true
|
|
10299
10458
|
});
|
|
10300
|
-
await
|
|
10301
|
-
|
|
10459
|
+
await fs3.writeFile(
|
|
10460
|
+
path8.join(bundledContentDir, FARM_DOCS_LAST_MODIFIED_MANIFEST),
|
|
10302
10461
|
`${JSON.stringify(lastModifiedManifest, null, 2)}
|
|
10303
10462
|
`
|
|
10304
10463
|
);
|
|
10305
|
-
logger.info(`\u{1F4DA} Bundled docs content for Vercel: ${
|
|
10464
|
+
logger.info(`\u{1F4DA} Bundled docs content for Vercel: ${path8.relative(root, docsContentDir)}`);
|
|
10306
10465
|
}
|
|
10307
10466
|
__name(copyFarmDocsContentForVercel, "copyFarmDocsContentForVercel");
|
|
10308
10467
|
function resolveServerFunctionPlatform(preset) {
|
|
@@ -10321,9 +10480,9 @@ function platformFieldAllows(field, value) {
|
|
|
10321
10480
|
return allowed.length === 0 || allowed.includes(value);
|
|
10322
10481
|
}
|
|
10323
10482
|
__name(platformFieldAllows, "platformFieldAllows");
|
|
10324
|
-
async function stageSharpRuntime(config, root, distDir,
|
|
10483
|
+
async function stageSharpRuntime(config, root, distDir, fs3, preset) {
|
|
10325
10484
|
const functionPlatform = resolveServerFunctionPlatform(preset);
|
|
10326
|
-
const projectRequire = createRequire(
|
|
10485
|
+
const projectRequire = createRequire(path8.join(root, "package.json"));
|
|
10327
10486
|
let sharpRequire = projectRequire;
|
|
10328
10487
|
if (!resolvePackageJson(projectRequire, "sharp")) {
|
|
10329
10488
|
try {
|
|
@@ -10333,10 +10492,10 @@ async function stageSharpRuntime(config, root, distDir, fs, preset) {
|
|
|
10333
10492
|
}
|
|
10334
10493
|
const copiedPackages = /* @__PURE__ */ new Map();
|
|
10335
10494
|
const packageCopies = /* @__PURE__ */ new Map();
|
|
10336
|
-
const stageRoot =
|
|
10337
|
-
await
|
|
10338
|
-
const stageDir = await
|
|
10339
|
-
const targetNodeModules =
|
|
10495
|
+
const stageRoot = path8.join(root, distDir, "tmp");
|
|
10496
|
+
await fs3.mkdir(stageRoot, { recursive: true });
|
|
10497
|
+
const stageDir = await fs3.mkdtemp(path8.join(stageRoot, "sharp-runtime-"));
|
|
10498
|
+
const targetNodeModules = path8.join(stageDir, "node_modules");
|
|
10340
10499
|
function copyPackage(packageName, parentRequire) {
|
|
10341
10500
|
const activeCopy = packageCopies.get(packageName);
|
|
10342
10501
|
if (activeCopy) return activeCopy;
|
|
@@ -10348,19 +10507,19 @@ async function stageSharpRuntime(config, root, distDir, fs, preset) {
|
|
|
10348
10507
|
async function copyPackageOnce(packageName, parentRequire) {
|
|
10349
10508
|
const packageJsonPath = resolvePackageJson(parentRequire, packageName);
|
|
10350
10509
|
if (!packageJsonPath) return;
|
|
10351
|
-
const packageJson = JSON.parse(await
|
|
10510
|
+
const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf8"));
|
|
10352
10511
|
if (functionPlatform && !packageSupportsPlatform(packageJson, functionPlatform)) return;
|
|
10353
|
-
const packageDir =
|
|
10354
|
-
const targetDir =
|
|
10512
|
+
const packageDir = path8.dirname(packageJsonPath);
|
|
10513
|
+
const targetDir = path8.join(targetNodeModules, ...packageName.split("/"));
|
|
10355
10514
|
copiedPackages.set(packageName, String(packageJson.version || "*"));
|
|
10356
|
-
await
|
|
10515
|
+
await fs3.mkdir(path8.dirname(targetDir), { recursive: true });
|
|
10357
10516
|
const packageRequire = createRequire(packageJsonPath);
|
|
10358
10517
|
const dependencies = {
|
|
10359
10518
|
...packageJson.dependencies,
|
|
10360
10519
|
...packageJson.optionalDependencies
|
|
10361
10520
|
};
|
|
10362
10521
|
await settleAllOrThrow([
|
|
10363
|
-
|
|
10522
|
+
fs3.cp(packageDir, targetDir, {
|
|
10364
10523
|
recursive: true,
|
|
10365
10524
|
force: true,
|
|
10366
10525
|
dereference: true,
|
|
@@ -10378,7 +10537,7 @@ async function stageSharpRuntime(config, root, distDir, fs, preset) {
|
|
|
10378
10537
|
throw new Error(`Farm image optimization requires sharp. ${SHARP_INSTALL_HINT}`);
|
|
10379
10538
|
}
|
|
10380
10539
|
} catch (error) {
|
|
10381
|
-
await
|
|
10540
|
+
await fs3.rm(stageDir, { recursive: true, force: true });
|
|
10382
10541
|
throw error;
|
|
10383
10542
|
}
|
|
10384
10543
|
return {
|
|
@@ -10389,19 +10548,19 @@ async function stageSharpRuntime(config, root, distDir, fs, preset) {
|
|
|
10389
10548
|
};
|
|
10390
10549
|
}
|
|
10391
10550
|
__name(stageSharpRuntime, "stageSharpRuntime");
|
|
10392
|
-
async function installStagedSharpRuntime(staged, nitroFuncDir,
|
|
10393
|
-
const stagedNodeModules =
|
|
10394
|
-
const targetNodeModules =
|
|
10551
|
+
async function installStagedSharpRuntime(staged, nitroFuncDir, fs3) {
|
|
10552
|
+
const stagedNodeModules = path8.join(staged.stageDir, "node_modules");
|
|
10553
|
+
const targetNodeModules = path8.join(nitroFuncDir, "node_modules");
|
|
10395
10554
|
try {
|
|
10396
|
-
await mergeStagedDirectory(stagedNodeModules, targetNodeModules,
|
|
10397
|
-
const functionPackage = await readNitroOutputPackage(nitroFuncDir,
|
|
10555
|
+
await mergeStagedDirectory(stagedNodeModules, targetNodeModules, fs3);
|
|
10556
|
+
const functionPackage = await readNitroOutputPackage(nitroFuncDir, fs3);
|
|
10398
10557
|
functionPackage.dependencies = {
|
|
10399
10558
|
...functionPackage.dependencies,
|
|
10400
10559
|
...staged.dependencies
|
|
10401
10560
|
};
|
|
10402
|
-
await writeNitroOutputPackage(nitroFuncDir, functionPackage,
|
|
10561
|
+
await writeNitroOutputPackage(nitroFuncDir, functionPackage, fs3);
|
|
10403
10562
|
} finally {
|
|
10404
|
-
await
|
|
10563
|
+
await fs3.rm(staged.stageDir, { recursive: true, force: true });
|
|
10405
10564
|
}
|
|
10406
10565
|
logger.info(
|
|
10407
10566
|
`\u{1F5BC}\uFE0F Bundled Sharp image runtime (${Object.keys(staged.dependencies).length} packages)`
|
|
@@ -10416,15 +10575,15 @@ async function settleAllOrThrow(operations) {
|
|
|
10416
10575
|
if (failure) throw failure.reason;
|
|
10417
10576
|
}
|
|
10418
10577
|
__name(settleAllOrThrow, "settleAllOrThrow");
|
|
10419
|
-
async function mergeStagedDirectory(sourceDir, targetDir,
|
|
10420
|
-
await
|
|
10421
|
-
const entries = await
|
|
10578
|
+
async function mergeStagedDirectory(sourceDir, targetDir, fs3) {
|
|
10579
|
+
await fs3.mkdir(targetDir, { recursive: true });
|
|
10580
|
+
const entries = await fs3.readdir(sourceDir, { withFileTypes: true });
|
|
10422
10581
|
await settleAllOrThrow(
|
|
10423
10582
|
entries.map(async (entry) => {
|
|
10424
|
-
const sourcePath =
|
|
10425
|
-
const targetPath =
|
|
10583
|
+
const sourcePath = path8.join(sourceDir, entry.name);
|
|
10584
|
+
const targetPath = path8.join(targetDir, entry.name);
|
|
10426
10585
|
try {
|
|
10427
|
-
await
|
|
10586
|
+
await fs3.rename(sourcePath, targetPath);
|
|
10428
10587
|
return;
|
|
10429
10588
|
} catch (error) {
|
|
10430
10589
|
const code = error.code;
|
|
@@ -10433,16 +10592,16 @@ async function mergeStagedDirectory(sourceDir, targetDir, fs) {
|
|
|
10433
10592
|
}
|
|
10434
10593
|
}
|
|
10435
10594
|
if (entry.isDirectory()) {
|
|
10436
|
-
await mergeStagedDirectory(sourcePath, targetPath,
|
|
10437
|
-
await
|
|
10595
|
+
await mergeStagedDirectory(sourcePath, targetPath, fs3);
|
|
10596
|
+
await fs3.rm(sourcePath, { recursive: true, force: true });
|
|
10438
10597
|
return;
|
|
10439
10598
|
}
|
|
10440
|
-
await
|
|
10599
|
+
await fs3.cp(sourcePath, targetPath, {
|
|
10441
10600
|
force: true,
|
|
10442
10601
|
dereference: true,
|
|
10443
10602
|
mode: fsConstants.COPYFILE_FICLONE
|
|
10444
10603
|
});
|
|
10445
|
-
await
|
|
10604
|
+
await fs3.rm(sourcePath, { force: true });
|
|
10446
10605
|
})
|
|
10447
10606
|
);
|
|
10448
10607
|
}
|
|
@@ -10450,14 +10609,14 @@ __name(mergeStagedDirectory, "mergeStagedDirectory");
|
|
|
10450
10609
|
function assertMetadataImageRuntimeInstalled(root, metadataImageRoutes) {
|
|
10451
10610
|
const generated = metadataImageRoutes.find((image) => image.sourceType === "module");
|
|
10452
10611
|
if (!generated || resolveMetadataImageRuntimePackageJson(root)) return;
|
|
10453
|
-
const file = generated.modulePath ? toPosixPath(
|
|
10612
|
+
const file = generated.modulePath ? toPosixPath(path8.relative(root, generated.modulePath)) : "";
|
|
10454
10613
|
throw new Error(
|
|
10455
10614
|
`${file || "A generated metadata image"} renders with @vercel/og, which is not installed. ${VERCEL_OG_INSTALL_HINT}`
|
|
10456
10615
|
);
|
|
10457
10616
|
}
|
|
10458
10617
|
__name(assertMetadataImageRuntimeInstalled, "assertMetadataImageRuntimeInstalled");
|
|
10459
10618
|
function resolveMetadataImageRuntimePackageJson(root) {
|
|
10460
|
-
const projectRequire = createRequire(
|
|
10619
|
+
const projectRequire = createRequire(path8.join(root, "package.json"));
|
|
10461
10620
|
const packageJsonPath = resolvePackageJson(projectRequire, "@vercel/og");
|
|
10462
10621
|
if (packageJsonPath) return packageJsonPath;
|
|
10463
10622
|
try {
|
|
@@ -10467,40 +10626,40 @@ function resolveMetadataImageRuntimePackageJson(root) {
|
|
|
10467
10626
|
}
|
|
10468
10627
|
}
|
|
10469
10628
|
__name(resolveMetadataImageRuntimePackageJson, "resolveMetadataImageRuntimePackageJson");
|
|
10470
|
-
async function copyMetadataImageRuntime(root, nitroFuncDir,
|
|
10629
|
+
async function copyMetadataImageRuntime(root, nitroFuncDir, fs3) {
|
|
10471
10630
|
const packageJsonPath = resolveMetadataImageRuntimePackageJson(root);
|
|
10472
10631
|
if (!packageJsonPath) return;
|
|
10473
|
-
const packageJson = JSON.parse(await
|
|
10474
|
-
const packageDir =
|
|
10475
|
-
const targetDir =
|
|
10476
|
-
await
|
|
10477
|
-
await
|
|
10632
|
+
const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf8"));
|
|
10633
|
+
const packageDir = path8.dirname(packageJsonPath);
|
|
10634
|
+
const targetDir = path8.join(nitroFuncDir, "node_modules", "@vercel", "og");
|
|
10635
|
+
await fs3.mkdir(path8.dirname(targetDir), { recursive: true });
|
|
10636
|
+
await fs3.cp(packageDir, targetDir, {
|
|
10478
10637
|
recursive: true,
|
|
10479
10638
|
force: true,
|
|
10480
10639
|
dereference: true,
|
|
10481
10640
|
mode: fsConstants.COPYFILE_FICLONE
|
|
10482
10641
|
});
|
|
10483
|
-
const functionPackage = await readNitroOutputPackage(nitroFuncDir,
|
|
10642
|
+
const functionPackage = await readNitroOutputPackage(nitroFuncDir, fs3);
|
|
10484
10643
|
functionPackage.dependencies = {
|
|
10485
10644
|
...functionPackage.dependencies,
|
|
10486
10645
|
"@vercel/og": String(packageJson.version || "0.11.1")
|
|
10487
10646
|
};
|
|
10488
|
-
await writeNitroOutputPackage(nitroFuncDir, functionPackage,
|
|
10647
|
+
await writeNitroOutputPackage(nitroFuncDir, functionPackage, fs3);
|
|
10489
10648
|
logger.info("\u{1F5BC}\uFE0F Bundled generated metadata image runtime");
|
|
10490
10649
|
}
|
|
10491
10650
|
__name(copyMetadataImageRuntime, "copyMetadataImageRuntime");
|
|
10492
|
-
async function readNitroOutputPackage(outputDir,
|
|
10493
|
-
const packagePath =
|
|
10494
|
-
return
|
|
10651
|
+
async function readNitroOutputPackage(outputDir, fs3) {
|
|
10652
|
+
const packagePath = path8.join(outputDir, "package.json");
|
|
10653
|
+
return fs3.readFile(packagePath, "utf8").then((contents) => JSON.parse(contents)).catch((error) => {
|
|
10495
10654
|
if (error.code === "ENOENT") return {};
|
|
10496
10655
|
throw error;
|
|
10497
10656
|
});
|
|
10498
10657
|
}
|
|
10499
10658
|
__name(readNitroOutputPackage, "readNitroOutputPackage");
|
|
10500
|
-
async function writeNitroOutputPackage(outputDir, packageJson,
|
|
10501
|
-
await
|
|
10502
|
-
await
|
|
10503
|
-
|
|
10659
|
+
async function writeNitroOutputPackage(outputDir, packageJson, fs3) {
|
|
10660
|
+
await fs3.mkdir(outputDir, { recursive: true });
|
|
10661
|
+
await fs3.writeFile(
|
|
10662
|
+
path8.join(outputDir, "package.json"),
|
|
10504
10663
|
`${JSON.stringify(packageJson, null, 2)}
|
|
10505
10664
|
`
|
|
10506
10665
|
);
|
|
@@ -10517,9 +10676,9 @@ function resolvePackageJson(parentRequire, packageName) {
|
|
|
10517
10676
|
}
|
|
10518
10677
|
}
|
|
10519
10678
|
try {
|
|
10520
|
-
let directory =
|
|
10521
|
-
while (directory !==
|
|
10522
|
-
const candidate =
|
|
10679
|
+
let directory = path8.dirname(metadataModule ?? parentRequire.resolve(packageName));
|
|
10680
|
+
while (directory !== path8.dirname(directory)) {
|
|
10681
|
+
const candidate = path8.join(directory, "package.json");
|
|
10523
10682
|
if (existsSync2(candidate)) {
|
|
10524
10683
|
try {
|
|
10525
10684
|
const manifest = JSON.parse(readFileSync(candidate, "utf8"));
|
|
@@ -10527,55 +10686,79 @@ function resolvePackageJson(parentRequire, packageName) {
|
|
|
10527
10686
|
} catch {
|
|
10528
10687
|
}
|
|
10529
10688
|
}
|
|
10530
|
-
if (
|
|
10531
|
-
directory =
|
|
10689
|
+
if (path8.basename(directory) === "node_modules") break;
|
|
10690
|
+
directory = path8.dirname(directory);
|
|
10532
10691
|
}
|
|
10533
10692
|
} catch {
|
|
10534
10693
|
}
|
|
10535
10694
|
return null;
|
|
10536
10695
|
}
|
|
10537
10696
|
__name(resolvePackageJson, "resolvePackageJson");
|
|
10538
|
-
async function copyPrismaClientForVercel(root, nitroFuncDir,
|
|
10539
|
-
const projectRequire = createRequire(
|
|
10697
|
+
async function copyPrismaClientForVercel(root, nitroFuncDir, fs3) {
|
|
10698
|
+
const projectRequire = createRequire(path8.join(root, "package.json"));
|
|
10540
10699
|
let prismaClientDir;
|
|
10541
10700
|
try {
|
|
10542
|
-
prismaClientDir =
|
|
10701
|
+
prismaClientDir = path8.dirname(projectRequire.resolve("@prisma/client/default.js"));
|
|
10543
10702
|
} catch {
|
|
10544
10703
|
return;
|
|
10545
10704
|
}
|
|
10546
|
-
const generatedClientDir =
|
|
10705
|
+
const generatedClientDir = path8.join(prismaClientDir, "..", "..", ".prisma", "client");
|
|
10547
10706
|
try {
|
|
10548
|
-
await
|
|
10707
|
+
await fs3.access(generatedClientDir);
|
|
10549
10708
|
} catch {
|
|
10550
10709
|
return;
|
|
10551
10710
|
}
|
|
10552
|
-
const targetNodeModules =
|
|
10553
|
-
const targetPrismaScopeDir =
|
|
10554
|
-
const targetGeneratedDir =
|
|
10555
|
-
const targetClientDir =
|
|
10556
|
-
await
|
|
10557
|
-
await
|
|
10711
|
+
const targetNodeModules = path8.join(nitroFuncDir, "node_modules");
|
|
10712
|
+
const targetPrismaScopeDir = path8.join(targetNodeModules, "@prisma");
|
|
10713
|
+
const targetGeneratedDir = path8.join(targetNodeModules, ".prisma", "client");
|
|
10714
|
+
const targetClientDir = path8.join(targetPrismaScopeDir, "client");
|
|
10715
|
+
await fs3.mkdir(targetPrismaScopeDir, { recursive: true });
|
|
10716
|
+
await fs3.cp(prismaClientDir, targetClientDir, {
|
|
10558
10717
|
recursive: true,
|
|
10559
10718
|
force: true
|
|
10560
10719
|
});
|
|
10561
|
-
await
|
|
10720
|
+
await fs3.cp(generatedClientDir, targetGeneratedDir, {
|
|
10562
10721
|
recursive: true,
|
|
10563
10722
|
force: true
|
|
10564
10723
|
});
|
|
10565
|
-
const clientPackagePath =
|
|
10724
|
+
const clientPackagePath = path8.join(prismaClientDir, "package.json");
|
|
10566
10725
|
const [functionPackage, clientPackageContent] = await Promise.all([
|
|
10567
|
-
readNitroOutputPackage(nitroFuncDir,
|
|
10568
|
-
|
|
10726
|
+
readNitroOutputPackage(nitroFuncDir, fs3),
|
|
10727
|
+
fs3.readFile(clientPackagePath, "utf-8")
|
|
10569
10728
|
]);
|
|
10570
10729
|
const clientPackage = JSON.parse(clientPackageContent);
|
|
10571
10730
|
functionPackage.dependencies = {
|
|
10572
10731
|
...functionPackage.dependencies,
|
|
10573
10732
|
"@prisma/client": clientPackage.version
|
|
10574
10733
|
};
|
|
10575
|
-
await writeNitroOutputPackage(nitroFuncDir, functionPackage,
|
|
10734
|
+
await writeNitroOutputPackage(nitroFuncDir, functionPackage, fs3);
|
|
10576
10735
|
}
|
|
10577
10736
|
__name(copyPrismaClientForVercel, "copyPrismaClientForVercel");
|
|
10578
10737
|
|
|
10738
|
+
// src/build/project-module-runner.ts
|
|
10739
|
+
async function createFarmProjectModuleSsrEnvironment() {
|
|
10740
|
+
const vite = await import("vite");
|
|
10741
|
+
const { ModuleRunner, createNodeImportMeta } = await import("vite/module-runner");
|
|
10742
|
+
return {
|
|
10743
|
+
dev: {
|
|
10744
|
+
createEnvironment(name, config) {
|
|
10745
|
+
return vite.createRunnableDevEnvironment(name, config, {
|
|
10746
|
+
runner: /* @__PURE__ */ __name((environment) => new ModuleRunner({
|
|
10747
|
+
transport: {
|
|
10748
|
+
...vite.createServerModuleRunnerTransport({ channel: environment.hot }),
|
|
10749
|
+
timeout: 0
|
|
10750
|
+
},
|
|
10751
|
+
hmr: false,
|
|
10752
|
+
createImportMeta: createNodeImportMeta,
|
|
10753
|
+
sourcemapInterceptor: "node"
|
|
10754
|
+
}), "runner")
|
|
10755
|
+
});
|
|
10756
|
+
}
|
|
10757
|
+
}
|
|
10758
|
+
};
|
|
10759
|
+
}
|
|
10760
|
+
__name(createFarmProjectModuleSsrEnvironment, "createFarmProjectModuleSsrEnvironment");
|
|
10761
|
+
|
|
10579
10762
|
// src/build/index.ts
|
|
10580
10763
|
async function build(config, options = {}) {
|
|
10581
10764
|
return withProductionNodeEnv(() => buildWithProductionNodeEnv(config, options));
|
|
@@ -10721,9 +10904,9 @@ async function buildWithProductionNodeEnv(inputConfig, options) {
|
|
|
10721
10904
|
} else {
|
|
10722
10905
|
const { build: legacyViteBuild } = await import("vite");
|
|
10723
10906
|
logger.info("\u{1F4E6} Building client bundle...");
|
|
10724
|
-
await buildClient2(legacyViteBuild, config, root, srcDir,
|
|
10907
|
+
await buildClient2(legacyViteBuild, config, root, srcDir, path9.join(root, distDir, "client"));
|
|
10725
10908
|
logger.info("\u{1F4E6} Building SSR bundle...");
|
|
10726
|
-
await buildSSR(legacyViteBuild, config, root, srcDir,
|
|
10909
|
+
await buildSSR(legacyViteBuild, config, root, srcDir, path9.join(root, distDir, "server"));
|
|
10727
10910
|
logger.info(`\u{1F680} Building server with Nitro (preset: ${preset})...`);
|
|
10728
10911
|
await buildNitro(
|
|
10729
10912
|
config,
|
|
@@ -10836,6 +11019,14 @@ async function createProjectModuleServer(createViteServer, config, root, buildLi
|
|
|
10836
11019
|
optimizeDeps: {
|
|
10837
11020
|
...viteConfig.optimizeDeps,
|
|
10838
11021
|
noDiscovery: true
|
|
11022
|
+
},
|
|
11023
|
+
// An app or plugin that brings its own SSR environment keeps it.
|
|
11024
|
+
environments: viteConfig.environments?.ssr?.dev?.createEnvironment ? viteConfig.environments : {
|
|
11025
|
+
...viteConfig.environments,
|
|
11026
|
+
ssr: {
|
|
11027
|
+
...viteConfig.environments?.ssr,
|
|
11028
|
+
...await createFarmProjectModuleSsrEnvironment()
|
|
11029
|
+
}
|
|
10839
11030
|
}
|
|
10840
11031
|
});
|
|
10841
11032
|
}
|
|
@@ -10903,12 +11094,12 @@ async function buildSSR(viteBuild, config, root, srcDir, outputDir) {
|
|
|
10903
11094
|
}
|
|
10904
11095
|
__name(buildSSR, "buildSSR");
|
|
10905
11096
|
function resolveLegacyPageEntry(config, root, srcDir) {
|
|
10906
|
-
const appDir =
|
|
11097
|
+
const appDir = path9.join(root, srcDir, "app");
|
|
10907
11098
|
for (const extension of getFarmRendererComponentExtensions(config.renderer)) {
|
|
10908
|
-
const candidate =
|
|
11099
|
+
const candidate = path9.join(appDir, `page${extension}`);
|
|
10909
11100
|
if (existsSync3(candidate)) return candidate;
|
|
10910
11101
|
}
|
|
10911
|
-
return
|
|
11102
|
+
return path9.join(appDir, "page.tsx");
|
|
10912
11103
|
}
|
|
10913
11104
|
__name(resolveLegacyPageEntry, "resolveLegacyPageEntry");
|
|
10914
11105
|
async function buildNitro(config, routeManager, apiRouteManager, serverRenderer, preset, root, distDir, pluginManager) {
|
|
@@ -10927,23 +11118,23 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
|
|
|
10927
11118
|
nitroConfig = await pluginManager.runHookSerial("beforeNitroBuild", nitroConfig);
|
|
10928
11119
|
}
|
|
10929
11120
|
const outputDir = resolveDeployOutputPath(root, config.deploy.outputDir);
|
|
10930
|
-
const serverOutputDir =
|
|
10931
|
-
const publicOutputDir =
|
|
11121
|
+
const serverOutputDir = path9.join(outputDir, "server");
|
|
11122
|
+
const publicOutputDir = path9.join(outputDir, "public");
|
|
10932
11123
|
const { mkdir, cp } = await import("fs/promises");
|
|
10933
11124
|
await mkdir(serverOutputDir, { recursive: true });
|
|
10934
11125
|
await mkdir(publicOutputDir, { recursive: true });
|
|
10935
|
-
const clientDir =
|
|
11126
|
+
const clientDir = path9.join(root, distDir, "client");
|
|
10936
11127
|
try {
|
|
10937
11128
|
await mkdir(publicOutputDir, { recursive: true });
|
|
10938
11129
|
await cp(clientDir, publicOutputDir, { recursive: true });
|
|
10939
11130
|
logger.info("\u{1F4E6} Copied client assets to public directory");
|
|
10940
|
-
const manifestPath =
|
|
10941
|
-
const assetsDir =
|
|
11131
|
+
const manifestPath = path9.join(publicOutputDir, "farm-client-manifest.json");
|
|
11132
|
+
const assetsDir = path9.join(publicOutputDir, "assets");
|
|
10942
11133
|
const manifestExists = await import("fs/promises").then(
|
|
10943
|
-
(
|
|
11134
|
+
(fs3) => fs3.access(manifestPath).then(() => true).catch(() => false)
|
|
10944
11135
|
);
|
|
10945
11136
|
const assetsExist = await import("fs/promises").then(
|
|
10946
|
-
(
|
|
11137
|
+
(fs3) => fs3.access(assetsDir).then(() => true).catch(() => false)
|
|
10947
11138
|
);
|
|
10948
11139
|
if (manifestExists && assetsExist) {
|
|
10949
11140
|
logger.info("\u2705 Verified client assets are present");
|
|
@@ -10954,8 +11145,8 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
|
|
|
10954
11145
|
logger.error(`\u274C Failed to copy client assets: ${error}`);
|
|
10955
11146
|
throw error;
|
|
10956
11147
|
}
|
|
10957
|
-
const serverDir =
|
|
10958
|
-
const nitroServerDir =
|
|
11148
|
+
const serverDir = path9.join(root, distDir, "server");
|
|
11149
|
+
const nitroServerDir = path9.join(root, distDir, ".nitro", "server", "farm");
|
|
10959
11150
|
try {
|
|
10960
11151
|
await mkdir(nitroServerDir, { recursive: true });
|
|
10961
11152
|
await cp(serverDir, nitroServerDir, { recursive: true });
|
|
@@ -10964,7 +11155,7 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
|
|
|
10964
11155
|
logger.warn(`Could not copy SSR bundles: ${error}`);
|
|
10965
11156
|
}
|
|
10966
11157
|
const nitro = await createNitro(nitroConfig);
|
|
10967
|
-
const registryPath =
|
|
11158
|
+
const registryPath = path9.join(root, distDir, ".nitro", "server", "farm-registry.ts");
|
|
10968
11159
|
try {
|
|
10969
11160
|
const { farmRegistry } = await import(
|
|
10970
11161
|
/* @vite-ignore */
|
|
@@ -10981,7 +11172,7 @@ async function buildNitro(config, routeManager, apiRouteManager, serverRenderer,
|
|
|
10981
11172
|
}
|
|
10982
11173
|
farmRegistry.routePaths = routePaths;
|
|
10983
11174
|
try {
|
|
10984
|
-
const clientManifestPath =
|
|
11175
|
+
const clientManifestPath = path9.join(root, distDir, "client", "farm-client-manifest.json");
|
|
10985
11176
|
const { readFile } = await import("fs/promises");
|
|
10986
11177
|
const manifestContent = await readFile(clientManifestPath, "utf-8");
|
|
10987
11178
|
farmRegistry.clientManifest = JSON.parse(manifestContent);
|