@farm.js/core 0.1.51-beta.0 → 0.1.51-beta.2
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-BBMfNpsC.d.ts → agent-mcp.d-CR5Ov83o.d.ts} +1 -1
- package/dist/{agent-mcp-D44ip11f.d.mts → agent-mcp.d-Z5DuwrqW.d.mts} +1 -1
- package/dist/agent-runtime.cjs +3 -3
- package/dist/agent-runtime.d.mts +13 -13
- package/dist/agent-runtime.d.ts +13 -13
- package/dist/agent-runtime.mjs +2 -2
- package/dist/{analyzer-VKUDHNDF.cjs → analyzer-T76CN3S7.cjs} +70 -21
- package/dist/{analyzer-HOUCQR3K.mjs → analyzer-Z6TNEAET.mjs} +70 -21
- package/dist/api/client.d.mts +4 -4
- package/dist/api/client.d.ts +4 -4
- package/dist/api/route-manager.d.mts +19 -19
- package/dist/api/route-manager.d.ts +19 -19
- package/dist/api/runtime.d.mts +15 -15
- package/dist/api/runtime.d.ts +15 -15
- package/dist/{api-client-CvI5oOBE.d.ts → api-client.d-BWcqZciH.d.ts} +3 -3
- package/dist/{api-client-CFdv-Xgh.d.mts → api-client.d-CeA6tNA6.d.mts} +3 -3
- package/dist/api.cjs +3 -3
- package/dist/api.d.mts +21 -21
- package/dist/api.d.ts +21 -21
- package/dist/api.mjs +2 -2
- package/dist/{app-manifest-LzjoNPeq.d.ts → app-manifest.d-CAHkOBFa.d.mts} +1 -1
- package/dist/{app-manifest-BC6mFn5A.d.mts → app-manifest.d-DiWr_Jfx.d.ts} +1 -1
- package/dist/app-markdown.d.mts +14 -14
- package/dist/app-markdown.d.ts +14 -14
- package/dist/{app-aeD4s_mg.d.mts → app.d-BfgJCsTQ.d.mts} +12 -10
- package/dist/{app-CourU3rQ.d.ts → app.d-DmapqkbV.d.ts} +12 -10
- package/dist/{chunk-AMRK3P6W.mjs → chunk-4SSRBCBR.mjs} +233 -84
- package/dist/{chunk-PDJSL7PL.cjs → chunk-5IONBVJY.cjs} +3 -3
- package/dist/{chunk-IOUOGRDX.cjs → chunk-5N7QAGEA.cjs} +25 -6
- package/dist/{chunk-DGOLAZLV.cjs → chunk-65Y5SIBH.cjs} +1 -1
- package/dist/{chunk-ZF3GX4O7.mjs → chunk-6CYQQQGR.mjs} +1 -1
- package/dist/{chunk-QI5AQMEE.mjs → chunk-72NBDVWQ.mjs} +1 -1
- package/dist/{chunk-I2ZA5SXS.mjs → chunk-74Z5KX4A.mjs} +53 -19
- package/dist/chunk-7FVVQEVL.cjs +541 -0
- package/dist/{chunk-OD6WM3I7.mjs → chunk-AV26KHTG.mjs} +1 -1
- package/dist/chunk-C3BOESDW.mjs +541 -0
- package/dist/{chunk-WAPQWAE6.cjs → chunk-CECUDGXQ.cjs} +9 -8
- package/dist/{chunk-IUQLRTTO.mjs → chunk-CO6UYM2D.mjs} +14 -1
- package/dist/{chunk-JF5CNHHF.mjs → chunk-CTM4SPB3.mjs} +123 -8
- package/dist/{chunk-WVX3BUNJ.mjs → chunk-CZ35L6PL.mjs} +8 -1
- package/dist/{chunk-SO3T6T4I.cjs → chunk-DTU4PX7V.cjs} +408 -259
- package/dist/{chunk-YLNBWUVS.mjs → chunk-E6LTONL4.mjs} +1 -1
- package/dist/{chunk-R5P4KFPM.mjs → chunk-E73PGHSR.mjs} +8 -6
- package/dist/{chunk-4GJJ65RB.mjs → chunk-EIMK7D2D.mjs} +24 -5
- package/dist/{chunk-CY7H5KS4.cjs → chunk-EKJYE4Y7.cjs} +2 -2
- package/dist/{chunk-3HA7PP72.mjs → chunk-FM2UEKS2.mjs} +60 -13
- package/dist/{chunk-VIFPE5RG.cjs → chunk-GNJIYJMS.cjs} +81 -34
- package/dist/{chunk-X5BCMLGP.cjs → chunk-GUJTVM36.cjs} +1 -1
- package/dist/{chunk-XWC5NAHV.mjs → chunk-IBSAYAWB.mjs} +2 -2
- package/dist/{chunk-J22JD5YJ.cjs → chunk-J3LBO2O4.cjs} +9 -7
- package/dist/{chunk-J37KTQIA.cjs → chunk-NK2VWS7P.cjs} +52 -3
- package/dist/{chunk-WSY2JD7O.mjs → chunk-NN3MOPSI.mjs} +1 -1
- package/dist/{chunk-O3MMJPC2.cjs → chunk-NPQLMP7M.cjs} +124 -9
- package/dist/{chunk-QK3HBOTG.cjs → chunk-NXBHYO7S.cjs} +5 -5
- package/dist/{chunk-S5ZA2T2W.mjs → chunk-PMKUU273.mjs} +21 -7
- package/dist/{chunk-75WWOZ5C.mjs → chunk-QOSDWGKT.mjs} +1 -1
- package/dist/{chunk-VO6NLTV4.cjs → chunk-QXPSWMUD.cjs} +3 -3
- package/dist/{chunk-Y7TLL65B.cjs → chunk-UQHIWZZ6.cjs} +11 -4
- package/dist/{chunk-PPDHCRTC.mjs → chunk-VS7EHLLW.mjs} +1 -1
- package/dist/{chunk-F42U3R4F.cjs → chunk-WZW6LEHM.cjs} +55 -41
- package/dist/{chunk-USL2ANCB.cjs → chunk-X2AMN2WV.cjs} +2 -2
- package/dist/{chunk-HHFMECFO.mjs → chunk-Y2G5SJFB.mjs} +2 -1
- package/dist/{chunk-Z5MZDFX4.cjs → chunk-YIHRZBD7.cjs} +14 -1
- package/dist/{chunk-DWW3AMJX.cjs → chunk-YU42A5MA.cjs} +282 -248
- package/dist/{chunk-MMEEXMUQ.cjs → chunk-ZOWNWHK6.cjs} +2 -2
- package/dist/{chunk-C5JXCUKR.mjs → chunk-ZQ5BDNKW.mjs} +51 -2
- package/dist/client/lifecycle.d.mts +1 -1
- package/dist/client/lifecycle.d.ts +1 -1
- package/dist/{client-plugins-cqy_dQd0.d.mts → client-plugins.d-Bx3FXpqm.d.mts} +57 -15
- package/dist/{client-plugins-CFBEfVPO.d.ts → client-plugins.d-TiLbS5j4.d.ts} +57 -15
- package/dist/client-plugins.d.mts +13 -13
- package/dist/client-plugins.d.ts +13 -13
- package/dist/client.d.mts +24 -24
- package/dist/client.d.ts +24 -24
- package/dist/{config-CnhyvvmT.d.mts → config.d-iRPI16ku.d.mts} +6 -2
- package/dist/{config-CnhyvvmT.d.ts → config.d-iRPI16ku.d.ts} +6 -2
- package/dist/config.d.mts +13 -13
- package/dist/config.d.ts +13 -13
- package/dist/desktop.d.mts +14 -14
- package/dist/desktop.d.ts +14 -14
- package/dist/{dev-guard-YLO5DE3H.cjs → dev-guard-2UW2KERP.cjs} +2 -2
- package/dist/{dev-guard-4PFQNXQX.mjs → dev-guard-ONNMVQUN.mjs} +1 -1
- package/dist/{devtools-4ZLMD454.cjs → devtools-6XWCZIGO.cjs} +4 -4
- package/dist/{devtools-4MLL3RAL.mjs → devtools-UQLDAOEI.mjs} +3 -3
- package/dist/docs.cjs +8 -6
- package/dist/docs.d.mts +23 -15
- package/dist/docs.d.ts +23 -15
- package/dist/docs.mjs +7 -5
- package/dist/environment/vite.cjs +2 -2
- package/dist/environment/vite.d.mts +1 -1
- package/dist/environment/vite.d.ts +1 -1
- package/dist/environment/vite.mjs +1 -1
- package/dist/{generate-route-types-TF5Wwtvz.d.mts → generate-route-types.d-BL2pq6xC.d.ts} +1 -1
- package/dist/{generate-route-types-DQP0cUzk.d.ts → generate-route-types.d-BoVDU8qX.d.mts} +1 -1
- package/dist/i18n/client.d.mts +2 -2
- package/dist/i18n/client.d.ts +2 -2
- package/dist/i18n/index.d.mts +3 -3
- package/dist/i18n/index.d.ts +3 -3
- package/dist/i18n/server.d.mts +5 -5
- package/dist/i18n/server.d.ts +5 -5
- package/dist/image/server.d.mts +1 -1
- package/dist/image/server.d.ts +1 -1
- package/dist/image/sharp.d.mts +1 -1
- package/dist/image/sharp.d.ts +1 -1
- package/dist/image.d.mts +1 -1
- package/dist/image.d.ts +1 -1
- package/dist/index.cjs +20 -17
- package/dist/{index-D3l4tREW.d.ts → index.d-BNNDpql4.d.ts} +2 -2
- package/dist/{index-DPUAPho_.d.mts → index.d-BqcfqJvt.d.mts} +2 -2
- package/dist/{index-BxjN_UDZ.d.ts → index.d-YxJ2AiDF.d.mts} +2 -2
- package/dist/{index-BYkNbeQV.d.mts → index.d-yueUNipJ.d.ts} +2 -2
- package/dist/index.d.mts +42 -42
- package/dist/index.d.ts +42 -42
- package/dist/index.mjs +19 -16
- package/dist/instrumentation.d.mts +2 -2
- package/dist/instrumentation.d.ts +2 -2
- package/dist/integrations.cjs +3 -3
- package/dist/integrations.d.mts +13 -13
- package/dist/integrations.d.ts +13 -13
- package/dist/integrations.mjs +2 -2
- package/dist/internal/app-markdown-runtime.d.mts +14 -14
- package/dist/internal/app-markdown-runtime.d.ts +14 -14
- package/dist/internal/build-runtime.cjs +16 -15
- package/dist/internal/build-runtime.d.mts +16 -16
- package/dist/internal/build-runtime.d.ts +16 -16
- package/dist/internal/build-runtime.mjs +15 -14
- package/dist/internal/cli-runtime.cjs +7 -7
- package/dist/internal/cli-runtime.mjs +6 -6
- package/dist/internal/client-error-overlay.cjs +4 -4
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.d.mts +21 -21
- package/dist/internal/client-runtime.d.ts +21 -21
- package/dist/internal/compression-runtime.d.mts +13 -13
- package/dist/internal/compression-runtime.d.ts +13 -13
- package/dist/internal/config-runtime.cjs +5 -5
- package/dist/internal/config-runtime.d.mts +29 -92
- package/dist/internal/config-runtime.d.ts +29 -92
- package/dist/internal/config-runtime.mjs +4 -4
- package/dist/internal/form-actions.d.mts +1 -1
- package/dist/internal/form-actions.d.ts +1 -1
- package/dist/internal/infra-analytics-runtime.cjs +5 -5
- package/dist/internal/infra-analytics-runtime.mjs +3 -3
- package/dist/internal/island-value-store.d.mts +1 -1
- package/dist/internal/island-value-store.d.ts +1 -1
- package/dist/internal/islands-runtime.d.mts +1 -1
- package/dist/internal/islands-runtime.d.ts +1 -1
- package/dist/internal/isolated-boundary.d.mts +2 -2
- package/dist/internal/isolated-boundary.d.ts +2 -2
- package/dist/internal/product-telemetry-runtime.cjs +2 -2
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-runtime.cjs +11 -3
- package/dist/internal/production-runtime.d.mts +57 -31
- package/dist/internal/production-runtime.d.ts +57 -31
- package/dist/internal/production-runtime.mjs +10 -2
- package/dist/internal/server-tree.d.mts +1 -1
- package/dist/internal/server-tree.d.ts +1 -1
- package/dist/markdown.d.mts +13 -13
- package/dist/markdown.d.ts +13 -13
- package/dist/middleware.cjs +4 -4
- package/dist/middleware.d.mts +15 -15
- package/dist/middleware.d.ts +15 -15
- package/dist/middleware.mjs +3 -3
- package/dist/mobile.d.mts +7 -7
- package/dist/mobile.d.ts +7 -7
- package/dist/{navigation-delegate-BU4xqdnw.d.ts → navigation-delegate.d-BY1e_Xrh.d.ts} +1 -1
- package/dist/{navigation-delegate-DLhbfEN4.d.mts → navigation-delegate.d-HnDXhlyP.d.mts} +1 -1
- package/dist/navigation.d.mts +17 -17
- package/dist/navigation.d.ts +17 -17
- package/dist/observability.d.mts +1 -1
- package/dist/observability.d.ts +1 -1
- package/dist/plugin.cjs +11 -11
- package/dist/plugin.d.mts +17 -17
- package/dist/plugin.d.ts +17 -17
- package/dist/plugin.mjs +10 -10
- package/dist/{production-runtime-DLA4J5WG.d.mts → production-runtime.d-BpJUDzP8.d.mts} +3 -3
- package/dist/{production-runtime-C78A8YgK.d.ts → production-runtime.d-lMjvE9cf.d.ts} +3 -3
- package/dist/{programmatic-routes-client-NpqGBn-i.d.mts → programmatic-routes-client.d-6CGQ3TCk.d.mts} +10 -2
- package/dist/{programmatic-routes-client-CBqkNhBy.d.ts → programmatic-routes-client.d-BlFp5hv4.d.ts} +10 -2
- package/dist/query/client.d.mts +1 -1
- package/dist/query/client.d.ts +1 -1
- package/dist/query/index.d.mts +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/server.d.mts +1 -1
- package/dist/query/server.d.ts +1 -1
- package/dist/{render-plan-CrqcBbnV.d.ts → render-plan.d-BH9edqKs.d.mts} +2 -2
- package/dist/{render-plan-C9sWvDTv.d.mts → render-plan.d-DhP0mTHF.d.ts} +2 -2
- package/dist/renderer-client.d.mts +19 -19
- package/dist/renderer-client.d.ts +19 -19
- package/dist/{request-BizeuqD7.d.ts → request.d-BVZrsR1v.d.ts} +1 -1
- package/dist/{request-WwB1-Uim.d.mts → request.d-DJFRdKi8.d.mts} +1 -1
- package/dist/request.d.mts +14 -14
- package/dist/request.d.ts +14 -14
- package/dist/{resolver-CJ-D9nP-.d.ts → resolver.d-BHyZgpa7.d.ts} +1 -1
- package/dist/{resolver-TDyZKgKI.d.mts → resolver.d-JnZKKsc5.d.mts} +1 -1
- package/dist/response.d-BolW0Vx_.d.mts +10 -0
- package/dist/response.d-BolW0Vx_.d.ts +10 -0
- package/dist/{route-rendering-BGhJN64l.d.ts → route-rendering.d-B00JtK_-.d.ts} +1 -1
- package/dist/{route-rendering-S6NFjnx4.d.mts → route-rendering.d-Bpmw7PED.d.mts} +1 -1
- package/dist/{route-2_yXC6gv.d.mts → route.d-BaVH3V0w.d.mts} +1 -1
- package/dist/{route-DFhZj6jN.d.ts → route.d-DBTEqifW.d.ts} +1 -1
- package/dist/{router-BUD_j2EL.d.ts → router.d-Bd1x9XxQ.d.ts} +1 -1
- package/dist/{router-BIheIy9G.d.mts → router.d-e0jQ3jQ-.d.mts} +1 -1
- package/dist/{routes-kEUsXHx3.d.mts → routes.d-Cmv8TgVq.d.mts} +91 -4
- package/dist/{routes-8PT9cl60.d.ts → routes.d-D96Dq9lz.d.ts} +91 -4
- package/dist/routes.d.mts +13 -13
- package/dist/routes.d.ts +13 -13
- package/dist/{rsc-pipeline-JRGUZBYM.cjs → rsc-pipeline-DX4OC5FN.cjs} +6 -6
- package/dist/{rsc-pipeline-OLAVIKI3.mjs → rsc-pipeline-ZQ4CTVEG.mjs} +5 -5
- package/dist/{runtime-OGCHDACZ.mjs → runtime-NPDRDV6R.mjs} +66 -17
- package/dist/{runtime-G23RSLEK.cjs → runtime-NQ3EDSA7.cjs} +75 -26
- package/dist/{runtime-CihDZ2Rn.d.mts → runtime.d-3iJAKptR.d.mts} +2 -2
- package/dist/{runtime-C4CmlOOh.d.ts → runtime.d-BtL3PCL3.d.ts} +2 -2
- package/dist/{runtime-CWP-21hP.d.ts → runtime.d-CgB3IJDq.d.mts} +4 -4
- package/dist/{runtime-CgJwe6H_.d.mts → runtime.d-D-td-RR3.d.ts} +4 -4
- package/dist/server-action-security.d.mts +1 -1
- package/dist/server-action-security.d.ts +1 -1
- package/dist/server-fn-client.d.mts +5 -5
- package/dist/server-fn-client.d.ts +5 -5
- package/dist/server-fn.d.mts +3 -3
- package/dist/server-fn.d.ts +3 -3
- package/dist/server-plugins.d.mts +14 -14
- package/dist/server-plugins.d.ts +14 -14
- package/dist/server-query-client.d.mts +5 -5
- package/dist/server-query-client.d.ts +5 -5
- package/dist/server-query.d.mts +2 -2
- package/dist/server-query.d.ts +2 -2
- package/dist/server.cjs +31 -31
- package/dist/server.d.mts +28 -29
- package/dist/server.d.ts +28 -29
- package/dist/server.mjs +13 -13
- package/dist/session-AAU7RNRO.cjs +23 -0
- package/dist/session-IGEDQ5PY.mjs +23 -0
- package/dist/{spa-router-Kytv4jSB.d.ts → spa-router.d-BWDhS0FK.d.mts} +5 -5
- package/dist/{spa-router-CVOL0Vrq.d.mts → spa-router.d-CO01mVOM.d.ts} +5 -5
- package/dist/storage.d.mts +2 -2
- package/dist/storage.d.ts +2 -2
- package/dist/testing.d.mts +14 -14
- package/dist/testing.d.ts +14 -14
- package/dist/theme/client.d.mts +1 -1
- package/dist/theme/client.d.ts +1 -1
- package/dist/theme/index.d.mts +2 -2
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/runtime.d.mts +1 -1
- package/dist/theme/runtime.d.ts +1 -1
- package/dist/theme/server.d.mts +1 -1
- package/dist/theme/server.d.ts +1 -1
- package/dist/{utils-DbyXlzaj.d.ts → utils.d-B77__yh8.d.ts} +1 -1
- package/dist/{utils-Dsa1HZ7X.d.mts → utils.d-DRDazhCA.d.mts} +1 -1
- package/dist/version.cjs +2 -2
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +11 -11
- package/dist/vite.d.mts +20 -19
- package/dist/vite.d.ts +20 -19
- package/dist/vite.mjs +10 -10
- package/dist/workflows.d.mts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/package.json +5 -5
- /package/dist/{base-path-BOUV5ozD.d.mts → base-path.d-BOUV5ozD.d.mts} +0 -0
- /package/dist/{base-path-BOUV5ozD.d.ts → base-path.d-BOUV5ozD.d.ts} +0 -0
- /package/dist/{chunk-recovery-lnQFzcQP.d.mts → chunk-recovery.d-lnQFzcQP.d.mts} +0 -0
- /package/dist/{chunk-recovery-lnQFzcQP.d.ts → chunk-recovery.d-lnQFzcQP.d.ts} +0 -0
- /package/dist/{client-cache-Deoqq-nM.d.ts → client-cache.d-Deoqq-nM.d.ts} +0 -0
- /package/dist/{client-cache-di_Nasxa.d.mts → client-cache.d-di_Nasxa.d.mts} +0 -0
- /package/dist/{endpoint-BgHn0lhl.d.ts → endpoint.d-BgHn0lhl.d.ts} +0 -0
- /package/dist/{endpoint-BkMSCRf6.d.mts → endpoint.d-BkMSCRf6.d.mts} +0 -0
- /package/dist/{image-config-CeDgNyX4.d.mts → image-config.d-CeDgNyX4.d.mts} +0 -0
- /package/dist/{image-config-CeDgNyX4.d.ts → image-config.d-CeDgNyX4.d.ts} +0 -0
- /package/dist/{instrumentation-runtime-CX9Zh-16.d.mts → instrumentation-runtime.d-CX9Zh-16.d.mts} +0 -0
- /package/dist/{instrumentation-runtime-CX9Zh-16.d.ts → instrumentation-runtime.d-CX9Zh-16.d.ts} +0 -0
- /package/dist/{island-value-protocol-BRayRghM.d.mts → island-value-protocol.d-BRayRghM.d.mts} +0 -0
- /package/dist/{island-value-protocol-BRayRghM.d.ts → island-value-protocol.d-BRayRghM.d.ts} +0 -0
- /package/dist/{island-CfGru1MO.d.mts → island.d-CfGru1MO.d.mts} +0 -0
- /package/dist/{island-CfGru1MO.d.ts → island.d-CfGru1MO.d.ts} +0 -0
- /package/dist/{layers-CcS42OGR.d.mts → layers.d-CcS42OGR.d.mts} +0 -0
- /package/dist/{layers-CcS42OGR.d.ts → layers.d-CcS42OGR.d.ts} +0 -0
- /package/dist/{lifecycle-C2aLBOwu.d.mts → lifecycle.d-C2aLBOwu.d.mts} +0 -0
- /package/dist/{lifecycle-C2aLBOwu.d.ts → lifecycle.d-C2aLBOwu.d.ts} +0 -0
- /package/dist/{observability-B2363jB6.d.mts → observability.d-B2363jB6.d.mts} +0 -0
- /package/dist/{observability-B2363jB6.d.ts → observability.d-B2363jB6.d.ts} +0 -0
- /package/dist/{params-BALtrRim.d.ts → params.d-BALtrRim.d.ts} +0 -0
- /package/dist/{params-ry-lxqmy.d.mts → params.d-ry-lxqmy.d.mts} +0 -0
- /package/dist/{production-vite-BQFAlG7n.d.mts → production-vite.d-BQFAlG7n.d.mts} +0 -0
- /package/dist/{production-vite-BQFAlG7n.d.ts → production-vite.d-BQFAlG7n.d.ts} +0 -0
- /package/dist/{route-pattern-CVsVbq5n.d.mts → route-pattern.d-CVsVbq5n.d.mts} +0 -0
- /package/dist/{route-pattern-CVsVbq5n.d.ts → route-pattern.d-CVsVbq5n.d.ts} +0 -0
- /package/dist/{server-client-bridge-DKWDl5NB.d.mts → server-client-bridge.d-DKWDl5NB.d.mts} +0 -0
- /package/dist/{server-client-bridge-DKWDl5NB.d.ts → server-client-bridge.d-DKWDl5NB.d.ts} +0 -0
- /package/dist/{server-fn-error-DrcH9cc1.d.mts → server-fn-error.d-DrcH9cc1.d.mts} +0 -0
- /package/dist/{server-fn-error-DrcH9cc1.d.ts → server-fn-error.d-DrcH9cc1.d.ts} +0 -0
- /package/dist/{server-query-runtime-DXRNhX_3.d.ts → server-query-runtime.d-DXRNhX_3.d.ts} +0 -0
- /package/dist/{server-query-runtime-aP52iuL5.d.mts → server-query-runtime.d-aP52iuL5.d.mts} +0 -0
- /package/dist/{types-BnIqOn9w.d.mts → types.d-BnIqOn9w.d.mts} +0 -0
- /package/dist/{types-BnIqOn9w.d.ts → types.d-BnIqOn9w.d.ts} +0 -0
- /package/dist/{types-C41ePjvP.d.mts → types.d-C41ePjvP.d.mts} +0 -0
- /package/dist/{types-C41ePjvP.d.ts → types.d-C41ePjvP.d.ts} +0 -0
- /package/dist/{types-DQnyD3VD.d.mts → types.d-DQnyD3VD.d.mts} +0 -0
- /package/dist/{types-DQnyD3VD.d.ts → types.d-DQnyD3VD.d.ts} +0 -0
- /package/dist/{workflows-CRMzQZ3k.d.mts → workflows.d-CRMzQZ3k.d.mts} +0 -0
- /package/dist/{workflows-CRMzQZ3k.d.ts → workflows.d-CRMzQZ3k.d.ts} +0 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getStorage
|
|
3
|
+
} from "./chunk-TJVUTGED.mjs";
|
|
4
|
+
import {
|
|
5
|
+
farmSecretsMatch
|
|
6
|
+
} from "./chunk-YP7YO3S3.mjs";
|
|
7
|
+
|
|
8
|
+
// src/mobile/session.ts
|
|
9
|
+
var FARM_MOBILE_SESSION_PLUGIN = "farm:mobile-session";
|
|
10
|
+
var FARM_MOBILE_SESSION_PATH = "/__farm/mobile/session";
|
|
11
|
+
var FARM_MOBILE_APP_HEADER = "x-farm-mobile";
|
|
12
|
+
var FARM_MOBILE_NONCE_HEADER = "x-farm-mobile-nonce";
|
|
13
|
+
var FARM_MOBILE_DEVICE_COOKIE = "farm_mobile";
|
|
14
|
+
var ACCESS_PREFIX = "fma1";
|
|
15
|
+
var REFRESH_PREFIX = "fmr1";
|
|
16
|
+
var STORAGE_NAMESPACE = "farm-mobile";
|
|
17
|
+
var STATE_KEY = "farm:mobile-session";
|
|
18
|
+
var USED_REFRESH_LIMIT = 8;
|
|
19
|
+
var BROWSER_HEADERS = [
|
|
20
|
+
"origin",
|
|
21
|
+
"sec-fetch-site",
|
|
22
|
+
"sec-fetch-mode",
|
|
23
|
+
"sec-fetch-dest",
|
|
24
|
+
"sec-fetch-user"
|
|
25
|
+
];
|
|
26
|
+
var APP_ID = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
|
|
27
|
+
var BASE64URL = /^[A-Za-z0-9_-]+$/;
|
|
28
|
+
var encoder = new TextEncoder();
|
|
29
|
+
var decoder = new TextDecoder();
|
|
30
|
+
function toBase64Url(bytes) {
|
|
31
|
+
let binary = "";
|
|
32
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
33
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
34
|
+
}
|
|
35
|
+
function fromBase64Url(value) {
|
|
36
|
+
const base64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
37
|
+
const binary = atob(base64 + "=".repeat((4 - base64.length % 4) % 4));
|
|
38
|
+
const bytes = new Uint8Array(binary.length);
|
|
39
|
+
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
40
|
+
return bytes;
|
|
41
|
+
}
|
|
42
|
+
function randomToken(bytes) {
|
|
43
|
+
return toBase64Url(globalThis.crypto.getRandomValues(new Uint8Array(bytes)));
|
|
44
|
+
}
|
|
45
|
+
async function sha256(value) {
|
|
46
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", encoder.encode(value));
|
|
47
|
+
return toBase64Url(new Uint8Array(digest));
|
|
48
|
+
}
|
|
49
|
+
async function aesKey(key) {
|
|
50
|
+
return globalThis.crypto.subtle.importKey("raw", fromBase64Url(key), "AES-GCM", false, [
|
|
51
|
+
"encrypt",
|
|
52
|
+
"decrypt"
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
async function sealJar(jar, key, deviceId) {
|
|
56
|
+
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
|
|
57
|
+
const data = await globalThis.crypto.subtle.encrypt(
|
|
58
|
+
{ name: "AES-GCM", iv, additionalData: encoder.encode(deviceId) },
|
|
59
|
+
await aesKey(key),
|
|
60
|
+
encoder.encode(JSON.stringify(jar))
|
|
61
|
+
);
|
|
62
|
+
return { iv: toBase64Url(iv), data: toBase64Url(new Uint8Array(data)) };
|
|
63
|
+
}
|
|
64
|
+
async function openJar(sealed, key, deviceId) {
|
|
65
|
+
try {
|
|
66
|
+
const data = await globalThis.crypto.subtle.decrypt(
|
|
67
|
+
{ name: "AES-GCM", iv: fromBase64Url(sealed.iv), additionalData: encoder.encode(deviceId) },
|
|
68
|
+
await aesKey(key),
|
|
69
|
+
fromBase64Url(sealed.data)
|
|
70
|
+
);
|
|
71
|
+
const jar = JSON.parse(decoder.decode(data));
|
|
72
|
+
if (!jar || typeof jar !== "object" || Array.isArray(jar)) return null;
|
|
73
|
+
return Object.fromEntries(
|
|
74
|
+
Object.entries(jar).filter(
|
|
75
|
+
(entry) => typeof entry[1] === "string"
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function formatToken(prefix, token) {
|
|
83
|
+
return `${prefix}.${token.deviceId}.${token.secret}.${token.key}`;
|
|
84
|
+
}
|
|
85
|
+
function parseFarmMobileToken(value, kind) {
|
|
86
|
+
if (typeof value !== "string" || value.length > 256) return null;
|
|
87
|
+
const parts = value.split(".");
|
|
88
|
+
if (parts.length !== 4 || parts[0] !== (kind === "access" ? ACCESS_PREFIX : REFRESH_PREFIX)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const [, deviceId, secret, key] = parts;
|
|
92
|
+
if (deviceId.length !== 22 || secret.length !== 43 || key.length !== 43) return null;
|
|
93
|
+
if (!BASE64URL.test(deviceId) || !BASE64URL.test(secret) || !BASE64URL.test(key)) return null;
|
|
94
|
+
return { deviceId, secret, key };
|
|
95
|
+
}
|
|
96
|
+
function readCookies(header) {
|
|
97
|
+
const cookies = {};
|
|
98
|
+
for (const part of (header ?? "").split(";")) {
|
|
99
|
+
const separator = part.indexOf("=");
|
|
100
|
+
if (separator <= 0) continue;
|
|
101
|
+
const name = part.slice(0, separator).trim();
|
|
102
|
+
if (!name || name === "__proto__" || name in cookies) continue;
|
|
103
|
+
cookies[name] = part.slice(separator + 1).trim();
|
|
104
|
+
}
|
|
105
|
+
return cookies;
|
|
106
|
+
}
|
|
107
|
+
function cookieHeader(jar) {
|
|
108
|
+
return Object.entries(jar).map(([name, value]) => `${name}=${value}`).join("; ");
|
|
109
|
+
}
|
|
110
|
+
function readSetCookies(headers, now) {
|
|
111
|
+
const changes = [];
|
|
112
|
+
for (const line of headers.getSetCookie()) {
|
|
113
|
+
const [pair = "", ...attributes] = line.split(";");
|
|
114
|
+
const separator = pair.indexOf("=");
|
|
115
|
+
if (separator <= 0) continue;
|
|
116
|
+
const name = pair.slice(0, separator).trim();
|
|
117
|
+
if (!name || name === "__proto__") continue;
|
|
118
|
+
let expired = false;
|
|
119
|
+
for (const attribute of attributes) {
|
|
120
|
+
const [rawKey = "", ...rest] = attribute.split("=");
|
|
121
|
+
const key = rawKey.trim().toLowerCase();
|
|
122
|
+
const value = rest.join("=").trim();
|
|
123
|
+
if (key === "max-age" && /^-?\d+$/.test(value)) expired = Number(value) <= 0;
|
|
124
|
+
if (key === "expires" && !attributes.some((item) => /^\s*max-age=/i.test(item))) {
|
|
125
|
+
const time = Date.parse(value);
|
|
126
|
+
if (!Number.isNaN(time) && time <= now) expired = true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
changes.push([name, expired ? null : pair.slice(separator + 1).trim()]);
|
|
130
|
+
}
|
|
131
|
+
return changes;
|
|
132
|
+
}
|
|
133
|
+
function applySetCookies(jar, changes) {
|
|
134
|
+
const next = { ...jar };
|
|
135
|
+
for (const [name, value] of changes) {
|
|
136
|
+
if (name === FARM_MOBILE_DEVICE_COOKIE) continue;
|
|
137
|
+
if (value === null) delete next[name];
|
|
138
|
+
else next[name] = value;
|
|
139
|
+
}
|
|
140
|
+
return next;
|
|
141
|
+
}
|
|
142
|
+
function json(body, status = 200, headers) {
|
|
143
|
+
const response = Response.json(body, { status, headers });
|
|
144
|
+
response.headers.set("cache-control", "no-store");
|
|
145
|
+
return response;
|
|
146
|
+
}
|
|
147
|
+
function failure(status, error, message) {
|
|
148
|
+
const response = json({ error, message }, status);
|
|
149
|
+
if (status === 401) {
|
|
150
|
+
response.headers.set("www-authenticate", `Bearer error="invalid_token"`);
|
|
151
|
+
}
|
|
152
|
+
return response;
|
|
153
|
+
}
|
|
154
|
+
function isFarmMobileNativeRequest(request) {
|
|
155
|
+
return !BROWSER_HEADERS.some((name) => request.headers.has(name));
|
|
156
|
+
}
|
|
157
|
+
function readAppId(request) {
|
|
158
|
+
const value = request.headers.get(FARM_MOBILE_APP_HEADER)?.trim();
|
|
159
|
+
return value && value.length <= 255 && APP_ID.test(value) ? value : null;
|
|
160
|
+
}
|
|
161
|
+
function bearer(request) {
|
|
162
|
+
const header = request.headers.get("authorization");
|
|
163
|
+
if (!header) return null;
|
|
164
|
+
const match = /^bearer\s+(\S+)$/i.exec(header.trim());
|
|
165
|
+
return match ? match[1] : null;
|
|
166
|
+
}
|
|
167
|
+
var SessionReadError = class extends Error {
|
|
168
|
+
constructor(message, reason) {
|
|
169
|
+
super(message);
|
|
170
|
+
this.reason = reason;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function createFarmMobileSessionPlugin(options) {
|
|
174
|
+
const basePath = options.basePath && options.basePath !== "/" ? options.basePath : "";
|
|
175
|
+
const accessTtl = (options.accessTokenTtl ?? 15 * 60) * 1e3;
|
|
176
|
+
const refreshTtl = (options.refreshTokenTtl ?? 30 * 24 * 60 * 60) * 1e3;
|
|
177
|
+
const nonceTtl = (options.nonceTtl ?? 60) * 1e3;
|
|
178
|
+
const now = options.now ?? Date.now;
|
|
179
|
+
const store = () => options.storage?.() ?? getStorage(STORAGE_NAMESPACE);
|
|
180
|
+
let warnedNoReader = false;
|
|
181
|
+
function sessionReader() {
|
|
182
|
+
for (const integration of Object.values(options.integrations() ?? {})) {
|
|
183
|
+
const session = integration?.session;
|
|
184
|
+
if (typeof session === "function") {
|
|
185
|
+
return (request) => session.call(integration, request);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
async function readSession(reader, url, cookies) {
|
|
191
|
+
const header = cookieHeader(cookies);
|
|
192
|
+
if (!header) return null;
|
|
193
|
+
let session;
|
|
194
|
+
try {
|
|
195
|
+
session = await reader(new Request(url, { headers: { cookie: header } }));
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new SessionReadError("The auth integration's session() failed", error);
|
|
198
|
+
}
|
|
199
|
+
const id = session?.id;
|
|
200
|
+
return typeof id === "string" && id ? session : null;
|
|
201
|
+
}
|
|
202
|
+
function noReader() {
|
|
203
|
+
if (!warnedNoReader) {
|
|
204
|
+
warnedNoReader = true;
|
|
205
|
+
console.warn(
|
|
206
|
+
"[Farm] Mobile session tokens need an auth integration that reads sessions (`session()`): @farm.js/auth (`auth: true`) or @farm.js/better-auth. No configured integration has one, so native screens stay signed out."
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return failure(
|
|
210
|
+
501,
|
|
211
|
+
"mobile_session_unavailable",
|
|
212
|
+
"No auth integration in this app reads sessions for mobile tokens."
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
function markerCookie(request, value, maxAge) {
|
|
216
|
+
const secure = new URL(request.url).protocol === "https:" ? "; Secure" : "";
|
|
217
|
+
return `${FARM_MOBILE_DEVICE_COOKIE}=${value}; Path=${basePath || "/"}; Max-Age=${maxAge}; HttpOnly; SameSite=Lax${secure}`;
|
|
218
|
+
}
|
|
219
|
+
async function loadDevice(deviceId) {
|
|
220
|
+
const record = await store().getItem(`device:${deviceId}`);
|
|
221
|
+
return record && record.v === 1 ? record : null;
|
|
222
|
+
}
|
|
223
|
+
async function saveDevice(deviceId, record) {
|
|
224
|
+
await store().setItem(`device:${deviceId}`, record);
|
|
225
|
+
}
|
|
226
|
+
async function revokeDevice(deviceId) {
|
|
227
|
+
await store().removeItem(`device:${deviceId}`);
|
|
228
|
+
}
|
|
229
|
+
async function challengeKey(sessionId, appId) {
|
|
230
|
+
return `challenge:${await sha256(`${sessionId}
|
|
231
|
+
${appId}`)}`;
|
|
232
|
+
}
|
|
233
|
+
async function issueTokens(deviceId, key, base, jar) {
|
|
234
|
+
const access = { deviceId, secret: randomToken(32), key };
|
|
235
|
+
const refresh2 = { deviceId, secret: randomToken(32), key };
|
|
236
|
+
const issuedAt = now();
|
|
237
|
+
const record = {
|
|
238
|
+
...base,
|
|
239
|
+
accessHash: await sha256(access.secret),
|
|
240
|
+
accessExpiresAt: issuedAt + accessTtl,
|
|
241
|
+
refreshHash: await sha256(refresh2.secret),
|
|
242
|
+
refreshExpiresAt: issuedAt + refreshTtl,
|
|
243
|
+
jar: await sealJar(jar, key, deviceId)
|
|
244
|
+
};
|
|
245
|
+
await saveDevice(deviceId, record);
|
|
246
|
+
return {
|
|
247
|
+
record,
|
|
248
|
+
body: {
|
|
249
|
+
tokenType: "Bearer",
|
|
250
|
+
accessToken: formatToken(ACCESS_PREFIX, access),
|
|
251
|
+
refreshToken: formatToken(REFRESH_PREFIX, refresh2),
|
|
252
|
+
expiresIn: Math.floor(accessTtl / 1e3),
|
|
253
|
+
refreshExpiresIn: Math.floor(refreshTtl / 1e3)
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function guardEndpoint(request) {
|
|
258
|
+
if (request.method !== "POST") {
|
|
259
|
+
return new Response("Method Not Allowed", {
|
|
260
|
+
status: 405,
|
|
261
|
+
headers: { allow: "POST", "cache-control": "no-store" }
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (!isFarmMobileNativeRequest(request)) {
|
|
265
|
+
return failure(403, "not_native", "Mobile session endpoints answer the app's shell only.");
|
|
266
|
+
}
|
|
267
|
+
const appId = readAppId(request);
|
|
268
|
+
if (!appId) {
|
|
269
|
+
return failure(400, "invalid_app", `Send the app's mobile.id in ${FARM_MOBILE_APP_HEADER}.`);
|
|
270
|
+
}
|
|
271
|
+
return { appId };
|
|
272
|
+
}
|
|
273
|
+
async function challenge(request) {
|
|
274
|
+
const guard = guardEndpoint(request);
|
|
275
|
+
if (guard instanceof Response) return guard;
|
|
276
|
+
const reader = sessionReader();
|
|
277
|
+
if (!reader) return noReader();
|
|
278
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
279
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
280
|
+
const session = await readSession(reader, request.url, cookies);
|
|
281
|
+
if (!session) return failure(401, "signed_out", "Sign in on a web screen first.");
|
|
282
|
+
const nonce = randomToken(32);
|
|
283
|
+
await store().setItem(await challengeKey(session.id, guard.appId), {
|
|
284
|
+
hash: await sha256(nonce),
|
|
285
|
+
expiresAt: now() + nonceTtl
|
|
286
|
+
});
|
|
287
|
+
return json({ nonce, expiresIn: Math.floor(nonceTtl / 1e3) });
|
|
288
|
+
}
|
|
289
|
+
async function issue(request) {
|
|
290
|
+
const guard = guardEndpoint(request);
|
|
291
|
+
if (guard instanceof Response) return guard;
|
|
292
|
+
const reader = sessionReader();
|
|
293
|
+
if (!reader) return noReader();
|
|
294
|
+
const nonce = request.headers.get(FARM_MOBILE_NONCE_HEADER)?.trim() ?? "";
|
|
295
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
296
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
297
|
+
const session = await readSession(reader, request.url, cookies);
|
|
298
|
+
if (!session) return failure(401, "signed_out", "Sign in on a web screen first.");
|
|
299
|
+
const key = await challengeKey(session.id, guard.appId);
|
|
300
|
+
const pending = await store().getItem(key);
|
|
301
|
+
if (pending) await store().removeItem(key);
|
|
302
|
+
if (!pending || pending.expiresAt <= now() || !nonce || !farmSecretsMatch(await sha256(nonce), pending.hash)) {
|
|
303
|
+
return failure(401, "invalid_nonce", "Request a new challenge and try again.");
|
|
304
|
+
}
|
|
305
|
+
const deviceId = randomToken(16);
|
|
306
|
+
const { body: tokens } = await issueTokens(
|
|
307
|
+
deviceId,
|
|
308
|
+
randomToken(32),
|
|
309
|
+
{
|
|
310
|
+
v: 1,
|
|
311
|
+
appId: guard.appId,
|
|
312
|
+
sessionHash: await sha256(session.id),
|
|
313
|
+
createdAt: now(),
|
|
314
|
+
usedRefreshHashes: []
|
|
315
|
+
},
|
|
316
|
+
cookies
|
|
317
|
+
);
|
|
318
|
+
const response = json(tokens);
|
|
319
|
+
response.headers.append(
|
|
320
|
+
"set-cookie",
|
|
321
|
+
markerCookie(request, deviceId, Math.floor(refreshTtl / 1e3))
|
|
322
|
+
);
|
|
323
|
+
return response;
|
|
324
|
+
}
|
|
325
|
+
async function refresh(request) {
|
|
326
|
+
const guard = guardEndpoint(request);
|
|
327
|
+
if (guard instanceof Response) return guard;
|
|
328
|
+
const reader = sessionReader();
|
|
329
|
+
if (!reader) return noReader();
|
|
330
|
+
const token = parseFarmMobileToken(bearer(request), "refresh");
|
|
331
|
+
if (!token) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
332
|
+
const record = await loadDevice(token.deviceId);
|
|
333
|
+
if (!record) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
334
|
+
if (record.appId !== guard.appId) {
|
|
335
|
+
return failure(401, "invalid_token", "The token belongs to another app.");
|
|
336
|
+
}
|
|
337
|
+
const hash = await sha256(token.secret);
|
|
338
|
+
if (!farmSecretsMatch(hash, record.refreshHash)) {
|
|
339
|
+
if (record.usedRefreshHashes.some((used) => farmSecretsMatch(hash, used))) {
|
|
340
|
+
await revokeDevice(token.deviceId);
|
|
341
|
+
return failure(401, "refresh_reused", "The refresh token was already used.");
|
|
342
|
+
}
|
|
343
|
+
return failure(401, "invalid_token", "Unknown refresh token.");
|
|
344
|
+
}
|
|
345
|
+
if (record.refreshExpiresAt <= now()) {
|
|
346
|
+
await revokeDevice(token.deviceId);
|
|
347
|
+
return failure(401, "invalid_token", "The refresh token expired.");
|
|
348
|
+
}
|
|
349
|
+
const jar = await openJar(record.jar, token.key, token.deviceId);
|
|
350
|
+
if (!jar) return failure(401, "invalid_token", "Unknown refresh token.");
|
|
351
|
+
let session;
|
|
352
|
+
try {
|
|
353
|
+
session = await readSession(reader, request.url, jar);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.error("[Farm] Mobile session refresh could not read the session:", error);
|
|
356
|
+
return failure(503, "session_unavailable", "Try again later.");
|
|
357
|
+
}
|
|
358
|
+
if (!session || await sha256(session.id) !== record.sessionHash) {
|
|
359
|
+
await revokeDevice(token.deviceId);
|
|
360
|
+
return failure(401, "signed_out", "The web session behind this device ended.");
|
|
361
|
+
}
|
|
362
|
+
const { body: tokens } = await issueTokens(
|
|
363
|
+
token.deviceId,
|
|
364
|
+
randomToken(32),
|
|
365
|
+
{
|
|
366
|
+
v: 1,
|
|
367
|
+
appId: record.appId,
|
|
368
|
+
sessionHash: record.sessionHash,
|
|
369
|
+
createdAt: record.createdAt,
|
|
370
|
+
usedRefreshHashes: [record.refreshHash, ...record.usedRefreshHashes].slice(
|
|
371
|
+
0,
|
|
372
|
+
USED_REFRESH_LIMIT
|
|
373
|
+
)
|
|
374
|
+
},
|
|
375
|
+
jar
|
|
376
|
+
);
|
|
377
|
+
const response = json(tokens);
|
|
378
|
+
response.headers.append(
|
|
379
|
+
"set-cookie",
|
|
380
|
+
markerCookie(request, token.deviceId, Math.floor(refreshTtl / 1e3))
|
|
381
|
+
);
|
|
382
|
+
return response;
|
|
383
|
+
}
|
|
384
|
+
async function revoke(request) {
|
|
385
|
+
const guard = guardEndpoint(request);
|
|
386
|
+
if (guard instanceof Response) return guard;
|
|
387
|
+
const access = parseFarmMobileToken(bearer(request), "access");
|
|
388
|
+
const token = access ?? parseFarmMobileToken(bearer(request), "refresh");
|
|
389
|
+
if (token) {
|
|
390
|
+
const record = await loadDevice(token.deviceId);
|
|
391
|
+
const hash = await sha256(token.secret);
|
|
392
|
+
if (record && record.appId === guard.appId && farmSecretsMatch(hash, access ? record.accessHash : record.refreshHash)) {
|
|
393
|
+
await revokeDevice(token.deviceId);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const response = new Response(null, { status: 204, headers: { "cache-control": "no-store" } });
|
|
397
|
+
response.headers.append("set-cookie", markerCookie(request, "", 0));
|
|
398
|
+
return response;
|
|
399
|
+
}
|
|
400
|
+
async function before(event) {
|
|
401
|
+
const { request } = event;
|
|
402
|
+
const value = bearer(request);
|
|
403
|
+
if (!value?.startsWith(`${ACCESS_PREFIX}.`)) return void 0;
|
|
404
|
+
if (!isFarmMobileNativeRequest(request)) return void 0;
|
|
405
|
+
const token = parseFarmMobileToken(value, "access");
|
|
406
|
+
if (!token) return failure(401, "invalid_token", "Unknown access token.");
|
|
407
|
+
const appId = readAppId(request);
|
|
408
|
+
const record = await loadDevice(token.deviceId);
|
|
409
|
+
const hash = await sha256(token.secret);
|
|
410
|
+
if (!record || !farmSecretsMatch(hash, record.accessHash)) {
|
|
411
|
+
return failure(401, "invalid_token", "Unknown access token.");
|
|
412
|
+
}
|
|
413
|
+
if (!appId || appId !== record.appId) {
|
|
414
|
+
return failure(401, "invalid_token", "The token belongs to another app.");
|
|
415
|
+
}
|
|
416
|
+
if (record.accessExpiresAt <= now()) {
|
|
417
|
+
return failure(401, "invalid_token", "The access token expired.");
|
|
418
|
+
}
|
|
419
|
+
const jar = await openJar(record.jar, token.key, token.deviceId);
|
|
420
|
+
if (!jar) return failure(401, "invalid_token", "Unknown access token.");
|
|
421
|
+
const headers = new Headers(request.headers);
|
|
422
|
+
headers.delete("authorization");
|
|
423
|
+
headers.delete("cookie");
|
|
424
|
+
const cookies = cookieHeader(jar);
|
|
425
|
+
if (cookies) headers.set("cookie", cookies);
|
|
426
|
+
headers.set("origin", new URL(request.url).origin);
|
|
427
|
+
event.req.set(STATE_KEY, {
|
|
428
|
+
deviceId: token.deviceId,
|
|
429
|
+
key: token.key,
|
|
430
|
+
accessHash: record.accessHash
|
|
431
|
+
});
|
|
432
|
+
return new Request(request, { headers });
|
|
433
|
+
}
|
|
434
|
+
async function after(event) {
|
|
435
|
+
const state = event.req.get(STATE_KEY);
|
|
436
|
+
if (state) return afterBearer(event.request, event.response, state);
|
|
437
|
+
const cookie = event.request.headers.get("cookie");
|
|
438
|
+
if (!cookie?.includes(`${FARM_MOBILE_DEVICE_COOKIE}=`)) return void 0;
|
|
439
|
+
return afterWebScreen(event.request, event.response);
|
|
440
|
+
}
|
|
441
|
+
async function afterBearer(request, response, state) {
|
|
442
|
+
const changes = readSetCookies(response.headers, now());
|
|
443
|
+
const headers = new Headers(response.headers);
|
|
444
|
+
headers.delete("set-cookie");
|
|
445
|
+
headers.set("cache-control", "private, no-store");
|
|
446
|
+
if (changes.length > 0) {
|
|
447
|
+
const record = await loadDevice(state.deviceId);
|
|
448
|
+
if (record && farmSecretsMatch(state.accessHash, record.accessHash)) {
|
|
449
|
+
const jar = await openJar(record.jar, state.key, state.deviceId);
|
|
450
|
+
if (jar) {
|
|
451
|
+
const next = applySetCookies(jar, changes);
|
|
452
|
+
const reader = sessionReader();
|
|
453
|
+
let signedOut = false;
|
|
454
|
+
if (reader && changes.some(([, value]) => value === null)) {
|
|
455
|
+
signedOut = await readSession(reader, request.url, next).then(
|
|
456
|
+
async (session) => !session || await sha256(session.id) !== record.sessionHash,
|
|
457
|
+
() => false
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
if (signedOut) await revokeDevice(state.deviceId);
|
|
461
|
+
else
|
|
462
|
+
await saveDevice(state.deviceId, {
|
|
463
|
+
...record,
|
|
464
|
+
jar: await sealJar(next, state.key, state.deviceId)
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return new Response(response.body, {
|
|
470
|
+
status: response.status,
|
|
471
|
+
statusText: response.statusText,
|
|
472
|
+
headers
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
async function afterWebScreen(request, response) {
|
|
476
|
+
const changes = readSetCookies(response.headers, now());
|
|
477
|
+
if (!changes.some(([, value]) => value === null)) return void 0;
|
|
478
|
+
const cookies = readCookies(request.headers.get("cookie"));
|
|
479
|
+
const deviceId = cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
480
|
+
if (!deviceId || deviceId.length !== 22 || !BASE64URL.test(deviceId)) return void 0;
|
|
481
|
+
const reader = sessionReader();
|
|
482
|
+
if (!reader) return void 0;
|
|
483
|
+
delete cookies[FARM_MOBILE_DEVICE_COOKIE];
|
|
484
|
+
const signedOut = await readSession(
|
|
485
|
+
reader,
|
|
486
|
+
request.url,
|
|
487
|
+
applySetCookies(cookies, changes)
|
|
488
|
+
).then(
|
|
489
|
+
(session) => !session,
|
|
490
|
+
() => false
|
|
491
|
+
);
|
|
492
|
+
if (!signedOut) return void 0;
|
|
493
|
+
await revokeDevice(deviceId);
|
|
494
|
+
const headers = new Headers(response.headers);
|
|
495
|
+
headers.append("set-cookie", markerCookie(request, "", 0));
|
|
496
|
+
return new Response(response.body, {
|
|
497
|
+
status: response.status,
|
|
498
|
+
statusText: response.statusText,
|
|
499
|
+
headers
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
const endpoint = (path, handler) => ({
|
|
503
|
+
path,
|
|
504
|
+
handler: (event) => handler(event.request).catch((error) => {
|
|
505
|
+
if (error instanceof SessionReadError) {
|
|
506
|
+
console.error("[Farm] Mobile session endpoint could not read the session:", error.reason);
|
|
507
|
+
return failure(503, "session_unavailable", "Try again later.");
|
|
508
|
+
}
|
|
509
|
+
throw error;
|
|
510
|
+
})
|
|
511
|
+
});
|
|
512
|
+
return {
|
|
513
|
+
name: FARM_MOBILE_SESSION_PLUGIN,
|
|
514
|
+
// Before app plugins, so their hooks see the signed-in request.
|
|
515
|
+
enforce: "pre",
|
|
516
|
+
runtime: {
|
|
517
|
+
// `before` changes only requests with a mobile bearer, and `after` marks those private.
|
|
518
|
+
// Every other response stays as cacheable as it was.
|
|
519
|
+
cache: "public",
|
|
520
|
+
endpoints: [
|
|
521
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/challenge`, challenge),
|
|
522
|
+
endpoint(FARM_MOBILE_SESSION_PATH, issue),
|
|
523
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/refresh`, refresh),
|
|
524
|
+
endpoint(`${FARM_MOBILE_SESSION_PATH}/revoke`, revoke)
|
|
525
|
+
],
|
|
526
|
+
before,
|
|
527
|
+
after
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export {
|
|
533
|
+
FARM_MOBILE_SESSION_PLUGIN,
|
|
534
|
+
FARM_MOBILE_SESSION_PATH,
|
|
535
|
+
FARM_MOBILE_APP_HEADER,
|
|
536
|
+
FARM_MOBILE_NONCE_HEADER,
|
|
537
|
+
FARM_MOBILE_DEVICE_COOKIE,
|
|
538
|
+
parseFarmMobileToken,
|
|
539
|
+
isFarmMobileNativeRequest,
|
|
540
|
+
createFarmMobileSessionPlugin
|
|
541
|
+
};
|
|
@@ -19,7 +19,7 @@ var _chunkITV4QQL2cjs = require('./chunk-ITV4QQL2.cjs');
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
var
|
|
22
|
+
var _chunkYIHRZBD7cjs = require('./chunk-YIHRZBD7.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
|
|
@@ -776,6 +776,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
776
776
|
}
|
|
777
777
|
},
|
|
778
778
|
async beforeRequest(req, res, context) {
|
|
779
|
+
if (req.url && !req.url.startsWith("/")) return;
|
|
779
780
|
const fullUrl = `http://${req.headers.host || "localhost"}${req.url || "/"}`;
|
|
780
781
|
const url = new URL(fullUrl);
|
|
781
782
|
const pathname = url.pathname;
|
|
@@ -806,7 +807,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
806
807
|
} catch (error) {
|
|
807
808
|
const response = _chunkLIFUPCXWcjs.createFarmRequestBodyErrorResponse.call(void 0, error);
|
|
808
809
|
if (!response) throw error;
|
|
809
|
-
await
|
|
810
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, response);
|
|
810
811
|
return null;
|
|
811
812
|
}
|
|
812
813
|
};
|
|
@@ -854,10 +855,10 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
854
855
|
for (const cookie of forwardedCookies) {
|
|
855
856
|
setCookieHeaders.append("set-cookie", cookie);
|
|
856
857
|
}
|
|
857
|
-
|
|
858
|
+
_chunkYIHRZBD7cjs.applyWebResponseHeaders.call(void 0, res, setCookieHeaders, { appendSetCookie: true });
|
|
858
859
|
}
|
|
859
860
|
if (response) {
|
|
860
|
-
await
|
|
861
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, response);
|
|
861
862
|
await emitIntegrationLog(integration, {
|
|
862
863
|
category: integration.category,
|
|
863
864
|
slot: integration.category,
|
|
@@ -950,7 +951,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
950
951
|
try {
|
|
951
952
|
const validation = await validateIntegrationRouteInput(route, request, url);
|
|
952
953
|
if (!validation.success) {
|
|
953
|
-
await
|
|
954
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, validation.response);
|
|
954
955
|
await emitIntegrationLog(integration, {
|
|
955
956
|
category: integration.category,
|
|
956
957
|
slot: integration.category,
|
|
@@ -973,7 +974,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
973
974
|
for (const middlewareEntry of route.middleware || []) {
|
|
974
975
|
const middlewareResponse = await middlewareEntry.handler(request, handlerContext);
|
|
975
976
|
if (middlewareResponse) {
|
|
976
|
-
await
|
|
977
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, middlewareResponse);
|
|
977
978
|
await emitIntegrationLog(integration, {
|
|
978
979
|
category: integration.category,
|
|
979
980
|
slot: integration.category,
|
|
@@ -1005,7 +1006,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
1005
1006
|
handlerContext,
|
|
1006
1007
|
beforeResponse
|
|
1007
1008
|
);
|
|
1008
|
-
await
|
|
1009
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, response2);
|
|
1009
1010
|
await emitIntegrationLog(integration, {
|
|
1010
1011
|
category: integration.category,
|
|
1011
1012
|
slot: integration.category,
|
|
@@ -1031,7 +1032,7 @@ function createIntegrationPlugin(integrationKey, integration) {
|
|
|
1031
1032
|
handlerContext,
|
|
1032
1033
|
handlerResponse
|
|
1033
1034
|
);
|
|
1034
|
-
await
|
|
1035
|
+
await _chunkYIHRZBD7cjs.sendWebResponse.call(void 0, res, response);
|
|
1035
1036
|
await emitIntegrationLog(integration, {
|
|
1036
1037
|
category: integration.category,
|
|
1037
1038
|
slot: integration.category,
|
|
@@ -152,8 +152,21 @@ async function sendWebResponse(res, response) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
async function fetchFarmExternalRewrite(request) {
|
|
156
|
+
const response = await fetch(request);
|
|
157
|
+
if (!response.headers.has("content-encoding")) return response;
|
|
158
|
+
const headers = new Headers(response.headers);
|
|
159
|
+
headers.delete("content-encoding");
|
|
160
|
+
headers.delete("content-length");
|
|
161
|
+
return new Response(response.body, {
|
|
162
|
+
status: response.status,
|
|
163
|
+
statusText: response.statusText,
|
|
164
|
+
headers
|
|
165
|
+
});
|
|
166
|
+
}
|
|
155
167
|
|
|
156
168
|
export {
|
|
157
169
|
applyWebResponseHeaders,
|
|
158
|
-
sendWebResponse
|
|
170
|
+
sendWebResponse,
|
|
171
|
+
fetchFarmExternalRewrite
|
|
159
172
|
};
|