@farm.js/core 0.1.0-beta.97 → 0.1.0-beta.98
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-CJKz2mbi.d.ts} +4 -4
- package/dist/{app-DBd6437H.d.mts → app-DMEGFLR2.d.mts} +4 -4
- package/dist/app-markdown.cjs.map +1 -0
- package/dist/app-markdown.d.mts +3 -3
- package/dist/app-markdown.d.ts +3 -3
- package/dist/cache.cjs.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-X4SFHKFH.mjs → chunk-6KJY25DQ.mjs} +5 -5
- package/dist/{chunk-FP5Q67FO.mjs → chunk-AAEZP2EY.mjs} +9 -9
- 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-J3MPQ4MQ.mjs → chunk-IHADQ6J7.mjs} +2 -2
- package/dist/{chunk-J3MPQ4MQ.mjs.map → chunk-IHADQ6J7.mjs.map} +1 -1
- package/dist/{chunk-FSIXEIOB.mjs → chunk-L7FSTPGS.mjs} +2 -2
- 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-WKDAA6V2.mjs → chunk-NBF56FXB.mjs} +20 -5
- package/dist/chunk-NBF56FXB.mjs.map +1 -0
- package/dist/chunk-RKUPOYQV.mjs +28 -0
- package/dist/chunk-RKUPOYQV.mjs.map +1 -0
- package/dist/{chunk-2SKCXYLB.mjs → chunk-RL3THP3L.mjs} +54 -5
- package/dist/chunk-RL3THP3L.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-YIBV77KZ.mjs → chunk-URQELPSH.mjs} +2 -2
- package/dist/{chunk-UMUWR5XA.mjs → chunk-UWQ4EEW7.mjs} +2 -2
- package/dist/{chunk-IZBX2TEU.mjs → chunk-VQG3QWWK.mjs} +2 -2
- package/dist/{chunk-D7F7YZ7L.mjs → chunk-WA77FWAO.mjs} +8 -8
- package/dist/{chunk-35NPLKQJ.mjs → chunk-XWM2C267.mjs} +21 -105
- package/dist/chunk-XWM2C267.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-CyTLPqjP.d.mts} +38 -2
- package/dist/{client-plugins-By6MVUX-.d.ts → client-plugins-D-UgzngJ.d.ts} +38 -2
- 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-KQ2PXSIC.mjs} +8 -6
- package/dist/{devtools-XWZX6CCL.mjs.map → devtools-KQ2PXSIC.mjs.map} +1 -1
- package/dist/docs.cjs +7 -3
- package/dist/docs.cjs.map +1 -0
- package/dist/docs.mjs +8 -6
- 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 +19 -4
- 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.mjs +1 -1
- package/dist/image.cjs.map +1 -0
- package/dist/index.cjs +370 -143
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.mjs +29 -21
- 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 +178 -51
- 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 +13 -11
- package/dist/internal/client-runtime.cjs +1 -1
- package/dist/internal/client-runtime.cjs.map +1 -0
- package/dist/internal/client-runtime.mjs +2 -2
- package/dist/internal/config-runtime.cjs +48 -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 +7 -5
- 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 +6 -2
- package/dist/internal/product-telemetry-runtime.cjs.map +1 -0
- package/dist/internal/product-telemetry-runtime.mjs +6 -2
- 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.map +1 -0
- package/dist/internal/production-runtime.d.mts +8 -8
- package/dist/internal/production-runtime.d.ts +8 -8
- package/dist/markdown.cjs.map +1 -0
- package/dist/{metadata-route-8_V3UonT.d.ts → metadata-route-BpU8K9RI.d.ts} +1 -1
- package/dist/{metadata-route-CWP_HjGU.d.mts → metadata-route-D1AYgWni.d.mts} +1 -1
- 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-IITKBMUI.mjs} +4 -3
- package/dist/{nitro-EGRNOB5P.mjs.map → nitro-IITKBMUI.mjs.map} +1 -1
- package/dist/observability.cjs.map +1 -0
- package/dist/plugin.cjs +143 -50
- 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 +10 -8
- package/dist/{production-runtime-BGRH1dKG.d.mts → production-runtime-BIKA-BVT.d.mts} +2 -2
- package/dist/{production-runtime-CdmzsDax.d.ts → production-runtime-DtCUEELY.d.ts} +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-Dimb23ux.d.mts} +1 -1
- package/dist/{render-plan-0GeHiGVZ.d.ts → render-plan-rg3uiSo3.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-ColD-ChW.d.ts} +1 -1
- package/dist/{request-BCNXSXLh.d.mts → request-D5zvbU2Z.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 +221 -116
- 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 +13 -11
- package/dist/server.mjs.map +1 -1
- package/dist/{spa-router-BeyAVSc6.d.mts → spa-router-BlilYGAN.d.mts} +1 -1
- package/dist/{spa-router-COgu4txb.d.ts → spa-router-kXORcsT_.d.ts} +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-DkU2c_1B.d.ts → utils-BhvF7Hhl.d.ts} +1 -1
- package/dist/{utils-DL2VwDQl.d.mts → utils-uF32evNX.d.mts} +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 +143 -50
- 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 +10 -8
- 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 +67 -4
- 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-AAC66ILR.mjs.map +0 -1
- package/dist/chunk-BZAIS65C.mjs.map +0 -1
- package/dist/chunk-EPDIF432.mjs.map +0 -1
- package/dist/chunk-ISSFLGJ5.mjs.map +0 -1
- package/dist/chunk-WKDAA6V2.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-X4SFHKFH.mjs.map → chunk-6KJY25DQ.mjs.map} +0 -0
- /package/dist/{chunk-FP5Q67FO.mjs.map → chunk-AAEZP2EY.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-52BR7LTX.mjs.map → chunk-STSPSJUI.mjs.map} +0 -0
- /package/dist/{chunk-YIBV77KZ.mjs.map → chunk-URQELPSH.mjs.map} +0 -0
- /package/dist/{chunk-UMUWR5XA.mjs.map → chunk-UWQ4EEW7.mjs.map} +0 -0
- /package/dist/{chunk-IZBX2TEU.mjs.map → chunk-VQG3QWWK.mjs.map} +0 -0
- /package/dist/{chunk-D7F7YZ7L.mjs.map → chunk-WA77FWAO.mjs.map} +0 -0
- /package/dist/{integration-orm-LLW6WZNK.mjs.map → integration-orm-G5BPBT5X.mjs.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -917,9 +917,13 @@ function getStorage(namespace) {
|
|
|
917
917
|
const namespaced = (0, import_unstorage.prefixStorage)(globalStorage, base);
|
|
918
918
|
return {
|
|
919
919
|
...namespaced,
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
920
|
+
// Scope the wipe to the namespace instead of the whole storage, and keep
|
|
921
|
+
// the caller's base so `clear("sessions")` cannot take unrelated keys with
|
|
922
|
+
// it. Dropping the argument silently widens a targeted clear into a
|
|
923
|
+
// namespace-wide delete.
|
|
924
|
+
async clear(base2, opts) {
|
|
925
|
+
const keys = await namespaced.getKeys(base2);
|
|
926
|
+
await Promise.all(keys.map((key) => namespaced.removeItem(key, opts)));
|
|
923
927
|
}
|
|
924
928
|
};
|
|
925
929
|
}
|
|
@@ -1359,6 +1363,170 @@ var init_route_pattern = __esm({
|
|
|
1359
1363
|
}
|
|
1360
1364
|
});
|
|
1361
1365
|
|
|
1366
|
+
// src/request-origin.ts
|
|
1367
|
+
function getRequestSourceOrigin(request) {
|
|
1368
|
+
const origin = request.headers.get("origin")?.trim();
|
|
1369
|
+
if (origin) {
|
|
1370
|
+
return parseSourceOrigin(origin);
|
|
1371
|
+
}
|
|
1372
|
+
const referer = request.headers.get("referer")?.trim();
|
|
1373
|
+
if (referer) {
|
|
1374
|
+
return parseSourceOrigin(referer);
|
|
1375
|
+
}
|
|
1376
|
+
return { ok: true, origin: null };
|
|
1377
|
+
}
|
|
1378
|
+
function parseSourceOrigin(value) {
|
|
1379
|
+
if (value === "null") {
|
|
1380
|
+
return { ok: false, reason: "opaque-origin" };
|
|
1381
|
+
}
|
|
1382
|
+
try {
|
|
1383
|
+
const parsed = new URL(value);
|
|
1384
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
1385
|
+
return { ok: false, reason: "invalid-origin" };
|
|
1386
|
+
}
|
|
1387
|
+
return { ok: true, origin: parsed.origin };
|
|
1388
|
+
} catch {
|
|
1389
|
+
return { ok: false, reason: "invalid-origin" };
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
function matchesHostHeader(sourceOrigin, request) {
|
|
1393
|
+
const host = request.headers.get("host")?.trim().toLowerCase();
|
|
1394
|
+
if (!host) return false;
|
|
1395
|
+
try {
|
|
1396
|
+
const source = new URL(sourceOrigin);
|
|
1397
|
+
const target = new URL(request.url);
|
|
1398
|
+
return source.protocol === target.protocol && source.host.toLowerCase() === host;
|
|
1399
|
+
} catch {
|
|
1400
|
+
return false;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function matchesAllowedOrigin(sourceOrigin, pattern) {
|
|
1404
|
+
const source = new URL(sourceOrigin);
|
|
1405
|
+
if (!pattern.includes("*")) {
|
|
1406
|
+
return pattern.includes("://") ? source.origin === pattern : source.host === pattern;
|
|
1407
|
+
}
|
|
1408
|
+
const schemeEnd = pattern.indexOf("://");
|
|
1409
|
+
const scheme = schemeEnd === -1 ? null : pattern.slice(0, schemeEnd + 1);
|
|
1410
|
+
const hostPattern = pattern.slice(schemeEnd === -1 ? 0 : schemeEnd + 3);
|
|
1411
|
+
const [wildcardHost, port] = splitHostAndPort(hostPattern);
|
|
1412
|
+
const baseHost = wildcardHost.slice(2);
|
|
1413
|
+
if (scheme && source.protocol !== scheme) return false;
|
|
1414
|
+
if (port && getEffectivePort(source) !== port) return false;
|
|
1415
|
+
if (!port && source.port) return false;
|
|
1416
|
+
return source.hostname.endsWith(`.${baseHost}`) && source.hostname !== baseHost;
|
|
1417
|
+
}
|
|
1418
|
+
function normalizeAllowedOriginPattern(value, label) {
|
|
1419
|
+
const pattern = value.trim().toLowerCase();
|
|
1420
|
+
if (!pattern) {
|
|
1421
|
+
throw new TypeError(`${label} cannot contain empty values`);
|
|
1422
|
+
}
|
|
1423
|
+
if (pattern.includes("*")) {
|
|
1424
|
+
if (!/^(?:https?:\/\/)?\*\.[a-z0-9.-]+(?::\d+)?$/.test(pattern)) {
|
|
1425
|
+
throw new TypeError(`Invalid ${label} pattern: ${JSON.stringify(value)}`);
|
|
1426
|
+
}
|
|
1427
|
+
return pattern;
|
|
1428
|
+
}
|
|
1429
|
+
if (pattern.includes("://")) {
|
|
1430
|
+
let parsed;
|
|
1431
|
+
try {
|
|
1432
|
+
parsed = new URL(pattern);
|
|
1433
|
+
} catch {
|
|
1434
|
+
throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
|
|
1435
|
+
}
|
|
1436
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
1437
|
+
throw new TypeError(`${label} must contain origins without paths: ${JSON.stringify(value)}`);
|
|
1438
|
+
}
|
|
1439
|
+
return parsed.origin;
|
|
1440
|
+
}
|
|
1441
|
+
if (/[/@?#]/.test(pattern)) {
|
|
1442
|
+
throw new TypeError(`${label} must contain origins or hosts: ${JSON.stringify(value)}`);
|
|
1443
|
+
}
|
|
1444
|
+
try {
|
|
1445
|
+
return new URL(`http://${pattern}`).host;
|
|
1446
|
+
} catch {
|
|
1447
|
+
throw new TypeError(`Invalid ${label} value: ${JSON.stringify(value)}`);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
function splitHostAndPort(value) {
|
|
1451
|
+
const separator = value.lastIndexOf(":");
|
|
1452
|
+
if (separator === -1) return [value, null];
|
|
1453
|
+
return [value.slice(0, separator), value.slice(separator + 1)];
|
|
1454
|
+
}
|
|
1455
|
+
function getEffectivePort(url) {
|
|
1456
|
+
if (url.port) return url.port;
|
|
1457
|
+
if (url.protocol === "https:") return "443";
|
|
1458
|
+
if (url.protocol === "http:") return "80";
|
|
1459
|
+
return "";
|
|
1460
|
+
}
|
|
1461
|
+
var init_request_origin = __esm({
|
|
1462
|
+
"src/request-origin.ts"() {
|
|
1463
|
+
"use strict";
|
|
1464
|
+
__name(getRequestSourceOrigin, "getRequestSourceOrigin");
|
|
1465
|
+
__name(parseSourceOrigin, "parseSourceOrigin");
|
|
1466
|
+
__name(matchesHostHeader, "matchesHostHeader");
|
|
1467
|
+
__name(matchesAllowedOrigin, "matchesAllowedOrigin");
|
|
1468
|
+
__name(normalizeAllowedOriginPattern, "normalizeAllowedOriginPattern");
|
|
1469
|
+
__name(splitHostAndPort, "splitHostAndPort");
|
|
1470
|
+
__name(getEffectivePort, "getEffectivePort");
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
// src/integration-request-security.ts
|
|
1475
|
+
function resolveIntegrationAllowedOrigins(values, label) {
|
|
1476
|
+
return Object.freeze((values ?? []).map((value) => normalizeAllowedOriginPattern(value, label)));
|
|
1477
|
+
}
|
|
1478
|
+
function validateIntegrationRequestOrigin(request, policy = {}) {
|
|
1479
|
+
const allowedOrigins = policy.allowedOrigins ?? [];
|
|
1480
|
+
const requireOriginMetadata = policy.requireOriginMetadata ?? true;
|
|
1481
|
+
const fetchSite = request.headers.get("sec-fetch-site")?.trim().toLowerCase();
|
|
1482
|
+
const source = getRequestSourceOrigin(request);
|
|
1483
|
+
if (!source.ok) {
|
|
1484
|
+
return { ok: false, reason: source.reason };
|
|
1485
|
+
}
|
|
1486
|
+
if (source.origin === null) {
|
|
1487
|
+
if (fetchSite === "same-origin") {
|
|
1488
|
+
return { ok: true };
|
|
1489
|
+
}
|
|
1490
|
+
if (requireOriginMetadata) {
|
|
1491
|
+
return { ok: false, reason: fetchSite === "cross-site" ? "cross-site" : "missing-origin" };
|
|
1492
|
+
}
|
|
1493
|
+
return fetchSite === "cross-site" ? { ok: false, reason: "cross-site" } : { ok: true };
|
|
1494
|
+
}
|
|
1495
|
+
const requestUrl = new URL(request.url);
|
|
1496
|
+
const matchesConfiguredOrigin = allowedOrigins.some(
|
|
1497
|
+
(pattern) => matchesAllowedOrigin(source.origin, pattern)
|
|
1498
|
+
);
|
|
1499
|
+
const matchesRequest = source.origin === requestUrl.origin || matchesHostHeader(source.origin, request);
|
|
1500
|
+
if (!matchesRequest && !matchesConfiguredOrigin) {
|
|
1501
|
+
return { ok: false, reason: "cross-site" };
|
|
1502
|
+
}
|
|
1503
|
+
if (fetchSite === "cross-site" && !matchesConfiguredOrigin) {
|
|
1504
|
+
return { ok: false, reason: "cross-site" };
|
|
1505
|
+
}
|
|
1506
|
+
return { ok: true };
|
|
1507
|
+
}
|
|
1508
|
+
function describeIntegrationOriginRejection(reason) {
|
|
1509
|
+
switch (reason) {
|
|
1510
|
+
case "missing-origin":
|
|
1511
|
+
return "Request is missing same-origin metadata.";
|
|
1512
|
+
case "opaque-origin":
|
|
1513
|
+
return "Opaque origins are not allowed.";
|
|
1514
|
+
case "invalid-origin":
|
|
1515
|
+
return "Invalid request origin.";
|
|
1516
|
+
case "cross-site":
|
|
1517
|
+
return "Cross-site request was rejected.";
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
var init_integration_request_security = __esm({
|
|
1521
|
+
"src/integration-request-security.ts"() {
|
|
1522
|
+
"use strict";
|
|
1523
|
+
init_request_origin();
|
|
1524
|
+
__name(resolveIntegrationAllowedOrigins, "resolveIntegrationAllowedOrigins");
|
|
1525
|
+
__name(validateIntegrationRequestOrigin, "validateIntegrationRequestOrigin");
|
|
1526
|
+
__name(describeIntegrationOriginRejection, "describeIntegrationOriginRejection");
|
|
1527
|
+
}
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1362
1530
|
// src/integration-api.ts
|
|
1363
1531
|
function defineIntegrationAPIOperation(operation2) {
|
|
1364
1532
|
return {
|
|
@@ -4195,6 +4363,7 @@ var init_integrations = __esm({
|
|
|
4195
4363
|
"src/integrations.ts"() {
|
|
4196
4364
|
"use strict";
|
|
4197
4365
|
init_route_pattern();
|
|
4366
|
+
init_integration_request_security();
|
|
4198
4367
|
init_integration_api();
|
|
4199
4368
|
init_plugin_integration_context();
|
|
4200
4369
|
init_decode();
|
|
@@ -4660,6 +4829,29 @@ var init_markdown = __esm({
|
|
|
4660
4829
|
}
|
|
4661
4830
|
});
|
|
4662
4831
|
|
|
4832
|
+
// src/utils/runtime-env.ts
|
|
4833
|
+
function getFarmRuntimeBindings() {
|
|
4834
|
+
const runtimeBindings = globalThis.__env__;
|
|
4835
|
+
return runtimeBindings && typeof runtimeBindings === "object" ? runtimeBindings : void 0;
|
|
4836
|
+
}
|
|
4837
|
+
function readFarmEnvironmentValue(name2) {
|
|
4838
|
+
const runtimeValue = getFarmRuntimeBindings()?.[name2];
|
|
4839
|
+
if (typeof runtimeValue === "string") return runtimeValue;
|
|
4840
|
+
return typeof process !== "undefined" ? process.env?.[name2] : void 0;
|
|
4841
|
+
}
|
|
4842
|
+
function isFarmDeployedRuntime() {
|
|
4843
|
+
if (getFarmRuntimeBindings()) return true;
|
|
4844
|
+
return readFarmEnvironmentValue("NODE_ENV") === "production";
|
|
4845
|
+
}
|
|
4846
|
+
var init_runtime_env = __esm({
|
|
4847
|
+
"src/utils/runtime-env.ts"() {
|
|
4848
|
+
"use strict";
|
|
4849
|
+
__name(getFarmRuntimeBindings, "getFarmRuntimeBindings");
|
|
4850
|
+
__name(readFarmEnvironmentValue, "readFarmEnvironmentValue");
|
|
4851
|
+
__name(isFarmDeployedRuntime, "isFarmDeployedRuntime");
|
|
4852
|
+
}
|
|
4853
|
+
});
|
|
4854
|
+
|
|
4663
4855
|
// src/workflows.ts
|
|
4664
4856
|
var workflows_exports = {};
|
|
4665
4857
|
__export(workflows_exports, {
|
|
@@ -4708,7 +4900,8 @@ function resolveWorkflowsConfig(workflows) {
|
|
|
4708
4900
|
dirs,
|
|
4709
4901
|
route: normalizeWorkflowRoute(options.route || DEFAULT_FARM_WORKFLOW_ROUTE),
|
|
4710
4902
|
secretEnv: options.secretEnv || DEFAULT_FARM_WORKFLOW_SECRET_ENV,
|
|
4711
|
-
secret: options.secret
|
|
4903
|
+
secret: options.secret,
|
|
4904
|
+
allowUnsecured: options.allowUnsecured === true
|
|
4712
4905
|
};
|
|
4713
4906
|
}
|
|
4714
4907
|
async function discoverFarmWorkflows(config, options = {}) {
|
|
@@ -4834,8 +5027,11 @@ async function prepareFarmWorkflowsForNitro(config) {
|
|
|
4834
5027
|
await fs16.mkdir(generatedDir, { recursive: true });
|
|
4835
5028
|
const tasks = {};
|
|
4836
5029
|
const scheduledTasks = createScheduledTasks(workflows);
|
|
5030
|
+
const wrapperNames = resolveWorkflowWrapperFileNames(workflows.map((workflow) => workflow.id));
|
|
4837
5031
|
for (const workflow of workflows) {
|
|
4838
|
-
const wrapperPath = toPosixPath(
|
|
5032
|
+
const wrapperPath = toPosixPath(
|
|
5033
|
+
path43.join(generatedDir, `${wrapperNames.get(workflow.id)}.mjs`)
|
|
5034
|
+
);
|
|
4839
5035
|
await fs16.writeFile(wrapperPath, createNitroTaskWrapper(workflow), "utf8");
|
|
4840
5036
|
tasks[workflow.id] = {
|
|
4841
5037
|
handler: wrapperPath,
|
|
@@ -5196,8 +5392,16 @@ function readScheduledTime(payload) {
|
|
|
5196
5392
|
return payload && typeof payload === "object" && "scheduledTime" in payload ? payload.scheduledTime : void 0;
|
|
5197
5393
|
}
|
|
5198
5394
|
function verifyWorkflowSecret(request, config) {
|
|
5199
|
-
const secret = config.secret ||
|
|
5200
|
-
if (!secret)
|
|
5395
|
+
const secret = config.secret || readFarmEnvironmentValue(config.secretEnv) || "";
|
|
5396
|
+
if (!secret) {
|
|
5397
|
+
if (config.allowUnsecured === true || !isFarmDeployedRuntime()) return null;
|
|
5398
|
+
return Response.json(
|
|
5399
|
+
{
|
|
5400
|
+
error: "Workflow route requires a secret. Set the CRON_SECRET environment variable, configure workflows.secret, or set workflows.allowUnsecured to true."
|
|
5401
|
+
},
|
|
5402
|
+
{ status: 401 }
|
|
5403
|
+
);
|
|
5404
|
+
}
|
|
5201
5405
|
const authorization = request.headers.get("authorization") || "";
|
|
5202
5406
|
const bearer = authorization.match(/^Bearer\s+(.+)$/i)?.[1] || "";
|
|
5203
5407
|
const headerSecret = request.headers.get("x-farm-workflow-secret") || "";
|
|
@@ -5210,6 +5414,37 @@ function joinRoute(...parts) {
|
|
|
5210
5414
|
function trimSlashes(value) {
|
|
5211
5415
|
return value.replace(/^\/+|\/+$/g, "");
|
|
5212
5416
|
}
|
|
5417
|
+
function resolveWorkflowWrapperFileNames(ids) {
|
|
5418
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5419
|
+
for (const id of ids) {
|
|
5420
|
+
const key = safeFileName(id).toLowerCase();
|
|
5421
|
+
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
5422
|
+
}
|
|
5423
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
5424
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
5425
|
+
for (const id of ids) {
|
|
5426
|
+
const base = safeFileName(id);
|
|
5427
|
+
const key = base.toLowerCase();
|
|
5428
|
+
const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${workflowIdFingerprint(id)}` : base;
|
|
5429
|
+
const claimedBy = claimed.get(fileName.toLowerCase());
|
|
5430
|
+
if (claimedBy !== void 0) {
|
|
5431
|
+
throw new Error(
|
|
5432
|
+
`Farm workflows ${JSON.stringify(claimedBy)} and ${JSON.stringify(id)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
|
|
5433
|
+
);
|
|
5434
|
+
}
|
|
5435
|
+
claimed.set(fileName.toLowerCase(), id);
|
|
5436
|
+
resolved.set(id, fileName);
|
|
5437
|
+
}
|
|
5438
|
+
return resolved;
|
|
5439
|
+
}
|
|
5440
|
+
function workflowIdFingerprint(value) {
|
|
5441
|
+
let hash = 2166136261;
|
|
5442
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
5443
|
+
hash ^= value.charCodeAt(index);
|
|
5444
|
+
hash = Math.imul(hash, 16777619);
|
|
5445
|
+
}
|
|
5446
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
5447
|
+
}
|
|
5213
5448
|
function safeFileName(value) {
|
|
5214
5449
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "workflow";
|
|
5215
5450
|
}
|
|
@@ -5222,6 +5457,7 @@ var init_workflows = __esm({
|
|
|
5222
5457
|
"use strict";
|
|
5223
5458
|
init_server_http();
|
|
5224
5459
|
init_search_params();
|
|
5460
|
+
init_runtime_env();
|
|
5225
5461
|
init_decode();
|
|
5226
5462
|
init_utils();
|
|
5227
5463
|
init_route_pattern();
|
|
@@ -5261,6 +5497,8 @@ var init_workflows = __esm({
|
|
|
5261
5497
|
__name(verifyWorkflowSecret, "verifyWorkflowSecret");
|
|
5262
5498
|
__name(joinRoute, "joinRoute");
|
|
5263
5499
|
__name(trimSlashes, "trimSlashes");
|
|
5500
|
+
__name(resolveWorkflowWrapperFileNames, "resolveWorkflowWrapperFileNames");
|
|
5501
|
+
__name(workflowIdFingerprint, "workflowIdFingerprint");
|
|
5264
5502
|
__name(safeFileName, "safeFileName");
|
|
5265
5503
|
__name(relativePath, "relativePath");
|
|
5266
5504
|
}
|
|
@@ -5312,9 +5550,10 @@ async function prepareFarmCronForNitro(config) {
|
|
|
5312
5550
|
await fs16.rm(generatedDir, { recursive: true, force: true });
|
|
5313
5551
|
await fs16.mkdir(generatedDir, { recursive: true });
|
|
5314
5552
|
const tasks = {};
|
|
5553
|
+
const wrapperNames = resolveCronWrapperFileNames(cron.jobs.map((job) => job.name));
|
|
5315
5554
|
for (const job of cron.jobs) {
|
|
5316
5555
|
const taskName = getFarmCronTaskName(job.name);
|
|
5317
|
-
const wrapperPath = toPosixPath(path43.join(generatedDir, `${
|
|
5556
|
+
const wrapperPath = toPosixPath(path43.join(generatedDir, `${wrapperNames.get(job.name)}.mjs`));
|
|
5318
5557
|
await fs16.writeFile(wrapperPath, createNitroCronTaskWrapper(job, cron.secretEnv), "utf8");
|
|
5319
5558
|
tasks[taskName] = {
|
|
5320
5559
|
handler: wrapperPath,
|
|
@@ -5397,9 +5636,9 @@ function mergeScheduledTasks(...maps) {
|
|
|
5397
5636
|
}
|
|
5398
5637
|
function isCronRequestAuthorized(request, options = {}) {
|
|
5399
5638
|
const secretEnv = options.secretEnv || DEFAULT_FARM_CRON_SECRET_ENV;
|
|
5400
|
-
const secret = options.secret ||
|
|
5639
|
+
const secret = options.secret || readFarmEnvironmentValue(secretEnv);
|
|
5401
5640
|
if (!secret) {
|
|
5402
|
-
return options.allowUnsecured === true || !getFarmRuntimeBindings() &&
|
|
5641
|
+
return options.allowUnsecured === true || !getFarmRuntimeBindings() && readFarmEnvironmentValue("NODE_ENV") !== "production";
|
|
5403
5642
|
}
|
|
5404
5643
|
const authorization = request.headers.get("authorization") || "";
|
|
5405
5644
|
const bearer = /^Bearer (.*)$/i.exec(authorization)?.[1] || "";
|
|
@@ -5596,14 +5835,36 @@ export default defineTask({
|
|
|
5596
5835
|
});
|
|
5597
5836
|
`.trim();
|
|
5598
5837
|
}
|
|
5599
|
-
function
|
|
5600
|
-
const
|
|
5601
|
-
|
|
5602
|
-
|
|
5838
|
+
function resolveCronWrapperFileNames(names) {
|
|
5839
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5840
|
+
for (const name2 of names) {
|
|
5841
|
+
const key = safeFileName2(name2).toLowerCase();
|
|
5842
|
+
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
5843
|
+
}
|
|
5844
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
5845
|
+
const claimed = /* @__PURE__ */ new Map();
|
|
5846
|
+
for (const name2 of names) {
|
|
5847
|
+
const base = safeFileName2(name2);
|
|
5848
|
+
const key = base.toLowerCase();
|
|
5849
|
+
const fileName = (groups.get(key) ?? 0) > 1 ? `${key}-${cronNameFingerprint(name2)}` : base;
|
|
5850
|
+
const claimedBy = claimed.get(fileName.toLowerCase());
|
|
5851
|
+
if (claimedBy !== void 0) {
|
|
5852
|
+
throw new Error(
|
|
5853
|
+
`Farm cron jobs ${JSON.stringify(claimedBy)} and ${JSON.stringify(name2)} generate the same wrapper file ${JSON.stringify(`${fileName}.mjs`)}. Rename one of them.`
|
|
5854
|
+
);
|
|
5855
|
+
}
|
|
5856
|
+
claimed.set(fileName.toLowerCase(), name2);
|
|
5857
|
+
resolved.set(name2, fileName);
|
|
5858
|
+
}
|
|
5859
|
+
return resolved;
|
|
5603
5860
|
}
|
|
5604
|
-
function
|
|
5605
|
-
|
|
5606
|
-
|
|
5861
|
+
function cronNameFingerprint(value) {
|
|
5862
|
+
let hash = 2166136261;
|
|
5863
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
5864
|
+
hash ^= value.charCodeAt(index);
|
|
5865
|
+
hash = Math.imul(hash, 16777619);
|
|
5866
|
+
}
|
|
5867
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
5607
5868
|
}
|
|
5608
5869
|
function safeFileName2(value) {
|
|
5609
5870
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-") || "cron";
|
|
@@ -5613,6 +5874,7 @@ var init_cron = __esm({
|
|
|
5613
5874
|
"src/cron.ts"() {
|
|
5614
5875
|
"use strict";
|
|
5615
5876
|
init_utils();
|
|
5877
|
+
init_runtime_env();
|
|
5616
5878
|
DEFAULT_FARM_CRON_SECRET_ENV = "CRON_SECRET";
|
|
5617
5879
|
FARM_CRON_MANIFEST = "cron-manifest.json";
|
|
5618
5880
|
CRON_FIELD_RANGES = [
|
|
@@ -5643,8 +5905,8 @@ var init_cron = __esm({
|
|
|
5643
5905
|
__name(mergeTaskNames, "mergeTaskNames");
|
|
5644
5906
|
__name(getFarmCronTaskName, "getFarmCronTaskName");
|
|
5645
5907
|
__name(createNitroCronTaskWrapper, "createNitroCronTaskWrapper");
|
|
5646
|
-
__name(
|
|
5647
|
-
__name(
|
|
5908
|
+
__name(resolveCronWrapperFileNames, "resolveCronWrapperFileNames");
|
|
5909
|
+
__name(cronNameFingerprint, "cronNameFingerprint");
|
|
5648
5910
|
__name(safeFileName2, "safeFileName");
|
|
5649
5911
|
}
|
|
5650
5912
|
});
|
|
@@ -6715,7 +6977,9 @@ var init_server_fn_error = __esm({
|
|
|
6715
6977
|
|
|
6716
6978
|
// src/server-action-security.ts
|
|
6717
6979
|
function resolveServerActionsConfig(config) {
|
|
6718
|
-
const allowedOrigins = (config?.allowedOrigins ?? []).map(
|
|
6980
|
+
const allowedOrigins = (config?.allowedOrigins ?? []).map(
|
|
6981
|
+
(value) => normalizeAllowedOriginPattern(value, SERVER_ACTION_ALLOWED_ORIGINS_LABEL)
|
|
6982
|
+
);
|
|
6719
6983
|
const bodySizeLimit = parseBodySizeLimit(
|
|
6720
6984
|
config?.bodySizeLimit ?? DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT,
|
|
6721
6985
|
"serverActions.bodySizeLimit"
|
|
@@ -6734,7 +6998,7 @@ function validateServerActionRequest(request, config) {
|
|
|
6734
6998
|
);
|
|
6735
6999
|
}
|
|
6736
7000
|
const requestUrl = new URL(request.url);
|
|
6737
|
-
const sourceOrigin =
|
|
7001
|
+
const sourceOrigin = resolveSourceOrigin(request);
|
|
6738
7002
|
const fetchSite = request.headers.get("sec-fetch-site")?.trim().toLowerCase();
|
|
6739
7003
|
if (!sourceOrigin) {
|
|
6740
7004
|
if (fetchSite !== "same-origin") {
|
|
@@ -6850,103 +7114,16 @@ function getFallbackAbortController() {
|
|
|
6850
7114
|
}
|
|
6851
7115
|
return globalState2[FALLBACK_ABORT_CONTROLLER_KEY];
|
|
6852
7116
|
}
|
|
6853
|
-
function
|
|
6854
|
-
const
|
|
6855
|
-
if (!
|
|
6856
|
-
throw new
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins pattern: ${JSON.stringify(value)}`);
|
|
6861
|
-
}
|
|
6862
|
-
return pattern;
|
|
6863
|
-
}
|
|
6864
|
-
if (pattern.includes("://")) {
|
|
6865
|
-
let parsed;
|
|
6866
|
-
try {
|
|
6867
|
-
parsed = new URL(pattern);
|
|
6868
|
-
} catch {
|
|
6869
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
|
|
6870
|
-
}
|
|
6871
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
6872
|
-
throw new TypeError(
|
|
6873
|
-
`serverActions.allowedOrigins must contain origins without paths: ${JSON.stringify(value)}`
|
|
6874
|
-
);
|
|
6875
|
-
}
|
|
6876
|
-
return parsed.origin;
|
|
6877
|
-
}
|
|
6878
|
-
if (/[/@?#]/.test(pattern)) {
|
|
6879
|
-
throw new TypeError(
|
|
6880
|
-
`serverActions.allowedOrigins must contain origins or hosts: ${JSON.stringify(value)}`
|
|
7117
|
+
function resolveSourceOrigin(request) {
|
|
7118
|
+
const result = getRequestSourceOrigin(request);
|
|
7119
|
+
if (!result.ok) {
|
|
7120
|
+
throw new ServerActionRequestError(
|
|
7121
|
+
"INVALID_ORIGIN",
|
|
7122
|
+
403,
|
|
7123
|
+
result.reason === "opaque-origin" ? "Opaque origins are not allowed" : "Invalid request origin"
|
|
6881
7124
|
);
|
|
6882
7125
|
}
|
|
6883
|
-
|
|
6884
|
-
return new URL(`http://${pattern}`).host;
|
|
6885
|
-
} catch {
|
|
6886
|
-
throw new TypeError(`Invalid serverActions.allowedOrigins value: ${JSON.stringify(value)}`);
|
|
6887
|
-
}
|
|
6888
|
-
}
|
|
6889
|
-
function getRequestSourceOrigin(request) {
|
|
6890
|
-
const origin = request.headers.get("origin")?.trim();
|
|
6891
|
-
if (origin) {
|
|
6892
|
-
return parseSourceOrigin(origin);
|
|
6893
|
-
}
|
|
6894
|
-
const referer = request.headers.get("referer")?.trim();
|
|
6895
|
-
if (referer) {
|
|
6896
|
-
return parseSourceOrigin(referer);
|
|
6897
|
-
}
|
|
6898
|
-
return null;
|
|
6899
|
-
}
|
|
6900
|
-
function parseSourceOrigin(value) {
|
|
6901
|
-
if (value === "null") {
|
|
6902
|
-
throw new ServerActionRequestError("INVALID_ORIGIN", 403, "Opaque origins are not allowed");
|
|
6903
|
-
}
|
|
6904
|
-
try {
|
|
6905
|
-
const parsed = new URL(value);
|
|
6906
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
6907
|
-
throw new Error("Unsupported protocol");
|
|
6908
|
-
}
|
|
6909
|
-
return parsed.origin;
|
|
6910
|
-
} catch {
|
|
6911
|
-
throw new ServerActionRequestError("INVALID_ORIGIN", 403, "Invalid request origin");
|
|
6912
|
-
}
|
|
6913
|
-
}
|
|
6914
|
-
function matchesHostHeader(sourceOrigin, request) {
|
|
6915
|
-
const host = request.headers.get("host")?.trim().toLowerCase();
|
|
6916
|
-
if (!host) return false;
|
|
6917
|
-
try {
|
|
6918
|
-
const source = new URL(sourceOrigin);
|
|
6919
|
-
const target = new URL(request.url);
|
|
6920
|
-
return source.protocol === target.protocol && source.host.toLowerCase() === host;
|
|
6921
|
-
} catch {
|
|
6922
|
-
return false;
|
|
6923
|
-
}
|
|
6924
|
-
}
|
|
6925
|
-
function matchesAllowedOrigin(sourceOrigin, pattern) {
|
|
6926
|
-
const source = new URL(sourceOrigin);
|
|
6927
|
-
if (!pattern.includes("*")) {
|
|
6928
|
-
return pattern.includes("://") ? source.origin === pattern : source.host === pattern;
|
|
6929
|
-
}
|
|
6930
|
-
const schemeEnd = pattern.indexOf("://");
|
|
6931
|
-
const scheme = schemeEnd === -1 ? null : pattern.slice(0, schemeEnd + 1);
|
|
6932
|
-
const hostPattern = pattern.slice(schemeEnd === -1 ? 0 : schemeEnd + 3);
|
|
6933
|
-
const [wildcardHost, port] = splitHostAndPort(hostPattern);
|
|
6934
|
-
const baseHost = wildcardHost.slice(2);
|
|
6935
|
-
if (scheme && source.protocol !== scheme) return false;
|
|
6936
|
-
if (port && getEffectivePort(source) !== port) return false;
|
|
6937
|
-
if (!port && source.port) return false;
|
|
6938
|
-
return source.hostname.endsWith(`.${baseHost}`) && source.hostname !== baseHost;
|
|
6939
|
-
}
|
|
6940
|
-
function splitHostAndPort(value) {
|
|
6941
|
-
const separator = value.lastIndexOf(":");
|
|
6942
|
-
if (separator === -1) return [value, null];
|
|
6943
|
-
return [value.slice(0, separator), value.slice(separator + 1)];
|
|
6944
|
-
}
|
|
6945
|
-
function getEffectivePort(url) {
|
|
6946
|
-
if (url.port) return url.port;
|
|
6947
|
-
if (url.protocol === "https:") return "443";
|
|
6948
|
-
if (url.protocol === "http:") return "80";
|
|
6949
|
-
return "";
|
|
7126
|
+
return result.origin;
|
|
6950
7127
|
}
|
|
6951
7128
|
function validateActionId(actionId) {
|
|
6952
7129
|
if (!actionId || actionId.length > 4096 || hasControlCharacters(actionId)) {
|
|
@@ -7067,14 +7244,16 @@ function throwIfAborted2(signal) {
|
|
|
7067
7244
|
if (signal.reason !== void 0) throw signal.reason;
|
|
7068
7245
|
throw new DOMException("The operation was aborted", "AbortError");
|
|
7069
7246
|
}
|
|
7070
|
-
var import_node_async_hooks, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, _ServerActionRequestError, ServerActionRequestError, SERVER_ACTION_STORAGE_KEY, FALLBACK_ABORT_CONTROLLER_KEY, FORM_ACTION_CONTENT_TYPES, JAVASCRIPT_ACTION_CONTENT_TYPES;
|
|
7247
|
+
var import_node_async_hooks, SERVER_ACTION_ALLOWED_ORIGINS_LABEL, DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT, _ServerActionRequestError, ServerActionRequestError, SERVER_ACTION_STORAGE_KEY, FALLBACK_ABORT_CONTROLLER_KEY, FORM_ACTION_CONTENT_TYPES, JAVASCRIPT_ACTION_CONTENT_TYPES;
|
|
7071
7248
|
var init_server_action_security = __esm({
|
|
7072
7249
|
"src/server-action-security.ts"() {
|
|
7073
7250
|
"use strict";
|
|
7074
7251
|
import_node_async_hooks = require("async_hooks");
|
|
7075
7252
|
init_cache_invalidation();
|
|
7253
|
+
init_request_origin();
|
|
7076
7254
|
init_server_fn_error();
|
|
7077
7255
|
init_server_http();
|
|
7256
|
+
SERVER_ACTION_ALLOWED_ORIGINS_LABEL = "serverActions.allowedOrigins";
|
|
7078
7257
|
DEFAULT_SERVER_ACTION_BODY_SIZE_LIMIT = 1e6;
|
|
7079
7258
|
_ServerActionRequestError = class _ServerActionRequestError extends Error {
|
|
7080
7259
|
constructor(code, status, message) {
|
|
@@ -7115,13 +7294,7 @@ var init_server_action_security = __esm({
|
|
|
7115
7294
|
});
|
|
7116
7295
|
__name(getServerActionStorage, "getServerActionStorage");
|
|
7117
7296
|
__name(getFallbackAbortController, "getFallbackAbortController");
|
|
7118
|
-
__name(
|
|
7119
|
-
__name(getRequestSourceOrigin, "getRequestSourceOrigin");
|
|
7120
|
-
__name(parseSourceOrigin, "parseSourceOrigin");
|
|
7121
|
-
__name(matchesHostHeader, "matchesHostHeader");
|
|
7122
|
-
__name(matchesAllowedOrigin, "matchesAllowedOrigin");
|
|
7123
|
-
__name(splitHostAndPort, "splitHostAndPort");
|
|
7124
|
-
__name(getEffectivePort, "getEffectivePort");
|
|
7297
|
+
__name(resolveSourceOrigin, "resolveSourceOrigin");
|
|
7125
7298
|
__name(validateActionId, "validateActionId");
|
|
7126
7299
|
__name(hasControlCharacters, "hasControlCharacters");
|
|
7127
7300
|
__name(getSupportedContentType, "getSupportedContentType");
|
|
@@ -17012,7 +17185,7 @@ var init_server3 = __esm({
|
|
|
17012
17185
|
var version;
|
|
17013
17186
|
var init_package = __esm({
|
|
17014
17187
|
"package.json"() {
|
|
17015
|
-
version = "0.1.0-beta.
|
|
17188
|
+
version = "0.1.0-beta.98";
|
|
17016
17189
|
}
|
|
17017
17190
|
});
|
|
17018
17191
|
|
|
@@ -25065,10 +25238,11 @@ function createFarmImageHandler(config, options) {
|
|
|
25065
25238
|
"quality"
|
|
25066
25239
|
);
|
|
25067
25240
|
const accept = request.headers.get("accept") ?? "";
|
|
25241
|
+
const negotiatedFormat = selectOutputFormat(accept, config.formats) ?? "";
|
|
25068
25242
|
const cacheKey = `${sourceUrl.href}
|
|
25069
25243
|
${width}
|
|
25070
25244
|
${quality}
|
|
25071
|
-
${
|
|
25245
|
+
${negotiatedFormat}`;
|
|
25072
25246
|
let optimized = cache.get(cacheKey);
|
|
25073
25247
|
if (!optimized) {
|
|
25074
25248
|
const fetchedSource = await fetchImageSource(
|
|
@@ -25095,7 +25269,8 @@ ${accept}`;
|
|
|
25095
25269
|
quality,
|
|
25096
25270
|
accept,
|
|
25097
25271
|
formats: config.formats,
|
|
25098
|
-
signal: request.signal
|
|
25272
|
+
signal: request.signal,
|
|
25273
|
+
maximumResponseBody: config.maximumResponseBody
|
|
25099
25274
|
});
|
|
25100
25275
|
throwIfAborted3(request.signal);
|
|
25101
25276
|
validateTransformedResult(result, config);
|
|
@@ -25426,7 +25601,7 @@ function throwIfAborted3(signal) {
|
|
|
25426
25601
|
function isAbortError(error) {
|
|
25427
25602
|
return error instanceof Error && error.name === "AbortError";
|
|
25428
25603
|
}
|
|
25429
|
-
var _FarmImageRequestError, FarmImageRequestError, _FarmImageMemoryCache, FarmImageMemoryCache;
|
|
25604
|
+
var _FarmImageRequestError, FarmImageRequestError, DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT, _FarmImageMemoryCache, FarmImageMemoryCache;
|
|
25430
25605
|
var init_image_server = __esm({
|
|
25431
25606
|
"src/image-server.ts"() {
|
|
25432
25607
|
"use strict";
|
|
@@ -25442,6 +25617,7 @@ var init_image_server = __esm({
|
|
|
25442
25617
|
__name(_FarmImageRequestError, "FarmImageRequestError");
|
|
25443
25618
|
FarmImageRequestError = _FarmImageRequestError;
|
|
25444
25619
|
__name(createFarmImageHandler, "createFarmImageHandler");
|
|
25620
|
+
DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT = 10 * 1024 * 1024;
|
|
25445
25621
|
__name(selectOutputFormat, "selectOutputFormat");
|
|
25446
25622
|
__name(isPrivateImageAddress, "isPrivateImageAddress");
|
|
25447
25623
|
__name(parseAllowedInteger, "parseAllowedInteger");
|
|
@@ -38279,6 +38455,7 @@ __export(src_exports, {
|
|
|
38279
38455
|
defineStorageClient: () => defineStorageClient,
|
|
38280
38456
|
defineTask: () => defineTask,
|
|
38281
38457
|
defineWorkflow: () => defineWorkflow,
|
|
38458
|
+
describeIntegrationOriginRejection: () => describeIntegrationOriginRejection,
|
|
38282
38459
|
discoverFarmDocsPages: () => discoverFarmDocsPages,
|
|
38283
38460
|
discoverFarmWorkflows: () => discoverFarmWorkflows,
|
|
38284
38461
|
dispatchIntegrationRequest: () => dispatchIntegrationRequest,
|
|
@@ -38475,6 +38652,7 @@ __export(src_exports, {
|
|
|
38475
38652
|
resolveFarmRouteRuleRuntimeConfig: () => resolveFarmRouteRuleRuntimeConfig,
|
|
38476
38653
|
resolveFarmRouteRuntimeConfig: () => resolveFarmRouteRuntimeConfig,
|
|
38477
38654
|
resolveFarmThemeConfig: () => resolveFarmThemeConfig,
|
|
38655
|
+
resolveIntegrationAllowedOrigins: () => resolveIntegrationAllowedOrigins,
|
|
38478
38656
|
resolveIntegrationOrmRuntimeClient: () => resolveIntegrationOrmRuntimeClient,
|
|
38479
38657
|
resolveIntegrationPlugins: () => resolveIntegrationPlugins,
|
|
38480
38658
|
resolveMarkdownConfig: () => resolveMarkdownConfig,
|
|
@@ -38535,6 +38713,7 @@ __export(src_exports, {
|
|
|
38535
38713
|
useServerFn: () => useServerFn,
|
|
38536
38714
|
useServerQuery: () => useServerQuery,
|
|
38537
38715
|
useTheme: () => useTheme,
|
|
38716
|
+
validateIntegrationRequestOrigin: () => validateIntegrationRequestOrigin,
|
|
38538
38717
|
validateServerActionRequest: () => validateServerActionRequest,
|
|
38539
38718
|
vercelBlobStorage: () => vercelBlobStorage,
|
|
38540
38719
|
vercelKVStorage: () => vercelKVStorage,
|
|
@@ -40247,6 +40426,7 @@ var _FarmClientDataCache = class _FarmClientDataCache {
|
|
|
40247
40426
|
const watched = /* @__PURE__ */ new Set();
|
|
40248
40427
|
for (const key of this.listeners.keys()) watched.add(this.resolveKey(key));
|
|
40249
40428
|
let remaining = false;
|
|
40429
|
+
const swept = /* @__PURE__ */ new Set();
|
|
40250
40430
|
for (const [key, entry] of this.entries) {
|
|
40251
40431
|
if (entry.gcAt === void 0) continue;
|
|
40252
40432
|
if (now2 < entry.gcAt || entry.fetching || this.inflight.has(key) || watched.has(key)) {
|
|
@@ -40255,9 +40435,28 @@ var _FarmClientDataCache = class _FarmClientDataCache {
|
|
|
40255
40435
|
}
|
|
40256
40436
|
this.entries.delete(key);
|
|
40257
40437
|
this.persistence?.onDelete(key);
|
|
40438
|
+
swept.add(key);
|
|
40258
40439
|
}
|
|
40440
|
+
if (swept.size > 0) this.sweepEntryMetadata(swept);
|
|
40259
40441
|
if (remaining) this.scheduleGcSweep();
|
|
40260
40442
|
}
|
|
40443
|
+
/**
|
|
40444
|
+
* Entry eviction alone leaves the per-key metadata behind. `invalidatedAt`
|
|
40445
|
+
* marks and provisional aliases are created per query invocation, so with
|
|
40446
|
+
* dynamic keys they accumulate for the lifetime of the page even though the
|
|
40447
|
+
* entries they describe are long gone.
|
|
40448
|
+
*/
|
|
40449
|
+
sweepEntryMetadata(swept) {
|
|
40450
|
+
for (const key of swept) this.invalidatedAt.delete(key);
|
|
40451
|
+
for (const [alias, target] of this.aliases) {
|
|
40452
|
+
if (this.entries.has(alias) || this.listeners.has(alias)) continue;
|
|
40453
|
+
const resolved = this.resolveKey(target);
|
|
40454
|
+
if (!swept.has(resolved)) continue;
|
|
40455
|
+
if (this.entries.has(resolved) || this.listeners.has(resolved)) continue;
|
|
40456
|
+
this.aliases.delete(alias);
|
|
40457
|
+
this.invalidatedAt.delete(alias);
|
|
40458
|
+
}
|
|
40459
|
+
}
|
|
40261
40460
|
emit(key, event) {
|
|
40262
40461
|
this.notifyListeners(key, event);
|
|
40263
40462
|
for (const [alias, target] of this.aliases) {
|
|
@@ -40268,7 +40467,12 @@ var _FarmClientDataCache = class _FarmClientDataCache {
|
|
|
40268
40467
|
}
|
|
40269
40468
|
notifyListeners(key, event) {
|
|
40270
40469
|
for (const listener of this.listeners.get(key) ?? []) {
|
|
40271
|
-
|
|
40470
|
+
try {
|
|
40471
|
+
listener(event);
|
|
40472
|
+
} catch (error) {
|
|
40473
|
+
const detail = error instanceof Error ? error.stack ?? error.message : String(error);
|
|
40474
|
+
console.warn(`[farm:client-cache] cache listener failed: ${detail}`);
|
|
40475
|
+
}
|
|
40272
40476
|
}
|
|
40273
40477
|
}
|
|
40274
40478
|
};
|
|
@@ -53922,29 +54126,36 @@ __name(isFormData4, "isFormData");
|
|
|
53922
54126
|
// src/cache-invalidation-broadcast.ts
|
|
53923
54127
|
init_cache_invalidation();
|
|
53924
54128
|
var FARM_CACHE_INVALIDATION_CHANNEL = "farm:cache-invalidation";
|
|
53925
|
-
var
|
|
54129
|
+
var FARM_CACHE_INVALIDATION_BRIDGE = /* @__PURE__ */ Symbol.for("farm.cacheInvalidationBridge");
|
|
54130
|
+
var bridgeGlobal = globalThis;
|
|
53926
54131
|
function enableCrossTabCacheInvalidation(options = {}) {
|
|
53927
54132
|
if (typeof BroadcastChannel !== "function") return () => {
|
|
53928
54133
|
};
|
|
53929
54134
|
const channelName = options.channelName ?? FARM_CACHE_INVALIDATION_CHANNEL;
|
|
53930
|
-
|
|
53931
|
-
|
|
54135
|
+
const existing = bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE];
|
|
54136
|
+
let bridge;
|
|
54137
|
+
if (existing) {
|
|
54138
|
+
if (existing.channelName !== channelName) {
|
|
53932
54139
|
throw new Error(
|
|
53933
|
-
`Cross-tab cache invalidation is already enabled on channel "${
|
|
54140
|
+
`Cross-tab cache invalidation is already enabled on channel "${existing.channelName}".`
|
|
53934
54141
|
);
|
|
53935
54142
|
}
|
|
53936
|
-
|
|
54143
|
+
existing.refCount += 1;
|
|
54144
|
+
bridge = existing;
|
|
53937
54145
|
} else {
|
|
53938
|
-
|
|
54146
|
+
bridge = createBridge(channelName);
|
|
54147
|
+
bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] = bridge;
|
|
53939
54148
|
}
|
|
53940
54149
|
let disposed = false;
|
|
53941
54150
|
return () => {
|
|
53942
|
-
if (disposed
|
|
54151
|
+
if (disposed) return;
|
|
53943
54152
|
disposed = true;
|
|
53944
|
-
|
|
53945
|
-
if (
|
|
53946
|
-
|
|
53947
|
-
|
|
54153
|
+
bridge.refCount -= 1;
|
|
54154
|
+
if (bridge.refCount === 0) {
|
|
54155
|
+
bridge.teardown();
|
|
54156
|
+
if (bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] === bridge) {
|
|
54157
|
+
bridgeGlobal[FARM_CACHE_INVALIDATION_BRIDGE] = void 0;
|
|
54158
|
+
}
|
|
53948
54159
|
}
|
|
53949
54160
|
};
|
|
53950
54161
|
}
|
|
@@ -54152,7 +54363,7 @@ function createSink(engine) {
|
|
|
54152
54363
|
scheduleFlush(engine);
|
|
54153
54364
|
},
|
|
54154
54365
|
onClear() {
|
|
54155
|
-
if (engine.disabled) return;
|
|
54366
|
+
if (engine.disabled || engine.clearing) return;
|
|
54156
54367
|
engine.pendingSets.clear();
|
|
54157
54368
|
engine.pendingDeletes.clear();
|
|
54158
54369
|
void engine.adapter.clear().catch((error) => disableEngine(engine, error));
|
|
@@ -54173,7 +54384,8 @@ function initPersistedClientCache(adapter, options = {}) {
|
|
|
54173
54384
|
pendingDeletes: /* @__PURE__ */ new Set(),
|
|
54174
54385
|
flushTimer: void 0,
|
|
54175
54386
|
hydrating: false,
|
|
54176
|
-
disabled: false
|
|
54387
|
+
disabled: false,
|
|
54388
|
+
clearing: false
|
|
54177
54389
|
};
|
|
54178
54390
|
activeEngine = engine;
|
|
54179
54391
|
engine.cache.attachPersistence(createSink(engine));
|
|
@@ -54188,6 +54400,7 @@ function disposePersistedClientCache() {
|
|
|
54188
54400
|
const engine = activeEngine;
|
|
54189
54401
|
if (!engine) return;
|
|
54190
54402
|
activeEngine = void 0;
|
|
54403
|
+
engine.disabled = true;
|
|
54191
54404
|
engine.cache.attachPersistence(void 0);
|
|
54192
54405
|
if (engine.flushTimer !== void 0) {
|
|
54193
54406
|
clearTimeout(engine.flushTimer);
|
|
@@ -54199,7 +54412,18 @@ function disposePersistedClientCache() {
|
|
|
54199
54412
|
__name(disposePersistedClientCache, "disposePersistedClientCache");
|
|
54200
54413
|
async function clearPersistedCache() {
|
|
54201
54414
|
const engine = activeEngine;
|
|
54202
|
-
if (!engine)
|
|
54415
|
+
if (!engine) {
|
|
54416
|
+
getFarmClientDataCache().clear();
|
|
54417
|
+
return;
|
|
54418
|
+
}
|
|
54419
|
+
engine.pendingSets.clear();
|
|
54420
|
+
engine.pendingDeletes.clear();
|
|
54421
|
+
engine.clearing = true;
|
|
54422
|
+
try {
|
|
54423
|
+
engine.cache.clear();
|
|
54424
|
+
} finally {
|
|
54425
|
+
engine.clearing = false;
|
|
54426
|
+
}
|
|
54203
54427
|
engine.pendingSets.clear();
|
|
54204
54428
|
engine.pendingDeletes.clear();
|
|
54205
54429
|
try {
|
|
@@ -57672,6 +57896,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
57672
57896
|
defineStorageClient,
|
|
57673
57897
|
defineTask,
|
|
57674
57898
|
defineWorkflow,
|
|
57899
|
+
describeIntegrationOriginRejection,
|
|
57675
57900
|
discoverFarmDocsPages,
|
|
57676
57901
|
discoverFarmWorkflows,
|
|
57677
57902
|
dispatchIntegrationRequest,
|
|
@@ -57868,6 +58093,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
57868
58093
|
resolveFarmRouteRuleRuntimeConfig,
|
|
57869
58094
|
resolveFarmRouteRuntimeConfig,
|
|
57870
58095
|
resolveFarmThemeConfig,
|
|
58096
|
+
resolveIntegrationAllowedOrigins,
|
|
57871
58097
|
resolveIntegrationOrmRuntimeClient,
|
|
57872
58098
|
resolveIntegrationPlugins,
|
|
57873
58099
|
resolveMarkdownConfig,
|
|
@@ -57928,6 +58154,7 @@ __name(decodeCookiePart, "decodeCookiePart");
|
|
|
57928
58154
|
useServerFn,
|
|
57929
58155
|
useServerQuery,
|
|
57930
58156
|
useTheme,
|
|
58157
|
+
validateIntegrationRequestOrigin,
|
|
57931
58158
|
validateServerActionRequest,
|
|
57932
58159
|
vercelBlobStorage,
|
|
57933
58160
|
vercelKVStorage,
|