@farm.js/core 0.1.0-beta.97 → 0.1.0-beta.99
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/after.cjs.map +1 -0
- package/dist/agent-runtime.cjs +7 -3
- package/dist/agent-runtime.cjs.map +1 -0
- package/dist/agent-runtime.d.mts +2 -2
- package/dist/agent-runtime.d.ts +2 -2
- package/dist/agent-runtime.mjs +2 -1
- package/dist/agent-runtime.mjs.map +1 -1
- package/dist/api/route-manager.cjs.map +1 -0
- package/dist/api/route-manager.d.mts +2 -2
- package/dist/api/route-manager.d.ts +2 -2
- package/dist/api/runtime.cjs.map +1 -0
- package/dist/api.cjs +26 -1
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.mts +3 -3
- package/dist/api.d.ts +3 -3
- package/dist/api.mjs +2 -2
- package/dist/{app-CIOx3LvY.d.ts → app-CGjrKNoN.d.ts} +4 -4
- package/dist/{app-DBd6437H.d.mts → app-DOcLs_iq.d.mts} +4 -4
- package/dist/app-markdown.cjs +21 -0
- package/dist/app-markdown.cjs.map +1 -0
- package/dist/app-markdown.d.mts +19 -4
- package/dist/app-markdown.d.ts +19 -4
- package/dist/app-markdown.mjs +7 -1
- package/dist/cache.cjs.map +1 -0
- package/dist/{chunk-VMCHLH3Y.mjs → chunk-26BCDVJS.mjs} +19 -1
- package/dist/chunk-26BCDVJS.mjs.map +1 -0
- package/dist/{chunk-FP5Q67FO.mjs → chunk-2HYYZCCI.mjs} +308 -19
- package/dist/chunk-2HYYZCCI.mjs.map +1 -0
- package/dist/{chunk-WKDAA6V2.mjs → chunk-3BTAMIQE.mjs} +100 -41
- package/dist/chunk-3BTAMIQE.mjs.map +1 -0
- package/dist/{chunk-WD2EBM3I.mjs → chunk-3CQJV3NC.mjs} +2 -2
- package/dist/{chunk-I3OOUWO5.mjs → chunk-3GDRV7SG.mjs} +2 -2
- package/dist/{chunk-YIBV77KZ.mjs → chunk-4WLAVHCY.mjs} +2 -2
- package/dist/{chunk-KDP5ZSWP.mjs → chunk-7PS5NKOM.mjs} +26 -11
- package/dist/chunk-7PS5NKOM.mjs.map +1 -0
- package/dist/{chunk-X4SFHKFH.mjs → chunk-BU65A3LZ.mjs} +10 -6
- package/dist/chunk-BU65A3LZ.mjs.map +1 -0
- package/dist/{chunk-WMJGA32P.mjs → chunk-BXVOHG6B.mjs} +27 -2
- package/dist/{chunk-WMJGA32P.mjs.map → chunk-BXVOHG6B.mjs.map} +1 -1
- package/dist/{chunk-BZAIS65C.mjs → chunk-DIHNOVZZ.mjs} +40 -13
- package/dist/chunk-DIHNOVZZ.mjs.map +1 -0
- package/dist/{chunk-ISSFLGJ5.mjs → chunk-FDWECN3W.mjs} +8 -4
- package/dist/chunk-FDWECN3W.mjs.map +1 -0
- package/dist/chunk-FDWXXTWR.mjs +114 -0
- package/dist/chunk-FDWXXTWR.mjs.map +1 -0
- package/dist/{chunk-FSIXEIOB.mjs → chunk-L7FSTPGS.mjs} +2 -2
- package/dist/{chunk-J3MPQ4MQ.mjs → chunk-LG4XB6RN.mjs} +2 -2
- package/dist/{chunk-J3MPQ4MQ.mjs.map → chunk-LG4XB6RN.mjs.map} +1 -1
- package/dist/{chunk-AAC66ILR.mjs → chunk-LXXG3K2Y.mjs} +61 -2
- package/dist/chunk-LXXG3K2Y.mjs.map +1 -0
- package/dist/{chunk-GJ7W6LNK.mjs → chunk-N5RK4LK6.mjs} +3 -3
- package/dist/{chunk-D7F7YZ7L.mjs → chunk-NCVFPT67.mjs} +100 -40
- package/dist/{chunk-D7F7YZ7L.mjs.map → chunk-NCVFPT67.mjs.map} +1 -1
- package/dist/{chunk-UMUWR5XA.mjs → chunk-PURU7FXR.mjs} +2 -2
- package/dist/{chunk-2SKCXYLB.mjs → chunk-QQCCBMTH.mjs} +60 -6
- package/dist/chunk-QQCCBMTH.mjs.map +1 -0
- package/dist/chunk-RKUPOYQV.mjs +28 -0
- package/dist/chunk-RKUPOYQV.mjs.map +1 -0
- package/dist/{chunk-52BR7LTX.mjs → chunk-STSPSJUI.mjs} +3 -3
- package/dist/{chunk-EPDIF432.mjs → chunk-UOGX6UNO.mjs} +37 -17
- package/dist/chunk-UOGX6UNO.mjs.map +1 -0
- package/dist/{chunk-IZBX2TEU.mjs → chunk-VQG3QWWK.mjs} +2 -2
- package/dist/{chunk-35NPLKQJ.mjs → chunk-XWM2C267.mjs} +21 -105
- package/dist/chunk-XWM2C267.mjs.map +1 -0
- package/dist/{chunk-7ZVN3YZI.mjs → chunk-Z5ARESQG.mjs} +43 -1
- package/dist/chunk-Z5ARESQG.mjs.map +1 -0
- package/dist/client/lifecycle.cjs.map +1 -0
- package/dist/client/lifecycle.mjs +2 -2
- package/dist/{client-plugins-B6-07YmP.d.mts → client-plugins-BqtHoJ9C.d.mts} +91 -3
- package/dist/{client-plugins-By6MVUX-.d.ts → client-plugins-DYprkCKN.d.ts} +91 -3
- package/dist/client-plugins.cjs +1 -1
- package/dist/client-plugins.cjs.map +1 -0
- package/dist/client-plugins.d.mts +2 -2
- package/dist/client-plugins.d.ts +2 -2
- package/dist/client-plugins.mjs +2 -2
- package/dist/client.cjs +61 -16
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +5 -5
- package/dist/client.d.ts +5 -5
- package/dist/client.mjs +7 -7
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.mts +2 -2
- package/dist/config.d.ts +2 -2
- package/dist/cron.cjs +48 -12
- package/dist/cron.cjs.map +1 -0
- package/dist/cron.mjs +2 -1
- package/dist/deferred.cjs.map +1 -0
- package/dist/deployment.cjs.map +1 -0
- package/dist/{devtools-XWZX6CCL.mjs → devtools-24N3U5IG.mjs} +9 -7
- package/dist/{devtools-XWZX6CCL.mjs.map → devtools-24N3U5IG.mjs.map} +1 -1
- package/dist/docs.cjs +7 -3
- package/dist/docs.cjs.map +1 -0
- package/dist/docs.mjs +9 -7
- package/dist/env-types.cjs.map +1 -0
- package/dist/env.cjs.map +1 -0
- package/dist/environment/vite.cjs.map +1 -0
- package/dist/environment.cjs.map +1 -0
- package/dist/font.cjs.map +1 -0
- package/dist/headers.cjs.map +1 -0
- package/dist/i18n/client.cjs.map +1 -0
- package/dist/i18n/index.cjs.map +1 -0
- package/dist/i18n/server.cjs.map +1 -0
- package/dist/image/server.cjs +99 -40
- package/dist/image/server.cjs.map +1 -0
- package/dist/image/server.d.mts +6 -0
- package/dist/image/server.d.ts +6 -0
- package/dist/image/server.mjs +1 -1
- package/dist/image/sharp.cjs +1 -0
- package/dist/image/sharp.cjs.map +1 -0
- package/dist/image/sharp.d.mts +1 -1
- package/dist/image/sharp.d.ts +1 -1
- package/dist/image/sharp.mjs +1 -1
- package/dist/image/sharp.mjs.map +1 -1
- package/dist/image.cjs.map +1 -0
- package/dist/index.cjs +943 -231
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.mjs +38 -24
- package/dist/index.mjs.map +1 -1
- package/dist/instrumentation.cjs.map +1 -0
- package/dist/{integration-orm-LLW6WZNK.mjs → integration-orm-G5BPBT5X.mjs} +3 -3
- package/dist/integrations.cjs +168 -5
- package/dist/integrations.cjs.map +1 -0
- package/dist/integrations.d.mts +2 -2
- package/dist/integrations.d.ts +2 -2
- package/dist/integrations.mjs +10 -3
- package/dist/internal/build-runtime.cjs +745 -139
- package/dist/internal/build-runtime.cjs.map +1 -0
- package/dist/internal/build-runtime.d.mts +4 -4
- package/dist/internal/build-runtime.d.ts +4 -4
- package/dist/internal/build-runtime.mjs +16 -14
- package/dist/internal/client-runtime.cjs +7 -2
- package/dist/internal/client-runtime.cjs.map +1 -0
- package/dist/internal/client-runtime.mjs +8 -3
- package/dist/internal/client-runtime.mjs.map +1 -1
- package/dist/internal/config-runtime.cjs +59 -42
- package/dist/internal/config-runtime.cjs.map +1 -0
- package/dist/internal/config-runtime.d.mts +3 -3
- package/dist/internal/config-runtime.d.ts +3 -3
- package/dist/internal/config-runtime.mjs +8 -6
- package/dist/internal/isolated-boundary.cjs.map +1 -0
- package/dist/internal/metadata-image-runtime.cjs.map +1 -0
- package/dist/internal/product-telemetry-runtime.cjs +52 -5
- package/dist/internal/product-telemetry-runtime.cjs.map +1 -0
- package/dist/internal/product-telemetry-runtime.d.mts +12 -1
- package/dist/internal/product-telemetry-runtime.d.ts +12 -1
- package/dist/internal/product-telemetry-runtime.mjs +50 -5
- package/dist/internal/product-telemetry-runtime.mjs.map +1 -1
- package/dist/internal/production-node-env.cjs.map +1 -0
- package/dist/internal/production-runtime.cjs +56 -10
- package/dist/internal/production-runtime.cjs.map +1 -0
- package/dist/internal/production-runtime.d.mts +8 -8
- package/dist/internal/production-runtime.d.ts +8 -8
- package/dist/internal/production-runtime.mjs +2 -2
- package/dist/markdown.cjs.map +1 -0
- package/dist/{metadata-route-8_V3UonT.d.ts → metadata-route-D2be_0kC.d.ts} +17 -2
- package/dist/{metadata-route-CWP_HjGU.d.mts → metadata-route-Dw5CrDIZ.d.mts} +17 -2
- package/dist/middleware.cjs.map +1 -0
- package/dist/middleware.d.mts +4 -4
- package/dist/middleware.d.ts +4 -4
- package/dist/navigation.cjs.map +1 -0
- package/dist/{nitro-EGRNOB5P.mjs → nitro-YJEP3FWM.mjs} +4 -3
- package/dist/{nitro-EGRNOB5P.mjs.map → nitro-YJEP3FWM.mjs.map} +1 -1
- package/dist/observability.cjs.map +1 -0
- package/dist/plugin.cjs +599 -104
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.mts +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.mjs +13 -11
- package/dist/{production-runtime-CdmzsDax.d.ts → production-runtime-CTqpD1C8.d.ts} +2 -2
- package/dist/{production-runtime-BGRH1dKG.d.mts → production-runtime-HNqNZd4D.d.mts} +2 -2
- package/dist/query/client.cjs.map +1 -0
- package/dist/query/index.cjs.map +1 -0
- package/dist/query/parsers.cjs.map +1 -0
- package/dist/query/server.cjs.map +1 -0
- package/dist/{render-plan-DLxJYAA5.d.mts → render-plan-COscpW-i.d.mts} +1 -1
- package/dist/{render-plan-0GeHiGVZ.d.ts → render-plan-Z4kSxaT_.d.ts} +1 -1
- package/dist/renderer/react/client.cjs.map +1 -0
- package/dist/renderer/react/server.cjs.map +1 -0
- package/dist/renderer/react/vite.cjs.map +1 -0
- package/dist/renderer-client.cjs +26 -1
- package/dist/renderer-client.cjs.map +1 -0
- package/dist/renderer-client.d.mts +4 -4
- package/dist/renderer-client.d.ts +4 -4
- package/dist/renderer-client.mjs +2 -2
- package/dist/renderer.cjs.map +1 -0
- package/dist/{request-BstWbZ6O.d.ts → request-BEDb2jE9.d.ts} +1 -1
- package/dist/{request-BCNXSXLh.d.mts → request-CbIAqJY9.d.mts} +1 -1
- package/dist/request.cjs.map +1 -0
- package/dist/request.d.mts +3 -3
- package/dist/request.d.ts +3 -3
- package/dist/router.cjs.map +1 -0
- package/dist/routes.cjs.map +1 -0
- package/dist/routes.d.mts +2 -2
- package/dist/routes.d.ts +2 -2
- package/dist/server-action-security.cjs +117 -104
- package/dist/server-action-security.cjs.map +1 -0
- package/dist/server-action-security.mjs +2 -1
- package/dist/server-fn-client.cjs.map +1 -0
- package/dist/server-fn.cjs.map +1 -0
- package/dist/server-fn.mjs +3 -2
- package/dist/server-plugins.cjs.map +1 -0
- package/dist/server-plugins.d.mts +3 -3
- package/dist/server-plugins.d.ts +3 -3
- package/dist/server-query-client.cjs +26 -1
- package/dist/server-query-client.cjs.map +1 -0
- package/dist/server-query-client.mjs +3 -3
- package/dist/server-query.cjs.map +1 -0
- package/dist/server-query.mjs +4 -3
- package/dist/server.cjs +686 -170
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.mts +8 -8
- package/dist/server.d.ts +8 -8
- package/dist/server.mjs +16 -14
- package/dist/server.mjs.map +1 -1
- package/dist/{spa-router-COgu4txb.d.ts → spa-router-CjeQites.d.ts} +1 -1
- package/dist/{spa-router-BeyAVSc6.d.mts → spa-router-FJbNou1a.d.mts} +1 -1
- package/dist/storage.cjs +7 -3
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.mjs +1 -1
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.mjs +2 -1
- package/dist/testing.mjs.map +1 -1
- package/dist/theme/client.cjs.map +1 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/runtime.cjs.map +1 -0
- package/dist/theme/server.cjs.map +1 -0
- package/dist/{utils-DL2VwDQl.d.mts → utils-BiMJv9Ys.d.mts} +1 -1
- package/dist/{utils-DkU2c_1B.d.ts → utils-BpnKRFv9.d.ts} +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -0
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +599 -104
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.mts +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.mjs +13 -11
- package/dist/{workflows-ChyK_oTu.d.mts → workflows-BantWytQ.d.mts} +7 -0
- package/dist/{workflows-ChyK_oTu.d.ts → workflows-BantWytQ.d.ts} +7 -0
- package/dist/workflows.cjs +73 -5
- package/dist/workflows.cjs.map +1 -0
- package/dist/workflows.d.mts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.mjs +2 -1
- package/package.json +17 -17
- package/dist/chunk-2SKCXYLB.mjs.map +0 -1
- package/dist/chunk-35NPLKQJ.mjs.map +0 -1
- package/dist/chunk-7ZVN3YZI.mjs.map +0 -1
- package/dist/chunk-AAC66ILR.mjs.map +0 -1
- package/dist/chunk-BZAIS65C.mjs.map +0 -1
- package/dist/chunk-EPDIF432.mjs.map +0 -1
- package/dist/chunk-FP5Q67FO.mjs.map +0 -1
- package/dist/chunk-ISSFLGJ5.mjs.map +0 -1
- package/dist/chunk-KDP5ZSWP.mjs.map +0 -1
- package/dist/chunk-VMCHLH3Y.mjs.map +0 -1
- package/dist/chunk-WKDAA6V2.mjs.map +0 -1
- package/dist/chunk-X4SFHKFH.mjs.map +0 -1
- /package/dist/{chunk-WD2EBM3I.mjs.map → chunk-3CQJV3NC.mjs.map} +0 -0
- /package/dist/{chunk-I3OOUWO5.mjs.map → chunk-3GDRV7SG.mjs.map} +0 -0
- /package/dist/{chunk-YIBV77KZ.mjs.map → chunk-4WLAVHCY.mjs.map} +0 -0
- /package/dist/{chunk-FSIXEIOB.mjs.map → chunk-L7FSTPGS.mjs.map} +0 -0
- /package/dist/{chunk-GJ7W6LNK.mjs.map → chunk-N5RK4LK6.mjs.map} +0 -0
- /package/dist/{chunk-UMUWR5XA.mjs.map → chunk-PURU7FXR.mjs.map} +0 -0
- /package/dist/{chunk-52BR7LTX.mjs.map → chunk-STSPSJUI.mjs.map} +0 -0
- /package/dist/{chunk-IZBX2TEU.mjs.map → chunk-VQG3QWWK.mjs.map} +0 -0
- /package/dist/{integration-orm-LLW6WZNK.mjs.map → integration-orm-G5BPBT5X.mjs.map} +0 -0
|
@@ -410,6 +410,54 @@ var init_route_pattern = __esm({
|
|
|
410
410
|
}
|
|
411
411
|
});
|
|
412
412
|
|
|
413
|
+
// src/request-origin.ts
|
|
414
|
+
function normalizeAllowedOriginPattern(value, label) {
|
|
415
|
+
const pattern = value.trim().toLowerCase();
|
|
416
|
+
if (!pattern) {
|
|
417
|
+
throw new TypeError(`${label} cannot contain empty values`);
|
|
418
|
+
}
|
|
419
|
+
if (pattern.includes("*")) {
|
|
420
|
+
if (!/^(?:https?:\/\/)?\*\.[a-z0-9.-]+(?::\d+)?$/.test(pattern)) {
|
|
421
|
+
throw new TypeError(`Invalid ${label} pattern: ${JSON.stringify(value)}`);
|
|
422
|
+
}
|
|
423
|
+
return pattern;
|
|
424
|
+
}
|
|
425
|
+
if (pattern.includes("://")) {
|
|
426
|
+
let parsed;
|
|
427
|
+
try {
|
|
428
|
+
parsed = new URL(pattern);
|
|
429
|
+
} catch {
|
|
430
|
+
throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
|
|
431
|
+
}
|
|
432
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
433
|
+
throw new TypeError(`${label} must contain origins without paths: ${JSON.stringify(value)}`);
|
|
434
|
+
}
|
|
435
|
+
return parsed.origin;
|
|
436
|
+
}
|
|
437
|
+
if (/[/@?#]/.test(pattern)) {
|
|
438
|
+
throw new TypeError(`${label} must contain origins or hosts: ${JSON.stringify(value)}`);
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
return new URL(`http://${pattern}`).host;
|
|
442
|
+
} catch {
|
|
443
|
+
throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
var init_request_origin = __esm({
|
|
447
|
+
"src/request-origin.ts"() {
|
|
448
|
+
"use strict";
|
|
449
|
+
__name(normalizeAllowedOriginPattern, "normalizeAllowedOriginPattern");
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// src/integration-request-security.ts
|
|
454
|
+
var init_integration_request_security = __esm({
|
|
455
|
+
"src/integration-request-security.ts"() {
|
|
456
|
+
"use strict";
|
|
457
|
+
init_request_origin();
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
|
|
413
461
|
// src/integration-api.ts
|
|
414
462
|
function defineIntegrationAPIOperation(operation) {
|
|
415
463
|
return {
|
|
@@ -1426,9 +1474,13 @@ function getStorage(namespace) {
|
|
|
1426
1474
|
const namespaced = (0, import_unstorage.prefixStorage)(globalStorage, base);
|
|
1427
1475
|
return {
|
|
1428
1476
|
...namespaced,
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1477
|
+
// Scope the wipe to the namespace instead of the whole storage, and keep
|
|
1478
|
+
// the caller's base so `clear("sessions")` cannot take unrelated keys with
|
|
1479
|
+
// it. Dropping the argument silently widens a targeted clear into a
|
|
1480
|
+
// namespace-wide delete.
|
|
1481
|
+
async clear(base2, opts) {
|
|
1482
|
+
const keys = await namespaced.getKeys(base2);
|
|
1483
|
+
await Promise.all(keys.map((key) => namespaced.removeItem(key, opts)));
|
|
1432
1484
|
}
|
|
1433
1485
|
};
|
|
1434
1486
|
}
|
|
@@ -3456,6 +3508,7 @@ var init_integrations = __esm({
|
|
|
3456
3508
|
"src/integrations.ts"() {
|
|
3457
3509
|
"use strict";
|
|
3458
3510
|
init_route_pattern();
|
|
3511
|
+
init_integration_request_security();
|
|
3459
3512
|
init_integration_api();
|
|
3460
3513
|
init_plugin_integration_context();
|
|
3461
3514
|
init_decode();
|
|
@@ -3885,6 +3938,29 @@ var init_search_params = __esm({
|
|
|
3885
3938
|
}
|
|
3886
3939
|
});
|
|
3887
3940
|
|
|
3941
|
+
// src/utils/runtime-env.ts
|
|
3942
|
+
function getFarmRuntimeBindings() {
|
|
3943
|
+
const runtimeBindings = globalThis.__env__;
|
|
3944
|
+
return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
|
|
3945
|
+
}
|
|
3946
|
+
function readFarmEnvironmentValue(name2) {
|
|
3947
|
+
const runtimeValue = getFarmRuntimeBindings()?.[name2];
|
|
3948
|
+
if (typeof runtimeValue === "string") return runtimeValue;
|
|
3949
|
+
return typeof process !== "undefined" ? process.env?.[name2] : void 0;
|
|
3950
|
+
}
|
|
3951
|
+
function isFarmDeployedRuntime() {
|
|
3952
|
+
if (getFarmRuntimeBindings()) return true;
|
|
3953
|
+
return readFarmEnvironmentValue("NODE_ENV") === "production";
|
|
3954
|
+
}
|
|
3955
|
+
var init_runtime_env = __esm({
|
|
3956
|
+
"src/utils/runtime-env.ts"() {
|
|
3957
|
+
"use strict";
|
|
3958
|
+
__name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
|
|
3959
|
+
__name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
|
|
3960
|
+
__name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
|
|
3961
|
+
}
|
|
3962
|
+
});
|
|
3963
|
+
|
|
3888
3964
|
// src/utils.ts
|
|
3889
3965
|
function parseRoutePath(filePath) {
|
|
3890
3966
|
const segments = [];
|
|
@@ -4109,7 +4185,8 @@ function resolveWorkflowsConfig(workflows) {
|
|
|
4109
4185
|
dirs,
|
|
4110
4186
|
route: normalizeWorkflowRoute(options.route || DEFAULT_FARM_WORKFLOW_ROUTE),
|
|
4111
4187
|
secretEnv: options.secretEnv || DEFAULT_FARM_WORKFLOW_SECRET_ENV,
|
|
4112
|
-
secret: options.secret
|
|
4188
|
+
secret: options.secret,
|
|
4189
|
+
allowUnsecured: options.allowUnsecured === true
|
|
4113
4190
|
};
|
|
4114
4191
|
}
|
|
4115
4192
|
async function discoverFarmWorkflows(config, options = {}) {
|
|
@@ -4235,8 +4312,11 @@ async function prepareFarmWorkflowsForNitro(config) {
|
|
|
4235
4312
|
await fs15.mkdir(generatedDir, { recursive: true });
|
|
4236
4313
|
const tasks = {};
|
|
4237
4314
|
const scheduledTasks = createScheduledTasks(workflows);
|
|
4315
|
+
const wrapperNames = resolveWorkflowWrapperFileNames(workflows.map((workflow) => workflow.id));
|
|
4238
4316
|
for (const workflow of workflows) {
|
|
4239
|
-
const wrapperPath = toPosixPath(
|
|
4317
|
+
const wrapperPath = toPosixPath(
|
|
4318
|
+
path42.join(generatedDir, `${wrapperNames.get(workflow.id)}.mjs`)
|
|
4319
|
+
);
|
|
4240
4320
|
await fs15.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
|
|
4241
4321
|
tasks[workflow.id] = {
|
|
4242
4322
|
handler: wrapperPath,
|
|
@@ -4474,6 +4554,7 @@ import {
|
|
|
4474
4554
|
const route = ${JSON.stringify(config.route)};
|
|
4475
4555
|
const secretEnv = ${JSON.stringify(config.secretEnv)};
|
|
4476
4556
|
const inlineSecret = ${JSON.stringify(config.secret || "")};
|
|
4557
|
+
const allowUnsecured = ${JSON.stringify(config.allowUnsecured === true)};
|
|
4477
4558
|
const bodySizeLimit = ${JSON.stringify(server.bodySizeLimit)};
|
|
4478
4559
|
const workflows = ${JSON.stringify(workflows.map(toWorkflowMetadata))};
|
|
4479
4560
|
const workflowIds = new Set(workflows.map((workflow) => workflow.id));
|
|
@@ -4503,7 +4584,10 @@ function getSecret() {
|
|
|
4503
4584
|
|
|
4504
4585
|
function verifySecret(event) {
|
|
4505
4586
|
const secret = getSecret();
|
|
4506
|
-
if (!secret)
|
|
4587
|
+
if (!secret) {
|
|
4588
|
+
if (allowUnsecured) return null;
|
|
4589
|
+
return json({ error: ${JSON.stringify(MISSING_FARM_WORKFLOW_SECRET_ERROR)} }, 401);
|
|
4590
|
+
}
|
|
4507
4591
|
const authorization = getHeader(event, "authorization") || "";
|
|
4508
4592
|
const headerSecret = getHeader(event, "x-farm-workflow-secret") || "";
|
|
4509
4593
|
const bearer = authorization.match(/^Bearer\\s+(.+)$/i)?.[1] || "";
|
|
@@ -4597,8 +4681,16 @@ function readScheduledTime(payload) {
|
|
|
4597
4681
|
return payload && typeof payload === "object" && "scheduledTime" in payload ? payload.scheduledTime : void 0;
|
|
4598
4682
|
}
|
|
4599
4683
|
function verifyWorkflowSecret(request, config) {
|
|
4600
|
-
const secret = config.secret ||
|
|
4601
|
-
if (!secret)
|
|
4684
|
+
const secret = config.secret || readFarmEnvironmentValue(config.secretEnv) || "";
|
|
4685
|
+
if (!secret) {
|
|
4686
|
+
if (config.allowUnsecured === true || !isFarmDeployedRuntime()) return null;
|
|
4687
|
+
return Response.json(
|
|
4688
|
+
{
|
|
4689
|
+
error: MISSING_FARM_WORKFLOW_SECRET_ERROR
|
|
4690
|
+
},
|
|
4691
|
+
{ status: 401 }
|
|
4692
|
+
);
|
|
4693
|
+
}
|
|
4602
4694
|
const authorization = request.headers.get("authorization") || "";
|
|
4603
4695
|
const bearer = authorization.match(/^Bearer\s+(.+)$/i)?.[1] || "";
|
|
4604
4696
|
const headerSecret = request.headers.get("x-farm-workflow-secret") || "";
|
|
@@ -4611,18 +4703,50 @@ function joinRoute(...parts) {
|
|
|
4611
4703
|
function trimSlashes(value) {
|
|
4612
4704
|
return value.replace(/^\/+|\/+$/g, "");
|
|
4613
4705
|
}
|
|
4706
|
+
function resolveWorkflowWrapperFileNames(ids) {
|
|
4707
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4708
|
+
for (const id of ids) {
|
|
4709
|
+
const key = safeFileName(id).toLowerCase();
|
|
4710
|
+
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
4711
|
+
}
|
|
4712
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
4713
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
4714
|
+
for (const id of ids) {
|
|
4715
|
+
const base = safeFileName(id);
|
|
4716
|
+
const key = base.toLowerCase();
|
|
4717
|
+
const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${workflowIdFingerprint(id)}` : base;
|
|
4718
|
+
const claimedBy = claimed.get(fileName.toLowerCase());
|
|
4719
|
+
if (claimedBy !== void 0) {
|
|
4720
|
+
throw new Error(
|
|
4721
|
+
`Farm workflows ${JSON.stringify(claimedBy)} and ${JSON.stringify(id)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
|
|
4722
|
+
);
|
|
4723
|
+
}
|
|
4724
|
+
claimed.set(fileName.toLowerCase(), id);
|
|
4725
|
+
resolved.set(id, fileName);
|
|
4726
|
+
}
|
|
4727
|
+
return resolved;
|
|
4728
|
+
}
|
|
4729
|
+
function workflowIdFingerprint(value) {
|
|
4730
|
+
let hash = 2166136261;
|
|
4731
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4732
|
+
hash ^= value.charCodeAt(index);
|
|
4733
|
+
hash = Math.imul(hash, 16777619);
|
|
4734
|
+
}
|
|
4735
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
4736
|
+
}
|
|
4614
4737
|
function safeFileName(value) {
|
|
4615
4738
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "workflow";
|
|
4616
4739
|
}
|
|
4617
4740
|
function relativePath(root, filePath) {
|
|
4618
4741
|
return filePath.replace(/\\/g, "/").replace(`${root.replace(/\\/g, "/")}/`, "");
|
|
4619
4742
|
}
|
|
4620
|
-
var import_node_path, DEFAULT_FARM_WORKFLOW_DIRS, DEFAULT_FARM_WORKFLOW_ROUTE, DEFAULT_FARM_WORKFLOW_SECRET_ENV;
|
|
4743
|
+
var import_node_path, DEFAULT_FARM_WORKFLOW_DIRS, DEFAULT_FARM_WORKFLOW_ROUTE, DEFAULT_FARM_WORKFLOW_SECRET_ENV, MISSING_FARM_WORKFLOW_SECRET_ERROR;
|
|
4621
4744
|
var init_workflows = __esm({
|
|
4622
4745
|
"src/workflows.ts"() {
|
|
4623
4746
|
"use strict";
|
|
4624
4747
|
init_server_http();
|
|
4625
4748
|
init_search_params();
|
|
4749
|
+
init_runtime_env();
|
|
4626
4750
|
init_decode();
|
|
4627
4751
|
init_utils();
|
|
4628
4752
|
init_route_pattern();
|
|
@@ -4630,6 +4754,7 @@ var init_workflows = __esm({
|
|
|
4630
4754
|
DEFAULT_FARM_WORKFLOW_DIRS = ["src/jobs", "src/workflows", "src/cron"];
|
|
4631
4755
|
DEFAULT_FARM_WORKFLOW_ROUTE = "/api/_farm/workflows";
|
|
4632
4756
|
DEFAULT_FARM_WORKFLOW_SECRET_ENV = "CRON_SECRET";
|
|
4757
|
+
MISSING_FARM_WORKFLOW_SECRET_ERROR = "Workflow route requires a secret. Set the CRON_SECRET environment variable, configure workflows.secret, or set workflows.allowUnsecured to true.";
|
|
4633
4758
|
__name(defineWorkflow, "defineWorkflow");
|
|
4634
4759
|
__name(defineTask, "defineTask");
|
|
4635
4760
|
__name(defineCron, "defineCron");
|
|
@@ -4662,6 +4787,8 @@ var init_workflows = __esm({
|
|
|
4662
4787
|
__name(verifyWorkflowSecret, "verifyWorkflowSecret");
|
|
4663
4788
|
__name(joinRoute, "joinRoute");
|
|
4664
4789
|
__name(trimSlashes, "trimSlashes");
|
|
4790
|
+
__name(resolveWorkflowWrapperFileNames, "resolveWorkflowWrapperFileNames");
|
|
4791
|
+
__name(workflowIdFingerprint, "workflowIdFingerprint");
|
|
4665
4792
|
__name(safeFileName, "safeFileName");
|
|
4666
4793
|
__name(relativePath, "relativePath");
|
|
4667
4794
|
}
|
|
@@ -4713,9 +4840,10 @@ async function prepareFarmCronForNitro(config) {
|
|
|
4713
4840
|
await fs15.rm(generatedDir, { recursive: true, force: true });
|
|
4714
4841
|
await fs15.mkdir(generatedDir, { recursive: true });
|
|
4715
4842
|
const tasks = {};
|
|
4843
|
+
const wrapperNames = resolveCronWrapperFileNames(cron.jobs.map((job) => job.name));
|
|
4716
4844
|
for (const job of cron.jobs) {
|
|
4717
4845
|
const taskName = getFarmCronTaskName(job.name);
|
|
4718
|
-
const wrapperPath = toPosixPath(path42.join(generatedDir, `${
|
|
4846
|
+
const wrapperPath = toPosixPath(path42.join(generatedDir, `${wrapperNames.get(job.name)}.mjs`));
|
|
4719
4847
|
await fs15.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
|
|
4720
4848
|
tasks[taskName] = {
|
|
4721
4849
|
handler: wrapperPath,
|
|
@@ -4977,6 +5105,37 @@ export default defineTask({
|
|
|
4977
5105
|
});
|
|
4978
5106
|
`.trim();
|
|
4979
5107
|
}
|
|
5108
|
+
function resolveCronWrapperFileNames(names) {
|
|
5109
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5110
|
+
for (const name2 of names) {
|
|
5111
|
+
const key = safeFileName2(name2).toLowerCase();
|
|
5112
|
+
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
5113
|
+
}
|
|
5114
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
5115
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
5116
|
+
for (const name2 of names) {
|
|
5117
|
+
const base = safeFileName2(name2);
|
|
5118
|
+
const key = base.toLowerCase();
|
|
5119
|
+
const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${cronNameFingerprint(name2)}` : base;
|
|
5120
|
+
const claimedBy = claimed.get(fileName.toLowerCase());
|
|
5121
|
+
if (claimedBy !== void 0) {
|
|
5122
|
+
throw new Error(
|
|
5123
|
+
`Farm cron jobs ${JSON.stringify(claimedBy)} and ${JSON.stringify(name2)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
|
|
5124
|
+
);
|
|
5125
|
+
}
|
|
5126
|
+
claimed.set(fileName.toLowerCase(), name2);
|
|
5127
|
+
resolved.set(name2, fileName);
|
|
5128
|
+
}
|
|
5129
|
+
return resolved;
|
|
5130
|
+
}
|
|
5131
|
+
function cronNameFingerprint(value) {
|
|
5132
|
+
let hash = 2166136261;
|
|
5133
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
5134
|
+
hash ^= value.charCodeAt(index);
|
|
5135
|
+
hash = Math.imul(hash, 16777619);
|
|
5136
|
+
}
|
|
5137
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
5138
|
+
}
|
|
4980
5139
|
function safeFileName2(value) {
|
|
4981
5140
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "cron";
|
|
4982
5141
|
}
|
|
@@ -4985,6 +5144,7 @@ var init_cron = __esm({
|
|
|
4985
5144
|
"src/cron.ts"() {
|
|
4986
5145
|
"use strict";
|
|
4987
5146
|
init_utils();
|
|
5147
|
+
init_runtime_env();
|
|
4988
5148
|
DEFAULT_FARM_CRON_SECRET_ENV = "CRON_SECRET";
|
|
4989
5149
|
FARM_CRON_MANIFEST = "cron-manifest.json";
|
|
4990
5150
|
CRON_FIELD_RANGES = [
|
|
@@ -5013,6 +5173,8 @@ var init_cron = __esm({
|
|
|
5013
5173
|
__name(mergeTaskNames, "mergeTaskNames");
|
|
5014
5174
|
__name(getFarmCronTaskName, "getFarmCronTaskName");
|
|
5015
5175
|
__name(createNitroCronTaskWrapper, "createNitroCronTaskWrapper");
|
|
5176
|
+
__name(resolveCronWrapperFileNames, "resolveCronWrapperFileNames");
|
|
5177
|
+
__name(cronNameFingerprint, "cronNameFingerprint");
|
|
5016
5178
|
__name(safeFileName2, "safeFileName");
|
|
5017
5179
|
}
|
|
5018
5180
|
});
|
|
@@ -5604,7 +5766,9 @@ var init_server_fn_error = __esm({
|
|
|
5604
5766
|
|
|
5605
5767
|
// src/server-action-security.ts
|
|
5606
5768
|
function resolveServerActionsConfig(config) {
|
|
5607
|
-
const allowedOrigins = (config?.allowedOrigins ?? []).map(
|
|
5769
|
+
const allowedOrigins = (config?.allowedOrigins ?? []).map(
|
|
5770
|
+
(value) => normalizeAllowedOriginPattern(value, SERVER_ACTION_ALLOWED_ORIGINS_LABEL)
|
|
5771
|
+
);
|
|
5608
5772
|
const bodySizeLimit = parseBodySizeLimit(
|
|
5609
5773
|
config?.bodySizeLimit ?? DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT,
|
|
5610
5774
|
"serverActions.bodySizeLimit"
|
|
@@ -5624,50 +5788,16 @@ function getServerActionStorage() {
|
|
|
5624
5788
|
}
|
|
5625
5789
|
return globalState2[SERVER_ACTION_STORAGE_KEY];
|
|
5626
5790
|
}
|
|
5627
|
-
|
|
5628
|
-
const pattern = value.trim().toLowerCase();
|
|
5629
|
-
if (!pattern) {
|
|
5630
|
-
throw new TypeError("serverActions.allowedOrigins cannot contain empty values");
|
|
5631
|
-
}
|
|
5632
|
-
if (pattern.includes("*")) {
|
|
5633
|
-
if (!/^(?:https?:\/\/)?\*\.[a-z0-9.-]+(?::\d+)?$/.test(pattern)) {
|
|
5634
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins pattern: ${JSON.stringify(value)}`);
|
|
5635
|
-
}
|
|
5636
|
-
return pattern;
|
|
5637
|
-
}
|
|
5638
|
-
if (pattern.includes("://")) {
|
|
5639
|
-
let parsed;
|
|
5640
|
-
try {
|
|
5641
|
-
parsed = new URL(pattern);
|
|
5642
|
-
} catch {
|
|
5643
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
|
|
5644
|
-
}
|
|
5645
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
5646
|
-
throw new TypeError(
|
|
5647
|
-
`serverActions.allowedOrigins must contain origins without paths: ${JSON.stringify(value)}`
|
|
5648
|
-
);
|
|
5649
|
-
}
|
|
5650
|
-
return parsed.origin;
|
|
5651
|
-
}
|
|
5652
|
-
if (/[/@?#]/.test(pattern)) {
|
|
5653
|
-
throw new TypeError(
|
|
5654
|
-
`serverActions.allowedOrigins must contain origins or hosts: ${JSON.stringify(value)}`
|
|
5655
|
-
);
|
|
5656
|
-
}
|
|
5657
|
-
try {
|
|
5658
|
-
return new URL(`http://${pattern}`).host;
|
|
5659
|
-
} catch {
|
|
5660
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
|
|
5661
|
-
}
|
|
5662
|
-
}
|
|
5663
|
-
var import_node_async_hooks, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, SERVER_ACTION_STORAGE_KEY;
|
|
5791
|
+
var import_node_async_hooks, SERVER_ACTION_ALLOWED_ORIGINS_LABEL, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, SERVER_ACTION_STORAGE_KEY;
|
|
5664
5792
|
var init_server_action_security = __esm({
|
|
5665
5793
|
"src/server-action-security.ts"() {
|
|
5666
5794
|
"use strict";
|
|
5667
5795
|
import_node_async_hooks = require("async_hooks");
|
|
5668
5796
|
init_cache_invalidation();
|
|
5797
|
+
init_request_origin();
|
|
5669
5798
|
init_server_fn_error();
|
|
5670
5799
|
init_server_http();
|
|
5800
|
+
SERVER_ACTION_ALLOWED_ORIGINS_LABEL = "serverActions.allowedOrigins";
|
|
5671
5801
|
DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT = 1e6;
|
|
5672
5802
|
SERVER_ACTION_STORAGE_KEY = /* @__PURE__ */ Symbol.for("farm.serverActionStorage");
|
|
5673
5803
|
__name(resolveServerActionsConfig, "resolveServerActionsConfig");
|
|
@@ -5679,7 +5809,6 @@ var init_server_action_security = __esm({
|
|
|
5679
5809
|
getServerActionExecutionContext()?.cacheTasks.add(task);
|
|
5680
5810
|
});
|
|
5681
5811
|
__name(getServerActionStorage, "getServerActionStorage");
|
|
5682
|
-
__name(normalizeAllowedOriginPattern, "normalizeAllowedOriginPattern");
|
|
5683
5812
|
}
|
|
5684
5813
|
});
|
|
5685
5814
|
|
|
@@ -7121,6 +7250,51 @@ var init_config2 = __esm({
|
|
|
7121
7250
|
}
|
|
7122
7251
|
});
|
|
7123
7252
|
|
|
7253
|
+
// src/agent-config.ts
|
|
7254
|
+
function resolveFarmAgentConfig(input) {
|
|
7255
|
+
const jsonLd = input?.jsonLd;
|
|
7256
|
+
if (!jsonLd) return { jsonLd: false };
|
|
7257
|
+
return { jsonLd: jsonLd === true ? {} : jsonLd };
|
|
7258
|
+
}
|
|
7259
|
+
function pruneUndefined(object) {
|
|
7260
|
+
const result = {};
|
|
7261
|
+
for (const [key, value] of Object.entries(object)) {
|
|
7262
|
+
if (value !== void 0 && value !== null && value !== "") result[key] = value;
|
|
7263
|
+
}
|
|
7264
|
+
return result;
|
|
7265
|
+
}
|
|
7266
|
+
function serializeJsonLd(value) {
|
|
7267
|
+
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
7268
|
+
}
|
|
7269
|
+
function renderFarmAgentJsonLd(config, context2) {
|
|
7270
|
+
const base = pruneUndefined({
|
|
7271
|
+
name: config.name ?? context2.siteName ?? context2.title,
|
|
7272
|
+
url: config.url ?? context2.metadataBase,
|
|
7273
|
+
description: config.description ?? context2.description,
|
|
7274
|
+
logo: config.logo,
|
|
7275
|
+
sameAs: config.sameAs && config.sameAs.length > 0 ? config.sameAs : void 0
|
|
7276
|
+
});
|
|
7277
|
+
const object = {
|
|
7278
|
+
"@context": "https://schema.org",
|
|
7279
|
+
"@type": config.type || "Organization",
|
|
7280
|
+
...base,
|
|
7281
|
+
...config.properties || {}
|
|
7282
|
+
};
|
|
7283
|
+
if (Object.keys(object).length <= 2 && !config.properties) {
|
|
7284
|
+
return "";
|
|
7285
|
+
}
|
|
7286
|
+
return `<script type="application/ld+json">${serializeJsonLd(object)}</script>`;
|
|
7287
|
+
}
|
|
7288
|
+
var init_agent_config = __esm({
|
|
7289
|
+
"src/agent-config.ts"() {
|
|
7290
|
+
"use strict";
|
|
7291
|
+
__name(resolveFarmAgentConfig, "resolveFarmAgentConfig");
|
|
7292
|
+
__name(pruneUndefined, "pruneUndefined");
|
|
7293
|
+
__name(serializeJsonLd, "serializeJsonLd");
|
|
7294
|
+
__name(renderFarmAgentJsonLd, "renderFarmAgentJsonLd");
|
|
7295
|
+
}
|
|
7296
|
+
});
|
|
7297
|
+
|
|
7124
7298
|
// src/renderer.ts
|
|
7125
7299
|
function getFarmRendererCapabilities(renderer) {
|
|
7126
7300
|
return {
|
|
@@ -7886,6 +8060,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
7886
8060
|
const openapi = {
|
|
7887
8061
|
enabled: false,
|
|
7888
8062
|
route: "/docs/reference",
|
|
8063
|
+
specRoute: "/openapi.json",
|
|
7889
8064
|
title: "API Documentation",
|
|
7890
8065
|
description: "Auto-generated API documentation",
|
|
7891
8066
|
version: "1.0.0",
|
|
@@ -7893,6 +8068,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
7893
8068
|
...userConfig.openapi
|
|
7894
8069
|
};
|
|
7895
8070
|
if (openapi.route !== void 0) validateConfigRouteSource(openapi.route, "openapi.route");
|
|
8071
|
+
if (openapi.specRoute) validateConfigRouteSource(openapi.specRoute, "openapi.specRoute");
|
|
7896
8072
|
const resolved = {
|
|
7897
8073
|
[FARM_RESOLVED_CUSTOM_CONTEXT]: typeof userConfig.context === "function",
|
|
7898
8074
|
root,
|
|
@@ -7925,6 +8101,7 @@ async function resolveConfig(userConfig, mode) {
|
|
|
7925
8101
|
ppr: false,
|
|
7926
8102
|
...userConfig.experimental
|
|
7927
8103
|
},
|
|
8104
|
+
agent: resolveFarmAgentConfig(userConfig.agent),
|
|
7928
8105
|
plugins: [...resolveIntegrationPlugins(integrations), ...userConfig.plugins || []],
|
|
7929
8106
|
integrations,
|
|
7930
8107
|
trailingSlash: userConfig.trailingSlash ?? false,
|
|
@@ -8033,6 +8210,7 @@ var init_config4 = __esm({
|
|
|
8033
8210
|
init_security();
|
|
8034
8211
|
init_navigation_errors();
|
|
8035
8212
|
init_config2();
|
|
8213
|
+
init_agent_config();
|
|
8036
8214
|
init_renderer();
|
|
8037
8215
|
init_framework_detect();
|
|
8038
8216
|
init_config3();
|
|
@@ -10909,6 +11087,18 @@ var init_routes_server = __esm({
|
|
|
10909
11087
|
function isFarmMarkdownPageFile(filePath) {
|
|
10910
11088
|
return /(^|[/\\])page\.mdx?$/i.test(filePath);
|
|
10911
11089
|
}
|
|
11090
|
+
function farmRequestWantsMarkdown(pathname, accept) {
|
|
11091
|
+
return pathname.toLowerCase().endsWith(".md") || requestAcceptsMarkdown(accept);
|
|
11092
|
+
}
|
|
11093
|
+
function createFarmMarkdownErrorBody(status, pathname, homeHref = "/") {
|
|
11094
|
+
const heading = status === 404 ? "Page not found" : `Request failed (${status})`;
|
|
11095
|
+
return `# ${heading}
|
|
11096
|
+
|
|
11097
|
+
No page is available at \`${pathname}\`. The URL may be incorrect, or the page has not been published.
|
|
11098
|
+
|
|
11099
|
+
Browse [the site homepage](${homeHref}) to find available pages.
|
|
11100
|
+
`;
|
|
11101
|
+
}
|
|
10912
11102
|
function normalizeFarmMarkdownRoutePath(pathname) {
|
|
10913
11103
|
const withoutExtension = pathname.replace(/\.md$/i, "");
|
|
10914
11104
|
const normalized = withoutExtension.startsWith("/") ? withoutExtension : `/${withoutExtension}`;
|
|
@@ -11052,7 +11242,7 @@ async function createFarmMarkdownSourceResponse(options) {
|
|
|
11052
11242
|
headers
|
|
11053
11243
|
});
|
|
11054
11244
|
}
|
|
11055
|
-
var import_promises4, import_path4, import_url;
|
|
11245
|
+
var import_promises4, import_path4, import_url, FARM_MARKDOWN_CONTENT_TYPE;
|
|
11056
11246
|
var init_app_markdown = __esm({
|
|
11057
11247
|
"src/app-markdown.ts"() {
|
|
11058
11248
|
"use strict";
|
|
@@ -11062,6 +11252,9 @@ var init_app_markdown = __esm({
|
|
|
11062
11252
|
init_markdown();
|
|
11063
11253
|
init_app_markdown_config();
|
|
11064
11254
|
__name(isFarmMarkdownPageFile, "isFarmMarkdownPageFile");
|
|
11255
|
+
FARM_MARKDOWN_CONTENT_TYPE = "text/markdown; charset=utf-8";
|
|
11256
|
+
__name(farmRequestWantsMarkdown, "farmRequestWantsMarkdown");
|
|
11257
|
+
__name(createFarmMarkdownErrorBody, "createFarmMarkdownErrorBody");
|
|
11065
11258
|
__name(normalizeFarmMarkdownRoutePath, "normalizeFarmMarkdownRoutePath");
|
|
11066
11259
|
__name(parseMarkdownFrontmatter, "parseMarkdownFrontmatter");
|
|
11067
11260
|
__name(titleFromMarkdown, "titleFromMarkdown");
|
|
@@ -11569,6 +11762,39 @@ function getStaticImportBindings(content) {
|
|
|
11569
11762
|
}
|
|
11570
11763
|
return bindings;
|
|
11571
11764
|
}
|
|
11765
|
+
function findParserSensitiveJsxContainer(content, localBindings) {
|
|
11766
|
+
if (!content || localBindings.length === 0) return void 0;
|
|
11767
|
+
const names = new Set(localBindings);
|
|
11768
|
+
const tokens = tokenizeModuleSource(content);
|
|
11769
|
+
const openDepth = /* @__PURE__ */ new Map();
|
|
11770
|
+
const isSelfClosing = /* @__PURE__ */ __name((openingIndex) => {
|
|
11771
|
+
for (let index = openingIndex; index < tokens.length; index++) {
|
|
11772
|
+
if (tokens[index].value === ">") return tokens[index - 1]?.value === "/";
|
|
11773
|
+
}
|
|
11774
|
+
return false;
|
|
11775
|
+
}, "isSelfClosing");
|
|
11776
|
+
for (let index = 0; index < tokens.length - 1; index++) {
|
|
11777
|
+
if (tokens[index].value !== "<") continue;
|
|
11778
|
+
if (tokens[index + 1].value === "/") {
|
|
11779
|
+
const closing = tokens[index + 2]?.value;
|
|
11780
|
+
if (closing && openDepth.has(closing)) {
|
|
11781
|
+
openDepth.set(closing, Math.max(0, (openDepth.get(closing) ?? 0) - 1));
|
|
11782
|
+
}
|
|
11783
|
+
continue;
|
|
11784
|
+
}
|
|
11785
|
+
const tag = tokens[index + 1].value;
|
|
11786
|
+
if (names.has(tag)) {
|
|
11787
|
+
for (const [container, depth] of openDepth) {
|
|
11788
|
+
if (depth > 0) return container;
|
|
11789
|
+
}
|
|
11790
|
+
continue;
|
|
11791
|
+
}
|
|
11792
|
+
if (PARSER_SENSITIVE_JSX_CONTAINERS.has(tag) && !isSelfClosing(index)) {
|
|
11793
|
+
openDepth.set(tag, (openDepth.get(tag) ?? 0) + 1);
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11796
|
+
return void 0;
|
|
11797
|
+
}
|
|
11572
11798
|
function countStaticJsxUses(content, localBindings) {
|
|
11573
11799
|
if (!content || localBindings.length === 0) return 0;
|
|
11574
11800
|
const names = new Set(localBindings);
|
|
@@ -11677,6 +11903,36 @@ function getClientRenderingHelpers(tokens, clientBindings) {
|
|
|
11677
11903
|
}
|
|
11678
11904
|
return helpers;
|
|
11679
11905
|
}
|
|
11906
|
+
function passesElementValuedProps(content, localBindings) {
|
|
11907
|
+
if (!content || localBindings.length === 0) return false;
|
|
11908
|
+
const names = new Set(localBindings);
|
|
11909
|
+
const tokens = tokenizeModuleSource(content);
|
|
11910
|
+
for (let index = 0; index < tokens.length - 1; index++) {
|
|
11911
|
+
if (tokens[index].value !== "<" || !names.has(tokens[index + 1].value)) continue;
|
|
11912
|
+
const name2 = tokens[index + 1].value;
|
|
11913
|
+
let cursor = index + 2;
|
|
11914
|
+
let braceDepth = 0;
|
|
11915
|
+
let selfClosing = false;
|
|
11916
|
+
for (; cursor < tokens.length; cursor++) {
|
|
11917
|
+
const value = tokens[cursor].value;
|
|
11918
|
+
if (value === "{") braceDepth++;
|
|
11919
|
+
else if (value === "}") braceDepth--;
|
|
11920
|
+
else if (value === "<" && braceDepth > 0) return true;
|
|
11921
|
+
else if (value === ">" && braceDepth === 0) {
|
|
11922
|
+
selfClosing = tokens[cursor - 1]?.value === "/";
|
|
11923
|
+
break;
|
|
11924
|
+
}
|
|
11925
|
+
}
|
|
11926
|
+
if (selfClosing || cursor >= tokens.length) continue;
|
|
11927
|
+
for (let child = cursor + 1; child < tokens.length; child++) {
|
|
11928
|
+
if (tokens[child].value !== "<") continue;
|
|
11929
|
+
const closesBoundary = tokens[child + 1]?.value === "/" && tokens[child + 2]?.value === name2;
|
|
11930
|
+
if (!closesBoundary) return true;
|
|
11931
|
+
break;
|
|
11932
|
+
}
|
|
11933
|
+
}
|
|
11934
|
+
return false;
|
|
11935
|
+
}
|
|
11680
11936
|
function hasDynamicJsxCardinality(content, localBindings) {
|
|
11681
11937
|
if (!content || localBindings.length === 0) return false;
|
|
11682
11938
|
const clientBindings = new Set(localBindings);
|
|
@@ -11758,6 +12014,17 @@ function collectIsolatedClientBoundaries(ownerPath, root) {
|
|
|
11758
12014
|
if (fallbackReason || importedBoundaryCount === 0) continue;
|
|
11759
12015
|
const localBindings = importedBindings.get(specifier) ?? [];
|
|
11760
12016
|
const staticUses = countStaticJsxUses(content, localBindings);
|
|
12017
|
+
if (staticUses > 0) {
|
|
12018
|
+
const container = findParserSensitiveJsxContainer(content, localBindings);
|
|
12019
|
+
if (container) {
|
|
12020
|
+
fallbackReason = `the client boundary imported from ${specifier} renders inside <${container}>, where the HTML parser relocates its hydration marker`;
|
|
12021
|
+
return 0;
|
|
12022
|
+
}
|
|
12023
|
+
if (passesElementValuedProps(content, localBindings)) {
|
|
12024
|
+
fallbackReason = `the client boundary imported from ${specifier} receives React elements, which cannot cross the boundary as serialized props`;
|
|
12025
|
+
return 0;
|
|
12026
|
+
}
|
|
12027
|
+
}
|
|
11761
12028
|
if (staticUses > 0 && hasDynamicJsxCardinality(content, localBindings)) {
|
|
11762
12029
|
fallbackReason = `the client boundary count imported from ${specifier} is data-dependent`;
|
|
11763
12030
|
costGuardExceeded = true;
|
|
@@ -12054,7 +12321,7 @@ function resolveSourceCandidate(candidates) {
|
|
|
12054
12321
|
}
|
|
12055
12322
|
return null;
|
|
12056
12323
|
}
|
|
12057
|
-
var import_fs2, import_path5, import_url2, FARM_ISOLATED_HYDRATION_MAX_BOUNDARIES, RESOLVABLE_SOURCE_EXTENSIONS, REGEXP_PREFIX_PUNCTUATION, REGEXP_PREFIX_KEYWORDS;
|
|
12324
|
+
var import_fs2, import_path5, import_url2, FARM_ISOLATED_HYDRATION_MAX_BOUNDARIES, RESOLVABLE_SOURCE_EXTENSIONS, REGEXP_PREFIX_PUNCTUATION, REGEXP_PREFIX_KEYWORDS, PARSER_SENSITIVE_JSX_CONTAINERS;
|
|
12058
12325
|
var init_client_component = __esm({
|
|
12059
12326
|
"src/utils/client-component.ts"() {
|
|
12060
12327
|
"use strict";
|
|
@@ -12132,11 +12399,23 @@ var init_client_component = __esm({
|
|
|
12132
12399
|
__name(enforceFarmIsolatedHydrationRouteBudget, "enforceFarmIsolatedHydrationRouteBudget");
|
|
12133
12400
|
__name(isIsolatableClientBoundarySource, "isIsolatableClientBoundarySource");
|
|
12134
12401
|
__name(getStaticImportBindings, "getStaticImportBindings");
|
|
12402
|
+
PARSER_SENSITIVE_JSX_CONTAINERS = /* @__PURE__ */ new Set([
|
|
12403
|
+
"table",
|
|
12404
|
+
"thead",
|
|
12405
|
+
"tbody",
|
|
12406
|
+
"tfoot",
|
|
12407
|
+
"tr",
|
|
12408
|
+
"select",
|
|
12409
|
+
"optgroup",
|
|
12410
|
+
"svg"
|
|
12411
|
+
]);
|
|
12412
|
+
__name(findParserSensitiveJsxContainer, "findParserSensitiveJsxContainer");
|
|
12135
12413
|
__name(countStaticJsxUses, "countStaticJsxUses");
|
|
12136
12414
|
__name(findMatchingToken, "findMatchingToken");
|
|
12137
12415
|
__name(containsClientJsx, "containsClientJsx");
|
|
12138
12416
|
__name(findStatementEnd, "findStatementEnd");
|
|
12139
12417
|
__name(getClientRenderingHelpers, "getClientRenderingHelpers");
|
|
12418
|
+
__name(passesElementValuedProps, "passesElementValuedProps");
|
|
12140
12419
|
__name(hasDynamicJsxCardinality, "hasDynamicJsxCardinality");
|
|
12141
12420
|
__name(collectIsolatedClientBoundaries, "collectIsolatedClientBoundaries");
|
|
12142
12421
|
__name(inspectClientModuleMetadata, "inspectClientModuleMetadata");
|
|
@@ -13779,7 +14058,7 @@ function addMetadataImageReference(metadata, reference) {
|
|
|
13779
14058
|
twitter
|
|
13780
14059
|
};
|
|
13781
14060
|
}
|
|
13782
|
-
function renderMetadataHead(metadata) {
|
|
14061
|
+
function renderMetadataHead(metadata, options = {}) {
|
|
13783
14062
|
const resolvedMetadata = metadata || {};
|
|
13784
14063
|
const metadataBase = resolveMetadataBase(resolvedMetadata);
|
|
13785
14064
|
const explicitTitle = resolveMetadataTitle(resolvedMetadata.title);
|
|
@@ -13800,14 +14079,16 @@ function renderMetadataHead(metadata) {
|
|
|
13800
14079
|
appendMetaName(tags, "publisher", resolvedMetadata.publisher);
|
|
13801
14080
|
appendMetaName(tags, "robots", normalizeRobots(resolvedMetadata.robots));
|
|
13802
14081
|
const alternates = resolvedMetadata.alternates;
|
|
13803
|
-
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
14082
|
+
const explicitCanonical = isRecord3(alternates) ? alternates.canonical : void 0;
|
|
14083
|
+
const canonicalHref = explicitCanonical != null ? resolveMetadataUrl(explicitCanonical, metadataBase) : options.pathname ? resolveMetadataUrl(options.pathname, metadataBase) : void 0;
|
|
14084
|
+
if (canonicalHref) {
|
|
14085
|
+
appendLink(tags, "canonical", canonicalHref);
|
|
14086
|
+
}
|
|
14087
|
+
if (isRecord3(alternates) && isRecord3(alternates.languages)) {
|
|
14088
|
+
for (const [language, href] of Object.entries(alternates.languages)) {
|
|
14089
|
+
appendLink(tags, "alternate", resolveMetadataUrl(href, metadataBase), {
|
|
14090
|
+
hreflang: language
|
|
14091
|
+
});
|
|
13811
14092
|
}
|
|
13812
14093
|
}
|
|
13813
14094
|
const hasFavicon = appendIcons(tags, resolvedMetadata.icons, metadataBase);
|
|
@@ -13820,6 +14101,16 @@ function renderMetadataHead(metadata) {
|
|
|
13820
14101
|
}
|
|
13821
14102
|
appendOpenGraph(tags, resolvedMetadata.openGraph, metadataBase);
|
|
13822
14103
|
appendTwitter(tags, resolvedMetadata.twitter, metadataBase);
|
|
14104
|
+
if (options.jsonLd) {
|
|
14105
|
+
const jsonLdConfig = options.jsonLd === true ? {} : options.jsonLd;
|
|
14106
|
+
const jsonLdScript = renderFarmAgentJsonLd(jsonLdConfig, {
|
|
14107
|
+
metadataBase,
|
|
14108
|
+
siteName: isRecord3(resolvedMetadata.openGraph) ? normalizeContent(resolvedMetadata.openGraph.siteName) : void 0,
|
|
14109
|
+
title: explicitTitle,
|
|
14110
|
+
description: normalizeContent(resolvedMetadata.description)
|
|
14111
|
+
});
|
|
14112
|
+
if (jsonLdScript) tags.push(jsonLdScript);
|
|
14113
|
+
}
|
|
13823
14114
|
return {
|
|
13824
14115
|
title: escapeText(title),
|
|
13825
14116
|
tags: tags.length > 0 ? `
|
|
@@ -13843,7 +14134,7 @@ function appendOpenGraph(tags, openGraph, metadataBase) {
|
|
|
13843
14134
|
appendMetaProperty(tags, "og:description", openGraph.description);
|
|
13844
14135
|
appendMetaProperty(tags, "og:url", resolveMetadataUrl(openGraph.url, metadataBase));
|
|
13845
14136
|
appendMetaProperty(tags, "og:site_name", openGraph.siteName);
|
|
13846
|
-
appendMetaProperty(tags, "og:type", openGraph.type);
|
|
14137
|
+
appendMetaProperty(tags, "og:type", openGraph.type ?? "website");
|
|
13847
14138
|
appendMetaProperty(tags, "og:locale", openGraph.locale);
|
|
13848
14139
|
const images = normalizeMetadataImages(
|
|
13849
14140
|
openGraph.images ?? openGraph.image,
|
|
@@ -14006,6 +14297,7 @@ function escapeAttribute(value) {
|
|
|
14006
14297
|
var init_metadata = __esm({
|
|
14007
14298
|
"src/metadata.ts"() {
|
|
14008
14299
|
"use strict";
|
|
14300
|
+
init_agent_config();
|
|
14009
14301
|
__name(mergeMetadata, "mergeMetadata");
|
|
14010
14302
|
__name(mergeMetadataTitle, "mergeMetadataTitle");
|
|
14011
14303
|
__name(applyTitleTemplate, "applyTitleTemplate");
|
|
@@ -17097,7 +17389,7 @@ var init_server3 = __esm({
|
|
|
17097
17389
|
var version;
|
|
17098
17390
|
var init_package = __esm({
|
|
17099
17391
|
"package.json"() {
|
|
17100
|
-
version = "0.1.0-beta.
|
|
17392
|
+
version = "0.1.0-beta.99";
|
|
17101
17393
|
}
|
|
17102
17394
|
});
|
|
17103
17395
|
|
|
@@ -17352,6 +17644,12 @@ function hasRequestHeader(req, name2) {
|
|
|
17352
17644
|
const value = req.headers[name2.toLowerCase()];
|
|
17353
17645
|
return Array.isArray(value) ? value.length > 0 : Boolean(value);
|
|
17354
17646
|
}
|
|
17647
|
+
function getFarmMetadataPathname(req) {
|
|
17648
|
+
const raw = req.__FARM_ROUTE__ || req.url;
|
|
17649
|
+
if (typeof raw !== "string" || raw.length === 0) return void 0;
|
|
17650
|
+
const boundary = raw.search(/[?#]/);
|
|
17651
|
+
return boundary === -1 ? raw : raw.slice(0, boundary);
|
|
17652
|
+
}
|
|
17355
17653
|
function serializeInlineValue2(value) {
|
|
17356
17654
|
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
17357
17655
|
}
|
|
@@ -17500,6 +17798,7 @@ var init_renderer2 = __esm({
|
|
|
17500
17798
|
init_server();
|
|
17501
17799
|
init_request_context();
|
|
17502
17800
|
init_ssg();
|
|
17801
|
+
init_app_markdown();
|
|
17503
17802
|
init_integrations();
|
|
17504
17803
|
init_request();
|
|
17505
17804
|
init_cache();
|
|
@@ -17541,6 +17840,7 @@ var init_renderer2 = __esm({
|
|
|
17541
17840
|
warnedFullDocumentLayout = false;
|
|
17542
17841
|
__name(warnFarmFullDocumentLayout, "warnFarmFullDocumentLayout");
|
|
17543
17842
|
__name(hasRequestHeader, "hasRequestHeader");
|
|
17843
|
+
__name(getFarmMetadataPathname, "getFarmMetadataPathname");
|
|
17544
17844
|
__name(serializeInlineValue2, "serializeInlineValue");
|
|
17545
17845
|
__name(escapeHtmlAttribute2, "escapeHtmlAttribute");
|
|
17546
17846
|
__name(appendResponseHeader, "appendResponseHeader");
|
|
@@ -17940,7 +18240,21 @@ var init_renderer2 = __esm({
|
|
|
17940
18240
|
const html = await this.rendererRuntime.renderToString(
|
|
17941
18241
|
await this.wrapWithIntegrationProviders(pageElement)
|
|
17942
18242
|
);
|
|
17943
|
-
await this.
|
|
18243
|
+
const mergedMetadata = await this.resolveRouteMetadata({
|
|
18244
|
+
layoutModules,
|
|
18245
|
+
routeModule: mod,
|
|
18246
|
+
pageProps,
|
|
18247
|
+
pathname: page2.urlPath
|
|
18248
|
+
});
|
|
18249
|
+
const { title, tags, hasFavicon } = renderMetadataHead(mergedMetadata);
|
|
18250
|
+
const metadataHead = `${hasFavicon ? "" : '<link rel="icon" href="data:,">\n '}<title>${title}</title>${tags}`;
|
|
18251
|
+
const fullDocument = this.createFullHTML(
|
|
18252
|
+
html,
|
|
18253
|
+
pageMetadata.shouldHydrate === true,
|
|
18254
|
+
page2.urlPath,
|
|
18255
|
+
metadataHead
|
|
18256
|
+
);
|
|
18257
|
+
await this.cacheSSGPage(page2, fullDocument, { document: true });
|
|
17944
18258
|
logger.info(`ISR: Regenerated ${page2.urlPath}`);
|
|
17945
18259
|
} catch (error) {
|
|
17946
18260
|
logger.error(`ISR regeneration failed for ${page2.urlPath}: ${error}`);
|
|
@@ -18980,7 +19294,10 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
|
|
|
18980
19294
|
tags: metaTags,
|
|
18981
19295
|
hasFavicon,
|
|
18982
19296
|
hasExplicitTitle
|
|
18983
|
-
} = renderMetadataHead(req.__FARM_METADATA__
|
|
19297
|
+
} = renderMetadataHead(req.__FARM_METADATA__, {
|
|
19298
|
+
pathname: getFarmMetadataPathname(req),
|
|
19299
|
+
jsonLd: this.config.agent?.jsonLd
|
|
19300
|
+
});
|
|
18984
19301
|
const documentTitleTag = !hasExplicitTitle && /<title[\s>]/i.test(rendererHead) ? "" : `<title>${title}</title>`;
|
|
18985
19302
|
const i18nSnapshot = getFarmI18nClientSnapshot();
|
|
18986
19303
|
const alternateTags = i18nSnapshot ? renderI18nAlternateLinks(req.__FARM_ROUTE__ || req.url || "/", i18nSnapshot) : "";
|
|
@@ -19165,7 +19482,10 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
|
|
|
19165
19482
|
title,
|
|
19166
19483
|
tags: metaTags,
|
|
19167
19484
|
hasFavicon
|
|
19168
|
-
} = renderMetadataHead(req.__FARM_METADATA__
|
|
19485
|
+
} = renderMetadataHead(req.__FARM_METADATA__, {
|
|
19486
|
+
pathname: getFarmMetadataPathname(req),
|
|
19487
|
+
jsonLd: this.config.agent?.jsonLd
|
|
19488
|
+
});
|
|
19169
19489
|
const i18nSnapshot = getFarmI18nClientSnapshot();
|
|
19170
19490
|
const i18nAlternateTags = i18nSnapshot ? renderI18nAlternateLinks(req.__FARM_ROUTE__ || req.url || "/", i18nSnapshot) : "";
|
|
19171
19491
|
const fontHead = renderFarmFontDevHead(this.config.root || process.cwd());
|
|
@@ -19323,6 +19643,15 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
|
|
|
19323
19643
|
const pathname = resolveFarmRequestURL(req, {
|
|
19324
19644
|
trustProxy: this.config.server?.trustProxy
|
|
19325
19645
|
}).pathname;
|
|
19646
|
+
const acceptHeader = req.headers.accept;
|
|
19647
|
+
const accept = Array.isArray(acceptHeader) ? acceptHeader.join(",") : acceptHeader;
|
|
19648
|
+
if (farmRequestWantsMarkdown(pathname, accept)) {
|
|
19649
|
+
res.setHeader("Content-Type", FARM_MARKDOWN_CONTENT_TYPE);
|
|
19650
|
+
res.setHeader("X-Farm-Markdown-Error", "404");
|
|
19651
|
+
res.setHeader("Cache-Control", "no-store");
|
|
19652
|
+
res.end(createFarmMarkdownErrorBody(404, pathname, this.config.basePath || "/"));
|
|
19653
|
+
return;
|
|
19654
|
+
}
|
|
19326
19655
|
try {
|
|
19327
19656
|
const appDir = path15.join(this.config.root, this.config.srcDir, "app");
|
|
19328
19657
|
const notFoundExtensions = getFarmRendererComponentExtensions(this.config.renderer);
|
|
@@ -19408,7 +19737,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
|
|
|
19408
19737
|
res.write(html);
|
|
19409
19738
|
res.end();
|
|
19410
19739
|
}
|
|
19411
|
-
createFullHTML(content, isClientComponent = false, requestPath = "/",
|
|
19740
|
+
createFullHTML(content, isClientComponent = false, requestPath = "/", metadataHead) {
|
|
19412
19741
|
const i18nSnapshot = getFarmI18nClientSnapshot();
|
|
19413
19742
|
const clientScript = isClientComponent ? ` <script type="module" src="/@farm/client.js"></script>` : "";
|
|
19414
19743
|
const integrationManifestScript = `<script>
|
|
@@ -19432,6 +19761,7 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};
|
|
|
19432
19761
|
headAssets: [
|
|
19433
19762
|
themeDocument.head,
|
|
19434
19763
|
`<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">`,
|
|
19764
|
+
metadataHead,
|
|
19435
19765
|
alternateLinks,
|
|
19436
19766
|
fontHead,
|
|
19437
19767
|
`<link rel="stylesheet" href="/src/app/globals.css" />`,
|
|
@@ -19450,8 +19780,7 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};
|
|
|
19450
19780
|
<meta charset="utf-8">
|
|
19451
19781
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
19452
19782
|
<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">
|
|
19453
|
-
<link rel="icon" href="data:,">
|
|
19454
|
-
<title>${escapeHtmlAttribute2(documentTitle)}</title>${alternateLinks}
|
|
19783
|
+
${metadataHead ?? '<link rel="icon" href="data:,">\n <title>Farm.js App</title>'}${alternateLinks}
|
|
19455
19784
|
${fontHead}
|
|
19456
19785
|
<link rel="stylesheet" href="/src/app/globals.css" />${this.collectDevStyleLinks().map((l) => `
|
|
19457
19786
|
${l}`).join("")}
|
|
@@ -19658,6 +19987,7 @@ var init_app = __esm({
|
|
|
19658
19987
|
ppr: config.experimental?.ppr ?? false,
|
|
19659
19988
|
...config.experimental
|
|
19660
19989
|
},
|
|
19990
|
+
agent: config.agent ?? {},
|
|
19661
19991
|
vite: config.vite || {}
|
|
19662
19992
|
};
|
|
19663
19993
|
}
|
|
@@ -25109,6 +25439,116 @@ var init_server_query_boundary = __esm({
|
|
|
25109
25439
|
}
|
|
25110
25440
|
});
|
|
25111
25441
|
|
|
25442
|
+
// src/client-boundary-env.ts
|
|
25443
|
+
function shouldInspectClientBoundary(id, code) {
|
|
25444
|
+
if (id.startsWith("\0") || id.startsWith("virtual:") || id.includes("node_modules")) return false;
|
|
25445
|
+
return code.includes("process.env") || code.includes("node:");
|
|
25446
|
+
}
|
|
25447
|
+
function analyzeClientBoundary(program, publicKeys) {
|
|
25448
|
+
const envKeys = /* @__PURE__ */ new Set();
|
|
25449
|
+
const publicEnvKeys = /* @__PURE__ */ new Set();
|
|
25450
|
+
const builtinImports = /* @__PURE__ */ new Set();
|
|
25451
|
+
const visit = /* @__PURE__ */ __name((node, inFunction) => {
|
|
25452
|
+
if (!node || typeof node !== "object") return;
|
|
25453
|
+
if (Array.isArray(node)) {
|
|
25454
|
+
for (const entry of node) visit(entry, inFunction);
|
|
25455
|
+
return;
|
|
25456
|
+
}
|
|
25457
|
+
const estree = node;
|
|
25458
|
+
if (typeof estree.type !== "string") return;
|
|
25459
|
+
if (!inFunction) {
|
|
25460
|
+
const builtin = readNodeBuiltinSource(estree);
|
|
25461
|
+
if (builtin !== void 0) builtinImports.add(builtin);
|
|
25462
|
+
const key = readProcessEnvKey(estree);
|
|
25463
|
+
if (key !== void 0) {
|
|
25464
|
+
if (key !== "NODE_ENV") {
|
|
25465
|
+
(publicKeys.has(key) ? publicEnvKeys : envKeys).add(key);
|
|
25466
|
+
}
|
|
25467
|
+
return;
|
|
25468
|
+
}
|
|
25469
|
+
}
|
|
25470
|
+
const nextInFunction = inFunction || FUNCTION_BODY_TYPES.has(estree.type);
|
|
25471
|
+
for (const [childKey, value] of Object.entries(estree)) {
|
|
25472
|
+
if (childKey === "type") continue;
|
|
25473
|
+
visit(value, nextInFunction);
|
|
25474
|
+
}
|
|
25475
|
+
}, "visit");
|
|
25476
|
+
visit(program.body, false);
|
|
25477
|
+
return {
|
|
25478
|
+
envKeys: [...envKeys],
|
|
25479
|
+
publicEnvKeys: [...publicEnvKeys],
|
|
25480
|
+
builtinImports: [...builtinImports]
|
|
25481
|
+
};
|
|
25482
|
+
}
|
|
25483
|
+
function readNodeBuiltinSource(node) {
|
|
25484
|
+
if (node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ImportExpression") {
|
|
25485
|
+
const value = node.source?.value;
|
|
25486
|
+
return typeof value === "string" && value.startsWith("node:") ? value : void 0;
|
|
25487
|
+
}
|
|
25488
|
+
if (node.type === "CallExpression") {
|
|
25489
|
+
const callee = node.callee;
|
|
25490
|
+
if (callee?.type === "Identifier" && callee.name === "require") {
|
|
25491
|
+
const arg = node.arguments?.[0];
|
|
25492
|
+
const value = arg?.type === "Literal" ? arg.value : void 0;
|
|
25493
|
+
return typeof value === "string" && value.startsWith("node:") ? value : void 0;
|
|
25494
|
+
}
|
|
25495
|
+
}
|
|
25496
|
+
return void 0;
|
|
25497
|
+
}
|
|
25498
|
+
function readProcessEnvKey(node) {
|
|
25499
|
+
if (node.type !== "MemberExpression") return void 0;
|
|
25500
|
+
const object = node.object;
|
|
25501
|
+
if (!object || object.type !== "MemberExpression" || object.object?.type !== "Identifier" || object.object.name !== "process" || object.property?.name !== "env") {
|
|
25502
|
+
return void 0;
|
|
25503
|
+
}
|
|
25504
|
+
const property = node.property;
|
|
25505
|
+
if (!property) return void 0;
|
|
25506
|
+
if (!node.computed && property.type === "Identifier") {
|
|
25507
|
+
return property.name;
|
|
25508
|
+
}
|
|
25509
|
+
if (node.computed && property.type === "Literal") {
|
|
25510
|
+
const value = property.value;
|
|
25511
|
+
return typeof value === "string" ? value : void 0;
|
|
25512
|
+
}
|
|
25513
|
+
return void 0;
|
|
25514
|
+
}
|
|
25515
|
+
function formatClientBoundaryWarning(id, findings) {
|
|
25516
|
+
const { envKeys, publicEnvKeys, builtinImports } = findings;
|
|
25517
|
+
const lines = [`${id} is compiled for the client but uses server-only APIs:`];
|
|
25518
|
+
if (envKeys.length > 0) {
|
|
25519
|
+
lines.push(
|
|
25520
|
+
`- module-scope read of process.env.${envKeys.join(", process.env.")} \u2014 undefined in the browser. Move the read behind a server boundary, or expose it through env.public in farm.config.ts.`
|
|
25521
|
+
);
|
|
25522
|
+
}
|
|
25523
|
+
if (publicEnvKeys.length > 0) {
|
|
25524
|
+
lines.push(
|
|
25525
|
+
`- module-scope read of process.env.${publicEnvKeys.join(", process.env.")} \u2014 process.env is not populated in the browser even for public keys. Read it through publicEnv from "@farm.js/core/env".`
|
|
25526
|
+
);
|
|
25527
|
+
}
|
|
25528
|
+
if (builtinImports.length > 0) {
|
|
25529
|
+
lines.push(
|
|
25530
|
+
`- import of ${builtinImports.join(", ")} \u2014 stubbed with an empty object in the browser. Move the import into server-only code.`
|
|
25531
|
+
);
|
|
25532
|
+
}
|
|
25533
|
+
return lines.join("\n");
|
|
25534
|
+
}
|
|
25535
|
+
var FUNCTION_BODY_TYPES;
|
|
25536
|
+
var init_client_boundary_env = __esm({
|
|
25537
|
+
"src/client-boundary-env.ts"() {
|
|
25538
|
+
"use strict";
|
|
25539
|
+
FUNCTION_BODY_TYPES = /* @__PURE__ */ new Set([
|
|
25540
|
+
"FunctionDeclaration",
|
|
25541
|
+
"FunctionExpression",
|
|
25542
|
+
"ArrowFunctionExpression"
|
|
25543
|
+
]);
|
|
25544
|
+
__name(shouldInspectClientBoundary, "shouldInspectClientBoundary");
|
|
25545
|
+
__name(analyzeClientBoundary, "analyzeClientBoundary");
|
|
25546
|
+
__name(readNodeBuiltinSource, "readNodeBuiltinSource");
|
|
25547
|
+
__name(readProcessEnvKey, "readProcessEnvKey");
|
|
25548
|
+
__name(formatClientBoundaryWarning, "formatClientBoundaryWarning");
|
|
25549
|
+
}
|
|
25550
|
+
});
|
|
25551
|
+
|
|
25112
25552
|
// src/image-vite.ts
|
|
25113
25553
|
function farmImageImportsPlugin() {
|
|
25114
25554
|
return {
|
|
@@ -25204,6 +25644,7 @@ var init_font = __esm({
|
|
|
25204
25644
|
function createFarmImageHandler(config, options) {
|
|
25205
25645
|
const fetcher = options.fetch ?? globalThis.fetch;
|
|
25206
25646
|
const cache = new FarmImageMemoryCache(options.cacheEntries ?? 100);
|
|
25647
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
25207
25648
|
const allowedWidths = /* @__PURE__ */ new Set([...config.deviceSizes, ...config.imageSizes]);
|
|
25208
25649
|
const allowedQualities = new Set(config.qualities);
|
|
25209
25650
|
return /* @__PURE__ */ __name(async function handleFarmImage(request) {
|
|
@@ -25232,50 +25673,55 @@ function createFarmImageHandler(config, options) {
|
|
|
25232
25673
|
"quality"
|
|
25233
25674
|
);
|
|
25234
25675
|
const accept = request.headers.get("accept") ?? "";
|
|
25676
|
+
const negotiatedFormat = selectOutputFormat(accept, config.formats) ?? "";
|
|
25235
25677
|
const cacheKey = `${sourceUrl.href}
|
|
25236
25678
|
${width}
|
|
25237
25679
|
${quality}
|
|
25238
|
-
${
|
|
25680
|
+
${negotiatedFormat}`;
|
|
25239
25681
|
let optimized = cache.get(cacheKey);
|
|
25240
25682
|
if (!optimized) {
|
|
25241
|
-
|
|
25242
|
-
|
|
25243
|
-
|
|
25244
|
-
|
|
25245
|
-
|
|
25246
|
-
|
|
25247
|
-
|
|
25248
|
-
|
|
25249
|
-
|
|
25250
|
-
|
|
25251
|
-
|
|
25252
|
-
|
|
25253
|
-
|
|
25254
|
-
|
|
25255
|
-
|
|
25256
|
-
|
|
25257
|
-
|
|
25258
|
-
|
|
25259
|
-
|
|
25260
|
-
|
|
25261
|
-
|
|
25262
|
-
|
|
25263
|
-
|
|
25264
|
-
|
|
25265
|
-
|
|
25683
|
+
optimized = await runCoalesced(inflight, cacheKey, request.signal, async (signal) => {
|
|
25684
|
+
const fetchedSource = await fetchImageSource(
|
|
25685
|
+
sourceUrl,
|
|
25686
|
+
requestUrl.origin,
|
|
25687
|
+
config,
|
|
25688
|
+
fetcher,
|
|
25689
|
+
options.fetchRemote,
|
|
25690
|
+
options.validateRemoteUrl,
|
|
25691
|
+
signal
|
|
25692
|
+
);
|
|
25693
|
+
const source = await readResponseWithLimit(
|
|
25694
|
+
fetchedSource.response,
|
|
25695
|
+
config.maximumResponseBody
|
|
25696
|
+
);
|
|
25697
|
+
const sourceType = detectImageContentType(source);
|
|
25698
|
+
validateSourceType(sourceType, config);
|
|
25699
|
+
throwIfAborted2(signal);
|
|
25700
|
+
const result = await options.transform({
|
|
25701
|
+
source,
|
|
25702
|
+
sourceUrl: fetchedSource.url,
|
|
25703
|
+
sourceType,
|
|
25704
|
+
width,
|
|
25705
|
+
quality,
|
|
25706
|
+
accept,
|
|
25707
|
+
formats: config.formats,
|
|
25708
|
+
signal,
|
|
25709
|
+
maximumResponseBody: config.maximumResponseBody
|
|
25710
|
+
});
|
|
25711
|
+
throwIfAborted2(signal);
|
|
25712
|
+
validateTransformedResult(result, config);
|
|
25713
|
+
const entry = {
|
|
25714
|
+
...result,
|
|
25715
|
+
etag: createImageEtag(result.body),
|
|
25716
|
+
cacheControl: `public, max-age=${config.minimumCacheTTL}, stale-while-revalidate=${Math.max(
|
|
25717
|
+
config.minimumCacheTTL,
|
|
25718
|
+
60
|
|
25719
|
+
)}`,
|
|
25720
|
+
expiresAt: Date.now() + config.minimumCacheTTL * 1e3
|
|
25721
|
+
};
|
|
25722
|
+
cache.set(cacheKey, entry);
|
|
25723
|
+
return entry;
|
|
25266
25724
|
});
|
|
25267
|
-
throwIfAborted2(request.signal);
|
|
25268
|
-
validateTransformedResult(result, config);
|
|
25269
|
-
optimized = {
|
|
25270
|
-
...result,
|
|
25271
|
-
etag: createImageEtag(result.body),
|
|
25272
|
-
cacheControl: `public, max-age=${config.minimumCacheTTL}, stale-while-revalidate=${Math.max(
|
|
25273
|
-
config.minimumCacheTTL,
|
|
25274
|
-
60
|
|
25275
|
-
)}`,
|
|
25276
|
-
expiresAt: Date.now() + config.minimumCacheTTL * 1e3
|
|
25277
|
-
};
|
|
25278
|
-
cache.set(cacheKey, optimized);
|
|
25279
25725
|
}
|
|
25280
25726
|
return createOptimizedImageResponse(request, optimized, config);
|
|
25281
25727
|
} catch (error) {
|
|
@@ -25426,6 +25872,44 @@ async function fetchImageSource(initialUrl, requestOrigin, config, fetcher, fetc
|
|
|
25426
25872
|
await validateImageSourceUrl(currentUrl, requestOrigin, config, validateRemoteUrl);
|
|
25427
25873
|
}
|
|
25428
25874
|
}
|
|
25875
|
+
async function runCoalesced(inflight, key, requestSignal, run) {
|
|
25876
|
+
let entry = inflight.get(key);
|
|
25877
|
+
if (!entry) {
|
|
25878
|
+
const controller = new AbortController();
|
|
25879
|
+
const created = {
|
|
25880
|
+
controller,
|
|
25881
|
+
waiters: 0,
|
|
25882
|
+
promise: void 0
|
|
25883
|
+
};
|
|
25884
|
+
created.promise = run(controller.signal).finally(() => {
|
|
25885
|
+
if (inflight.get(key) === created) inflight.delete(key);
|
|
25886
|
+
});
|
|
25887
|
+
created.promise.catch(() => {
|
|
25888
|
+
});
|
|
25889
|
+
inflight.set(key, created);
|
|
25890
|
+
entry = created;
|
|
25891
|
+
}
|
|
25892
|
+
const pending = entry;
|
|
25893
|
+
pending.waiters += 1;
|
|
25894
|
+
try {
|
|
25895
|
+
return await raceRequestAbort(pending.promise, requestSignal);
|
|
25896
|
+
} finally {
|
|
25897
|
+
pending.waiters -= 1;
|
|
25898
|
+
if (pending.waiters === 0 && inflight.get(key) === pending) {
|
|
25899
|
+
inflight.delete(key);
|
|
25900
|
+
pending.controller.abort();
|
|
25901
|
+
}
|
|
25902
|
+
}
|
|
25903
|
+
}
|
|
25904
|
+
function raceRequestAbort(promise, signal) {
|
|
25905
|
+
if (!signal) return promise;
|
|
25906
|
+
if (signal.aborted) return Promise.reject(signal.reason ?? new Error("Aborted"));
|
|
25907
|
+
return new Promise((resolve10, reject) => {
|
|
25908
|
+
const onAbort = /* @__PURE__ */ __name(() => reject(signal.reason ?? new Error("Aborted")), "onAbort");
|
|
25909
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
25910
|
+
promise.then(resolve10, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
25911
|
+
});
|
|
25912
|
+
}
|
|
25429
25913
|
async function readResponseWithLimit(response, limit) {
|
|
25430
25914
|
const contentLength = response.headers.get("content-length");
|
|
25431
25915
|
if (contentLength && Number(contentLength) > limit) {
|
|
@@ -25593,7 +26077,7 @@ function throwIfAborted2(signal) {
|
|
|
25593
26077
|
function isAbortError(error) {
|
|
25594
26078
|
return error instanceof Error && error.name === "AbortError";
|
|
25595
26079
|
}
|
|
25596
|
-
var _FarmImageRequestError, FarmImageRequestError, _FarmImageMemoryCache, FarmImageMemoryCache;
|
|
26080
|
+
var _FarmImageRequestError, FarmImageRequestError, DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT, _FarmImageMemoryCache, FarmImageMemoryCache;
|
|
25597
26081
|
var init_image_server = __esm({
|
|
25598
26082
|
"src/image-server.ts"() {
|
|
25599
26083
|
"use strict";
|
|
@@ -25609,12 +26093,15 @@ var init_image_server = __esm({
|
|
|
25609
26093
|
__name(_FarmImageRequestError, "FarmImageRequestError");
|
|
25610
26094
|
FarmImageRequestError = _FarmImageRequestError;
|
|
25611
26095
|
__name(createFarmImageHandler, "createFarmImageHandler");
|
|
26096
|
+
DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT = 10 * 1024 * 1024;
|
|
25612
26097
|
__name(selectOutputFormat, "selectOutputFormat");
|
|
25613
26098
|
__name(isPrivateImageAddress, "isPrivateImageAddress");
|
|
25614
26099
|
__name(parseAllowedInteger, "parseAllowedInteger");
|
|
25615
26100
|
__name(resolveImageSourceUrl, "resolveImageSourceUrl");
|
|
25616
26101
|
__name(validateImageSourceUrl, "validateImageSourceUrl");
|
|
25617
26102
|
__name(fetchImageSource, "fetchImageSource");
|
|
26103
|
+
__name(runCoalesced, "runCoalesced");
|
|
26104
|
+
__name(raceRequestAbort, "raceRequestAbort");
|
|
25618
26105
|
__name(readResponseWithLimit, "readResponseWithLimit");
|
|
25619
26106
|
__name(cancelResponseBody, "cancelResponseBody");
|
|
25620
26107
|
__name(detectImageContentType, "detectImageContentType");
|
|
@@ -31478,6 +31965,22 @@ function isFarmConfigFile(file, root) {
|
|
|
31478
31965
|
const relative6 = normalized.startsWith(`${rootSlug}/`) ? normalized.slice(rootSlug.length + 1) : normalized;
|
|
31479
31966
|
return FARM_CONFIG_FILENAMES.has(relative6);
|
|
31480
31967
|
}
|
|
31968
|
+
function warnClientBoundaryOnce(context2, id, code, config) {
|
|
31969
|
+
if (warnedClientBoundaryIds.has(id)) return;
|
|
31970
|
+
let program;
|
|
31971
|
+
try {
|
|
31972
|
+
program = context2.parse(code);
|
|
31973
|
+
} catch {
|
|
31974
|
+
return;
|
|
31975
|
+
}
|
|
31976
|
+
const publicKeys = new Set(Object.keys(config.env?.public ?? {}));
|
|
31977
|
+
const findings = analyzeClientBoundary(program, publicKeys);
|
|
31978
|
+
if (findings.envKeys.length === 0 && findings.publicEnvKeys.length === 0 && findings.builtinImports.length === 0) {
|
|
31979
|
+
return;
|
|
31980
|
+
}
|
|
31981
|
+
warnedClientBoundaryIds.add(id);
|
|
31982
|
+
logger.warn(formatClientBoundaryWarning(id, findings));
|
|
31983
|
+
}
|
|
31481
31984
|
function farmPlugin(options = {}, initialPluginManager) {
|
|
31482
31985
|
const imageImports = farmImageImportsPlugin();
|
|
31483
31986
|
const fontImports = farmFontImportsPlugin({
|
|
@@ -32088,6 +32591,22 @@ window.__FARM_MANIFEST__ = ${inlineValue({
|
|
|
32088
32591
|
}
|
|
32089
32592
|
return;
|
|
32090
32593
|
}
|
|
32594
|
+
if (openAPIManager && options.openapi?.specRoute && requestPathname === options.openapi.specRoute) {
|
|
32595
|
+
if (requestMethod !== "GET" && requestMethod !== "HEAD") {
|
|
32596
|
+
res.statusCode = 405;
|
|
32597
|
+
res.setHeader("Allow", "GET, HEAD");
|
|
32598
|
+
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
32599
|
+
res.end("Method Not Allowed");
|
|
32600
|
+
return;
|
|
32601
|
+
}
|
|
32602
|
+
const spec = await openAPIManager.getSpec();
|
|
32603
|
+
const body = JSON.stringify(spec);
|
|
32604
|
+
res.statusCode = 200;
|
|
32605
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
32606
|
+
res.setHeader("Cache-Control", "no-store");
|
|
32607
|
+
res.end(requestMethod === "HEAD" ? void 0 : body);
|
|
32608
|
+
return;
|
|
32609
|
+
}
|
|
32091
32610
|
if (openAPIManager && requestPathname === options.openapi?.route) {
|
|
32092
32611
|
const docsHandler = openAPIManager.getDocsRouteHandler();
|
|
32093
32612
|
return docsHandler(req, res);
|
|
@@ -32098,6 +32617,11 @@ window.__FARM_MANIFEST__ = ${inlineValue({
|
|
|
32098
32617
|
docsHeaders.set(key, Array.isArray(value) ? value.join(", ") : value);
|
|
32099
32618
|
}
|
|
32100
32619
|
}
|
|
32620
|
+
const runAppMiddlewareForContentRoute = /* @__PURE__ */ __name(async () => {
|
|
32621
|
+
if (!middlewareManager?.hasMiddleware()) return false;
|
|
32622
|
+
const middlewareRequest = createRequestFromNodeRequest(req, new URL(fullUrl));
|
|
32623
|
+
return farmApp.getServerRenderer().runWithRequestContext(middlewareRequest, () => middlewareManager.execute(req, res));
|
|
32624
|
+
}, "runAppMiddlewareForContentRoute");
|
|
32101
32625
|
if (farmDocsHandler) {
|
|
32102
32626
|
const docsRequest = new Request(fullUrl, {
|
|
32103
32627
|
method: requestMethod,
|
|
@@ -32105,6 +32629,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
|
|
|
32105
32629
|
});
|
|
32106
32630
|
const docsResponse = await farmDocsHandler(docsRequest.clone());
|
|
32107
32631
|
if (docsResponse) {
|
|
32632
|
+
if (await runAppMiddlewareForContentRoute()) return;
|
|
32108
32633
|
await sendWebResponse(
|
|
32109
32634
|
res,
|
|
32110
32635
|
await wrapFarmDocsResponseWithLayouts(docsRequest, docsResponse)
|
|
@@ -32131,6 +32656,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
|
|
|
32131
32656
|
}, "resolveSource")
|
|
32132
32657
|
});
|
|
32133
32658
|
if (markdownSourceResponse) {
|
|
32659
|
+
if (await runAppMiddlewareForContentRoute()) return;
|
|
32134
32660
|
await sendWebResponse(res, markdownSourceResponse);
|
|
32135
32661
|
return;
|
|
32136
32662
|
}
|
|
@@ -32144,9 +32670,23 @@ window.__FARM_MANIFEST__ = ${inlineValue({
|
|
|
32144
32670
|
renderPage: /* @__PURE__ */ __name(async (request) => fetch(request), "renderPage")
|
|
32145
32671
|
});
|
|
32146
32672
|
if (markdownResponse) {
|
|
32673
|
+
if (await runAppMiddlewareForContentRoute()) return;
|
|
32147
32674
|
await sendWebResponse(res, markdownResponse);
|
|
32148
32675
|
return;
|
|
32149
32676
|
}
|
|
32677
|
+
if (farmRequestWantsMarkdown(requestPathname, req.headers.accept)) {
|
|
32678
|
+
const markdownRoute = farmApp.getRouteManager().matchRoute(normalizeFarmMarkdownRoutePath(requestPathname));
|
|
32679
|
+
if (!markdownRoute.route) {
|
|
32680
|
+
res.statusCode = 404;
|
|
32681
|
+
res.setHeader("Content-Type", FARM_MARKDOWN_CONTENT_TYPE);
|
|
32682
|
+
res.setHeader("X-Farm-Markdown-Error", "404");
|
|
32683
|
+
res.setHeader("Cache-Control", "no-store");
|
|
32684
|
+
res.end(
|
|
32685
|
+
createFarmMarkdownErrorBody(404, requestPathname, farmConfig.basePath || "/")
|
|
32686
|
+
);
|
|
32687
|
+
return;
|
|
32688
|
+
}
|
|
32689
|
+
}
|
|
32150
32690
|
const markdownPageTarget = resolveMarkdownMirrorTarget(
|
|
32151
32691
|
farmApp.getConfig().md,
|
|
32152
32692
|
requestPathname,
|
|
@@ -33095,6 +33635,9 @@ export const manifest = getManifest();
|
|
|
33095
33635
|
}
|
|
33096
33636
|
}
|
|
33097
33637
|
}
|
|
33638
|
+
if (!transformOptions?.ssr && shouldInspectClientBoundary(id, code)) {
|
|
33639
|
+
warnClientBoundaryOnce(this, id, code, farmApp?.getConfig() ?? options);
|
|
33640
|
+
}
|
|
33098
33641
|
if (typeof imageImports.transform === "function") {
|
|
33099
33642
|
const imageModule = await imageImports.transform.call(this, code, id, transformOptions);
|
|
33100
33643
|
if (imageModule) return imageModule;
|
|
@@ -35434,7 +35977,7 @@ async function defineConfig2(config = {}) {
|
|
|
35434
35977
|
}
|
|
35435
35978
|
};
|
|
35436
35979
|
}
|
|
35437
|
-
var fs14, path38, import_node_url9, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, warnedDeprecatedDevtoolsDashboard, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES;
|
|
35980
|
+
var fs14, path38, import_node_url9, ALL_TYPE_ARTIFACTS, createEmptyTypeArtifactSelection, FARM_I18N_CLIENT_BRIDGE_ID, warnedDeprecatedDevtoolsDashboard, EMPTY_FARM_DOCS_SEARCH_CLIENT_RUNTIME, FARM_CONFIG_FILENAMES, warnedClientBoundaryIds;
|
|
35438
35981
|
var init_vite2 = __esm({
|
|
35439
35982
|
"src/vite.ts"() {
|
|
35440
35983
|
"use strict";
|
|
@@ -35471,6 +36014,7 @@ var init_vite2 = __esm({
|
|
|
35471
36014
|
init_server_context();
|
|
35472
36015
|
init_dev_static();
|
|
35473
36016
|
init_server_query_boundary();
|
|
36017
|
+
init_client_boundary_env();
|
|
35474
36018
|
init_deployment();
|
|
35475
36019
|
init_image_config();
|
|
35476
36020
|
init_image_vite();
|
|
@@ -35570,6 +36114,8 @@ async function mountFarmDocsSearch() {
|
|
|
35570
36114
|
__name(walkModuleAst, "walkModuleAst");
|
|
35571
36115
|
__name(isFarmModuleAstNode, "isFarmModuleAstNode");
|
|
35572
36116
|
__name(isFarmConfigFile, "isFarmConfigFile");
|
|
36117
|
+
warnedClientBoundaryIds = /* @__PURE__ */ new Set();
|
|
36118
|
+
__name(warnClientBoundaryOnce, "warnClientBoundaryOnce");
|
|
35573
36119
|
__name(farmPlugin, "farmPlugin");
|
|
35574
36120
|
__name(isFarmClientVirtualId, "isFarmClientVirtualId");
|
|
35575
36121
|
__name(generateProgrammaticRouteModule, "generateProgrammaticRouteModule");
|
|
@@ -40048,7 +40594,9 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
|
|
|
40048
40594
|
}
|
|
40049
40595
|
openAPIReference = {
|
|
40050
40596
|
route: config.openapi.route,
|
|
40051
|
-
html: renderOpenAPIReferenceHTML2(spec, config.openapi)
|
|
40597
|
+
html: renderOpenAPIReferenceHTML2(spec, config.openapi),
|
|
40598
|
+
spec,
|
|
40599
|
+
specRoute: config.openapi.specRoute || null
|
|
40052
40600
|
};
|
|
40053
40601
|
}
|
|
40054
40602
|
const middlewareRoutes = await discoverMiddlewareRoutes(appDirs);
|
|
@@ -40670,6 +41218,7 @@ import { dirname as farmDocsDirname, join as farmDocsJoin } from "node:path";
|
|
|
40670
41218
|
import { fileURLToPath as farmDocsFileURLToPath } from "node:url";` : "";
|
|
40671
41219
|
const markdownHandlerImport = config.md?.enabled ? `import { applyMarkdownNegotiationHeaders, createMarkdownMirrorResponse } from "@farm.js/core/markdown";` : "";
|
|
40672
41220
|
const appMarkdownImport = hasMarkdownPages ? `import { createFarmMarkdownRouteModule, createFarmMarkdownSourceResponse } from "@farm.js/core/app-markdown";` : "const createFarmMarkdownSourceResponse = null;";
|
|
41221
|
+
const markdownErrorImport = `import { FARM_MARKDOWN_CONTENT_TYPE, createFarmMarkdownErrorBody, farmRequestWantsMarkdown } from "@farm.js/core/app-markdown";`;
|
|
40673
41222
|
const mdxComponentsPath = typeof config.mdx?.components === "string" ? import_path14.default.isAbsolute(config.mdx.components) ? config.mdx.components : import_path14.default.join(config.root, config.mdx.components) : null;
|
|
40674
41223
|
const mdxComponentsImport = mdxComponentsPath ? `import * as FarmMdxComponentsModule from ${toVirtualEntryImportSpecifier(mdxComponentsPath)};` : "";
|
|
40675
41224
|
const layerConfigPaths = (config.layers || []).map((layer) => layer.configFile).filter((configFile) => Boolean(configFile)).filter((configFile) => configFile !== configModulePath);
|
|
@@ -40812,6 +41361,7 @@ ${docsFontImport}
|
|
|
40812
41361
|
${docsRuntimeImport}
|
|
40813
41362
|
${markdownHandlerImport}
|
|
40814
41363
|
${appMarkdownImport}
|
|
41364
|
+
${markdownErrorImport}
|
|
40815
41365
|
${mdxComponentsImport}
|
|
40816
41366
|
${integrationImports}
|
|
40817
41367
|
${providerServerImports}
|
|
@@ -42355,12 +42905,38 @@ async function handleFarmRequestInContext(
|
|
|
42355
42905
|
}
|
|
42356
42906
|
` : ""}
|
|
42357
42907
|
|
|
42908
|
+
${hasMiddlewareRuntime ? `
|
|
42909
|
+
const requestBeforeMiddleware = request;
|
|
42910
|
+
const middlewareResult = await farmMiddlewareRunner(request);
|
|
42911
|
+
if (middlewareResult.response) {
|
|
42912
|
+
return middlewareResult.response;
|
|
42913
|
+
}
|
|
42914
|
+
request = middlewareResult.request;
|
|
42915
|
+
const middlewareData = middlewareResult.data;
|
|
42916
|
+
const middlewareContext = middlewareResult.context;
|
|
42917
|
+
const middlewareHeaders = middlewareResult.headers;
|
|
42918
|
+
url = new URL(request.url);
|
|
42919
|
+
pathname = url.pathname;
|
|
42920
|
+
routePathname = getFarmRoutePathname(pathname);
|
|
42921
|
+
|
|
42922
|
+
// Middleware may replace the Request when it rewrites a URL. Re-enter the
|
|
42923
|
+
// request store so pages, layouts, and route context observe that rewritten
|
|
42924
|
+
// request instead of the original outer-handler value.
|
|
42925
|
+
const runResolvedRequest = async () => {
|
|
42926
|
+
` : `
|
|
42927
|
+
const middlewareData = undefined;
|
|
42928
|
+
const middlewareContext = undefined;
|
|
42929
|
+
const middlewareHeaders = undefined;
|
|
42930
|
+
`}
|
|
42931
|
+
|
|
42358
42932
|
${config.docs?.enabled ? `
|
|
42933
|
+
// Docs responses are served after app middleware so route guards and
|
|
42934
|
+
// middleware headers apply to the docs engine like any other page content.
|
|
42359
42935
|
if (farmDocsHandler) {
|
|
42360
42936
|
const docsResponse = await farmDocsHandler(request.clone());
|
|
42361
42937
|
if (docsResponse) {
|
|
42362
42938
|
if (!docsResponse.headers.get("content-type")?.toLowerCase().includes("text/html")) {
|
|
42363
|
-
return docsResponse;
|
|
42939
|
+
return applyProductionMiddlewareHeaders(docsResponse, middlewareHeaders);
|
|
42364
42940
|
}
|
|
42365
42941
|
const wrappedDocsResponse = await wrapFarmDocsResponseWithLayouts(
|
|
42366
42942
|
request,
|
|
@@ -42368,16 +42944,18 @@ async function handleFarmRequestInContext(
|
|
|
42368
42944
|
);
|
|
42369
42945
|
const docsHeaders = new Headers(wrappedDocsResponse.headers);
|
|
42370
42946
|
docsHeaders.set("x-farm-preload-buffered", "1");
|
|
42371
|
-
return new Response(wrappedDocsResponse.body, {
|
|
42947
|
+
return applyProductionMiddlewareHeaders(new Response(wrappedDocsResponse.body, {
|
|
42372
42948
|
status: wrappedDocsResponse.status,
|
|
42373
42949
|
statusText: wrappedDocsResponse.statusText,
|
|
42374
42950
|
headers: docsHeaders,
|
|
42375
|
-
});
|
|
42951
|
+
}), middlewareHeaders);
|
|
42376
42952
|
}
|
|
42377
42953
|
}
|
|
42378
42954
|
` : ""}
|
|
42379
42955
|
|
|
42380
42956
|
${hasMarkdownPages ? `
|
|
42957
|
+
// The raw markdown source of a page route is the page's content in another
|
|
42958
|
+
// representation; middleware guarding the route must run before serving it.
|
|
42381
42959
|
const markdownSourceResponse = await createFarmMarkdownSourceResponse?.({
|
|
42382
42960
|
request: request.clone(),
|
|
42383
42961
|
config: farmMdxConfig,
|
|
@@ -42387,7 +42965,7 @@ async function handleFarmRequestInContext(
|
|
|
42387
42965
|
},
|
|
42388
42966
|
});
|
|
42389
42967
|
if (markdownSourceResponse) {
|
|
42390
|
-
return markdownSourceResponse;
|
|
42968
|
+
return applyProductionMiddlewareHeaders(markdownSourceResponse, middlewareHeaders);
|
|
42391
42969
|
}
|
|
42392
42970
|
` : ""}
|
|
42393
42971
|
|
|
@@ -42401,35 +42979,11 @@ async function handleFarmRequestInContext(
|
|
|
42401
42979
|
renderPage: (targetRequest) => handleFarmRequest(targetRequest),
|
|
42402
42980
|
});
|
|
42403
42981
|
if (markdownResponse) {
|
|
42404
|
-
return markdownResponse;
|
|
42982
|
+
return applyProductionMiddlewareHeaders(markdownResponse, middlewareHeaders);
|
|
42405
42983
|
}
|
|
42406
42984
|
}
|
|
42407
42985
|
` : ""}
|
|
42408
42986
|
|
|
42409
|
-
${hasMiddlewareRuntime ? `
|
|
42410
|
-
const requestBeforeMiddleware = request;
|
|
42411
|
-
const middlewareResult = await farmMiddlewareRunner(request);
|
|
42412
|
-
if (middlewareResult.response) {
|
|
42413
|
-
return middlewareResult.response;
|
|
42414
|
-
}
|
|
42415
|
-
request = middlewareResult.request;
|
|
42416
|
-
const middlewareData = middlewareResult.data;
|
|
42417
|
-
const middlewareContext = middlewareResult.context;
|
|
42418
|
-
const middlewareHeaders = middlewareResult.headers;
|
|
42419
|
-
url = new URL(request.url);
|
|
42420
|
-
pathname = url.pathname;
|
|
42421
|
-
routePathname = getFarmRoutePathname(pathname);
|
|
42422
|
-
|
|
42423
|
-
// Middleware may replace the Request when it rewrites a URL. Re-enter the
|
|
42424
|
-
// request store so pages, layouts, and route context observe that rewritten
|
|
42425
|
-
// request instead of the original outer-handler value.
|
|
42426
|
-
const runResolvedRequest = async () => {
|
|
42427
|
-
` : `
|
|
42428
|
-
const middlewareData = undefined;
|
|
42429
|
-
const middlewareContext = undefined;
|
|
42430
|
-
const middlewareHeaders = undefined;
|
|
42431
|
-
`}
|
|
42432
|
-
|
|
42433
42987
|
${apiRoutes.length > 0 ? `
|
|
42434
42988
|
const apiResponse = await handleAPIRequest(request.clone());
|
|
42435
42989
|
if (apiResponse) {
|
|
@@ -42437,6 +42991,31 @@ async function handleFarmRequestInContext(
|
|
|
42437
42991
|
}
|
|
42438
42992
|
` : ""}
|
|
42439
42993
|
|
|
42994
|
+
if (
|
|
42995
|
+
farmOpenAPIReference &&
|
|
42996
|
+
farmOpenAPIReference.specRoute &&
|
|
42997
|
+
normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.specRoute)
|
|
42998
|
+
) {
|
|
42999
|
+
const method = request.method.toUpperCase();
|
|
43000
|
+
const specResponse = method === "GET" || method === "HEAD"
|
|
43001
|
+
? new Response(method === "HEAD" ? null : JSON.stringify(farmOpenAPIReference.spec), {
|
|
43002
|
+
status: 200,
|
|
43003
|
+
headers: {
|
|
43004
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
43005
|
+
"Cache-Control": "public, max-age=0, must-revalidate",
|
|
43006
|
+
"X-Content-Type-Options": "nosniff",
|
|
43007
|
+
},
|
|
43008
|
+
})
|
|
43009
|
+
: new Response("Method Not Allowed", {
|
|
43010
|
+
status: 405,
|
|
43011
|
+
headers: {
|
|
43012
|
+
"Allow": "GET, HEAD",
|
|
43013
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
43014
|
+
},
|
|
43015
|
+
});
|
|
43016
|
+
return applyProductionMiddlewareHeaders(specResponse, middlewareHeaders);
|
|
43017
|
+
}
|
|
43018
|
+
|
|
42440
43019
|
if (
|
|
42441
43020
|
farmOpenAPIReference &&
|
|
42442
43021
|
normalizeRuntimePath(pathname) === normalizeRuntimePath(farmOpenAPIReference.route)
|
|
@@ -42909,7 +43488,7 @@ async function handleFarmRequestInContext(
|
|
|
42909
43488
|
}
|
|
42910
43489
|
}
|
|
42911
43490
|
|
|
42912
|
-
const renderedMetadata = renderMetadataHead(mergedMetadata);
|
|
43491
|
+
const renderedMetadata = renderMetadataHead(mergedMetadata, { pathname, jsonLd: ${JSON.stringify(config.agent?.jsonLd ?? false)} });
|
|
42913
43492
|
const title = renderedMetadata.title;
|
|
42914
43493
|
const metaTags = renderedMetadata.tags;
|
|
42915
43494
|
const hasFavicon = renderedMetadata.hasFavicon;
|
|
@@ -43285,6 +43864,30 @@ async function handleFarmRequestInContext(
|
|
|
43285
43864
|
|
|
43286
43865
|
// 404 fallback - render proper HTML page
|
|
43287
43866
|
emitFarmEvent({ type: "route.notFound", pathname });
|
|
43867
|
+
|
|
43868
|
+
// Agents that navigate in Markdown (a \`.md\` URL or \`Accept: text/markdown\`)
|
|
43869
|
+
// get a Markdown error body instead of the HTML not-found shell.
|
|
43870
|
+
if (farmRequestWantsMarkdown(pathname, request.headers.get("accept"))) {
|
|
43871
|
+
emitFarmEvent({
|
|
43872
|
+
type: "render.complete",
|
|
43873
|
+
route: pathname,
|
|
43874
|
+
pathname,
|
|
43875
|
+
status: 404,
|
|
43876
|
+
durationMs: Date.now() - requestStartTime,
|
|
43877
|
+
});
|
|
43878
|
+
return applyProductionMiddlewareHeaders(new Response(
|
|
43879
|
+
createFarmMarkdownErrorBody(404, pathname, applyFarmBasePath("/", farmResolvedRuntimeConfig.basePath)),
|
|
43880
|
+
{
|
|
43881
|
+
status: 404,
|
|
43882
|
+
headers: {
|
|
43883
|
+
"Content-Type": FARM_MARKDOWN_CONTENT_TYPE,
|
|
43884
|
+
"X-Farm-Markdown-Error": "404",
|
|
43885
|
+
"Cache-Control": "no-store",
|
|
43886
|
+
},
|
|
43887
|
+
}
|
|
43888
|
+
), middlewareHeaders);
|
|
43889
|
+
}
|
|
43890
|
+
|
|
43288
43891
|
try {
|
|
43289
43892
|
const defaultNotFoundHomeHref = applyFarmBasePath("/", farmResolvedRuntimeConfig.basePath);
|
|
43290
43893
|
// Default 404 page component
|
|
@@ -43524,6 +44127,9 @@ async function handleFarmFetch(request, context) {
|
|
|
43524
44127
|
const healthResponse = await farmProductionLifecycle.handleHealthRequest(request);
|
|
43525
44128
|
if (healthResponse) return healthResponse;
|
|
43526
44129
|
|
|
44130
|
+
const productionSiteAttestation = farmProductionSiteTelemetry?.handleAttestation(request);
|
|
44131
|
+
if (productionSiteAttestation) return productionSiteAttestation;
|
|
44132
|
+
|
|
43527
44133
|
farmProductionSiteTelemetry?.report(
|
|
43528
44134
|
request.url,
|
|
43529
44135
|
typeof context?.waitUntil === "function" ? context.waitUntil.bind(context) : undefined,
|