@farm.js/core 0.1.0-beta.11 → 0.1.0-beta.13
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/{chunk-5EVQFRL2.mjs → chunk-3WIRO3N7.mjs} +2 -2
- package/dist/chunk-3WIRO3N7.mjs.map +1 -0
- package/dist/chunk-53MVSX3R.mjs +168 -0
- package/dist/chunk-53MVSX3R.mjs.map +1 -0
- package/dist/{chunk-AW6I64AP.mjs → chunk-6ZXIQSXE.mjs} +16 -1
- package/dist/chunk-6ZXIQSXE.mjs.map +1 -0
- package/dist/chunk-7ZVN3YZI.mjs +333 -0
- package/dist/chunk-7ZVN3YZI.mjs.map +1 -0
- package/dist/{chunk-7N62DNSO.mjs → chunk-H3TE3LOV.mjs} +2 -2
- package/dist/{chunk-QTZZ2ISQ.mjs → chunk-KLA67WKG.mjs} +1 -1
- package/dist/chunk-KLA67WKG.mjs.map +1 -0
- package/dist/{chunk-K5ZTUF22.mjs → chunk-L2PE36GQ.mjs} +7 -3
- package/dist/chunk-L2PE36GQ.mjs.map +1 -0
- package/dist/{chunk-4LND3PXF.mjs → chunk-OPHK6OJN.mjs} +513 -48
- package/dist/chunk-OPHK6OJN.mjs.map +1 -0
- package/dist/chunk-USLFXFFH.mjs +46 -0
- package/dist/chunk-USLFXFFH.mjs.map +1 -0
- package/dist/{chunk-4677KXB7.mjs → chunk-VSDZEB5M.mjs} +368 -103
- package/dist/chunk-VSDZEB5M.mjs.map +1 -0
- package/dist/{chunk-77BOAQHI.mjs → chunk-Z3YG4OZT.mjs} +725 -147
- package/dist/chunk-Z3YG4OZT.mjs.map +1 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/{devtools-A22KUJZT.mjs → devtools-GAZ7F3KL.mjs} +4 -3
- package/dist/{devtools-A22KUJZT.mjs.map → devtools-GAZ7F3KL.mjs.map} +1 -1
- package/dist/docs.cjs +622 -124
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.mjs +5 -3
- package/dist/font.cjs +19 -2
- package/dist/font.cjs.map +1 -1
- package/dist/font.mjs +7 -3
- package/dist/index.cjs +2206 -680
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +27 -19
- package/dist/index.mjs.map +1 -1
- package/dist/internal/build-runtime.cjs +2033 -516
- package/dist/internal/build-runtime.cjs.map +1 -1
- package/dist/internal/build-runtime.mjs +13 -10
- package/dist/internal/client-runtime.cjs +169 -2
- package/dist/internal/client-runtime.cjs.map +1 -1
- package/dist/internal/client-runtime.mjs +170 -2
- package/dist/internal/client-runtime.mjs.map +1 -1
- package/dist/internal/config-runtime.cjs +22 -0
- package/dist/internal/config-runtime.cjs.map +1 -1
- package/dist/internal/config-runtime.mjs +3 -2
- package/dist/internal/metadata-image-runtime.cjs +199 -0
- package/dist/internal/metadata-image-runtime.cjs.map +1 -0
- package/dist/internal/metadata-image-runtime.mjs +8 -0
- package/dist/internal/metadata-image-runtime.mjs.map +1 -0
- package/dist/internal/production-runtime.cjs +310 -0
- package/dist/internal/production-runtime.cjs.map +1 -1
- package/dist/internal/production-runtime.mjs +10 -0
- package/dist/internal/production-runtime.mjs.map +1 -1
- package/dist/navigation.cjs.map +1 -1
- package/dist/navigation.mjs +2 -2
- package/dist/plugin.cjs +1521 -339
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +9 -5
- package/dist/server.cjs +1634 -410
- package/dist/server.cjs.map +1 -1
- package/dist/server.mjs +17 -19
- package/dist/server.mjs.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +1575 -349
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +9 -5
- package/package.json +10 -1
- package/dist/after.d.mts +0 -25
- package/dist/after.d.ts +0 -25
- package/dist/agent-runtime.d.mts +0 -94
- package/dist/agent-runtime.d.ts +0 -94
- package/dist/api/route-manager.d.mts +0 -66
- package/dist/api/route-manager.d.ts +0 -66
- package/dist/api/runtime.d.mts +0 -3
- package/dist/api/runtime.d.ts +0 -3
- package/dist/api.d.mts +0 -48
- package/dist/api.d.ts +0 -48
- package/dist/app-BNE2FoZ4.d.mts +0 -302
- package/dist/app-DRGUmJ3s.d.ts +0 -302
- package/dist/app-markdown.d.mts +0 -22
- package/dist/app-markdown.d.ts +0 -22
- package/dist/cache.d.mts +0 -192
- package/dist/cache.d.ts +0 -192
- package/dist/chunk-4677KXB7.mjs.map +0 -1
- package/dist/chunk-4LND3PXF.mjs.map +0 -1
- package/dist/chunk-5EVQFRL2.mjs.map +0 -1
- package/dist/chunk-77BOAQHI.mjs.map +0 -1
- package/dist/chunk-AW6I64AP.mjs.map +0 -1
- package/dist/chunk-K5ZTUF22.mjs.map +0 -1
- package/dist/chunk-QM746KUO.mjs +0 -56
- package/dist/chunk-QM746KUO.mjs.map +0 -1
- package/dist/chunk-QTZZ2ISQ.mjs.map +0 -1
- package/dist/client-BT1mFQas.d.mts +0 -447
- package/dist/client-Nn0q4eO4.d.ts +0 -447
- package/dist/client-cache-CIlyBlmx.d.ts +0 -6
- package/dist/client-cache-D-EZ7XVW.d.mts +0 -6
- package/dist/client-plugins-Bc5jHcNr.d.ts +0 -1927
- package/dist/client-plugins-jsk-ZLzJ.d.mts +0 -1927
- package/dist/client-plugins.d.mts +0 -22
- package/dist/client-plugins.d.ts +0 -22
- package/dist/client.d.mts +0 -447
- package/dist/client.d.ts +0 -447
- package/dist/config.d.mts +0 -29
- package/dist/config.d.ts +0 -29
- package/dist/cron.d.mts +0 -78
- package/dist/cron.d.ts +0 -78
- package/dist/deferred.d.mts +0 -42
- package/dist/deferred.d.ts +0 -42
- package/dist/deployment.d.mts +0 -34
- package/dist/deployment.d.ts +0 -34
- package/dist/docs.d.mts +0 -69
- package/dist/docs.d.ts +0 -69
- package/dist/env-types.d.mts +0 -12
- package/dist/env-types.d.ts +0 -12
- package/dist/env.d.mts +0 -45
- package/dist/env.d.ts +0 -45
- package/dist/environment/vite.d.mts +0 -22
- package/dist/environment/vite.d.ts +0 -22
- package/dist/environment.d.mts +0 -18
- package/dist/environment.d.ts +0 -18
- package/dist/font.d.mts +0 -70
- package/dist/font.d.ts +0 -70
- package/dist/headers.d.mts +0 -22
- package/dist/headers.d.ts +0 -22
- package/dist/i18n/client.d.mts +0 -32
- package/dist/i18n/client.d.ts +0 -32
- package/dist/i18n/index.d.mts +0 -20
- package/dist/i18n/index.d.ts +0 -20
- package/dist/i18n/server.d.mts +0 -30
- package/dist/i18n/server.d.ts +0 -30
- package/dist/image/server.d.mts +0 -37
- package/dist/image/server.d.ts +0 -37
- package/dist/image/sharp.d.mts +0 -7
- package/dist/image/sharp.d.ts +0 -7
- package/dist/image-config-Duob7wER.d.mts +0 -50
- package/dist/image-config-Duob7wER.d.ts +0 -50
- package/dist/image.d.mts +0 -39
- package/dist/image.d.ts +0 -39
- package/dist/index.d.mts +0 -455
- package/dist/index.d.ts +0 -455
- package/dist/integration-api-CHT2OKAf.d.mts +0 -93
- package/dist/integration-api-CHT2OKAf.d.ts +0 -93
- package/dist/integrations.d.mts +0 -22
- package/dist/integrations.d.ts +0 -22
- package/dist/internal/build-runtime.d.mts +0 -39
- package/dist/internal/build-runtime.d.ts +0 -39
- package/dist/internal/client-runtime.d.mts +0 -2
- package/dist/internal/client-runtime.d.ts +0 -2
- package/dist/internal/config-runtime.d.mts +0 -39
- package/dist/internal/config-runtime.d.ts +0 -39
- package/dist/internal/production-node-env.d.mts +0 -12
- package/dist/internal/production-node-env.d.ts +0 -12
- package/dist/internal/production-runtime.d.mts +0 -41
- package/dist/internal/production-runtime.d.ts +0 -41
- package/dist/markdown.d.mts +0 -60
- package/dist/markdown.d.ts +0 -60
- package/dist/metadata-7ffpT3jr.d.mts +0 -22
- package/dist/metadata-JHn-8eht.d.ts +0 -22
- package/dist/middleware.d.mts +0 -164
- package/dist/middleware.d.ts +0 -164
- package/dist/navigation-errors-Dvwpzaer.d.mts +0 -13
- package/dist/navigation-errors-Dvwpzaer.d.ts +0 -13
- package/dist/navigation.d.mts +0 -14
- package/dist/navigation.d.ts +0 -14
- package/dist/observability.d.mts +0 -335
- package/dist/observability.d.ts +0 -335
- package/dist/params-BALtrRim.d.ts +0 -15
- package/dist/params-ry-lxqmy.d.mts +0 -15
- package/dist/plugin-BJDf43dc.d.mts +0 -165
- package/dist/plugin-BJDf43dc.d.ts +0 -165
- package/dist/plugin.d.mts +0 -22
- package/dist/plugin.d.ts +0 -22
- package/dist/production-runtime-9KG7GuvW.d.ts +0 -79
- package/dist/production-runtime-B-fweKts.d.mts +0 -79
- package/dist/production-runtime-C_B79w2P.d.mts +0 -28
- package/dist/production-runtime-DDEM1D2q.d.ts +0 -28
- package/dist/query/client.d.mts +0 -61
- package/dist/query/client.d.ts +0 -61
- package/dist/query/index.d.mts +0 -90
- package/dist/query/index.d.ts +0 -90
- package/dist/query/parsers.d.mts +0 -25
- package/dist/query/parsers.d.ts +0 -25
- package/dist/query/server.d.mts +0 -55
- package/dist/query/server.d.ts +0 -55
- package/dist/request-Dsq4kGW0.d.mts +0 -6
- package/dist/request-udtobOLv.d.ts +0 -6
- package/dist/request.d.mts +0 -2
- package/dist/request.d.ts +0 -2
- package/dist/resolver-DJqjLMg_.d.mts +0 -14
- package/dist/resolver-IH4RmPEl.d.ts +0 -14
- package/dist/route-runtime-DoOHzCAD.d.mts +0 -38
- package/dist/route-runtime-DoOHzCAD.d.ts +0 -38
- package/dist/router.d.mts +0 -36
- package/dist/router.d.ts +0 -36
- package/dist/routes.d.mts +0 -224
- package/dist/routes.d.ts +0 -224
- package/dist/runtime-9nQjVM7X.d.mts +0 -206
- package/dist/runtime-Cxpq6xZN.d.mts +0 -27
- package/dist/runtime-DgeS2skB.d.ts +0 -206
- package/dist/runtime-bv63eUiO.d.ts +0 -27
- package/dist/server-action-security.d.mts +0 -43
- package/dist/server-action-security.d.ts +0 -43
- package/dist/server-fn-client.d.mts +0 -32
- package/dist/server-fn-client.d.ts +0 -32
- package/dist/server-fn.d.mts +0 -93
- package/dist/server-fn.d.ts +0 -93
- package/dist/server-plugins.d.mts +0 -55
- package/dist/server-plugins.d.ts +0 -55
- package/dist/server-query-client.d.mts +0 -50
- package/dist/server-query-client.d.ts +0 -50
- package/dist/server-query.d.mts +0 -36
- package/dist/server-query.d.ts +0 -36
- package/dist/server.d.mts +0 -48
- package/dist/server.d.ts +0 -48
- package/dist/storage.d.mts +0 -52
- package/dist/storage.d.ts +0 -52
- package/dist/testing.d.mts +0 -101
- package/dist/testing.d.ts +0 -101
- package/dist/transport-BmbGTXA5.d.mts +0 -49
- package/dist/transport-BmbGTXA5.d.ts +0 -49
- package/dist/types-BMxWr97v.d.mts +0 -81
- package/dist/types-BMxWr97v.d.ts +0 -81
- package/dist/types-C9N-nk5R.d.mts +0 -53
- package/dist/types-C9N-nk5R.d.ts +0 -53
- package/dist/types-D1A6-XvH.d.mts +0 -73
- package/dist/types-D1A6-XvH.d.ts +0 -73
- package/dist/utils-CA0z0c-2.d.ts +0 -23
- package/dist/utils-mYVkSOt2.d.mts +0 -23
- package/dist/version.d.mts +0 -3
- package/dist/version.d.ts +0 -3
- package/dist/vite.d.mts +0 -22
- package/dist/vite.d.ts +0 -22
- package/dist/workflows.d.mts +0 -110
- package/dist/workflows.d.ts +0 -110
- /package/dist/{chunk-7N62DNSO.mjs.map → chunk-H3TE3LOV.mjs.map} +0 -0
|
@@ -5,13 +5,14 @@ import {
|
|
|
5
5
|
loadConfig,
|
|
6
6
|
resolveConfig,
|
|
7
7
|
resolveDeployConfig
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-L2PE36GQ.mjs";
|
|
9
9
|
import "../chunk-UVCIEUJC.mjs";
|
|
10
10
|
import "../chunk-RQ633A5I.mjs";
|
|
11
11
|
import "../chunk-I4CUBGVF.mjs";
|
|
12
|
+
import "../chunk-7MABZJIM.mjs";
|
|
12
13
|
import "../chunk-YW7OBE6Q.mjs";
|
|
13
14
|
import "../chunk-74YTBPTY.mjs";
|
|
14
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-7ZVN3YZI.mjs";
|
|
15
16
|
import "../chunk-GY2STC2S.mjs";
|
|
16
17
|
import "../chunk-UB5UOSHB.mjs";
|
|
17
18
|
import "../chunk-ZVWA4ZQ3.mjs";
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/metadata-image.ts
|
|
32
|
+
var metadata_image_exports = {};
|
|
33
|
+
__export(metadata_image_exports, {
|
|
34
|
+
createFarmMetadataImageResponse: () => createFarmMetadataImageResponse
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(metadata_image_exports);
|
|
37
|
+
var import_react = __toESM(require("react"));
|
|
38
|
+
var import_server = require("react-dom/server");
|
|
39
|
+
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
40
|
+
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
41
|
+
var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
|
|
42
|
+
function isResponse(value) {
|
|
43
|
+
return typeof Response !== "undefined" && (value instanceof Response || Boolean(
|
|
44
|
+
value && typeof value === "object" && typeof value.arrayBuffer === "function" && value.headers
|
|
45
|
+
));
|
|
46
|
+
}
|
|
47
|
+
__name(isResponse, "isResponse");
|
|
48
|
+
function isThenable(value) {
|
|
49
|
+
return Boolean(
|
|
50
|
+
value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
__name(isThenable, "isThenable");
|
|
54
|
+
async function prepareMetadataImageNode(node) {
|
|
55
|
+
if (isThenable(node)) {
|
|
56
|
+
return prepareMetadataImageNode(await node);
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(node)) {
|
|
59
|
+
return Promise.all(node.map((child) => prepareMetadataImageNode(child)));
|
|
60
|
+
}
|
|
61
|
+
if (!import_react.default.isValidElement(node)) {
|
|
62
|
+
return node;
|
|
63
|
+
}
|
|
64
|
+
const element = node;
|
|
65
|
+
const type = element.type;
|
|
66
|
+
const props = element.props || {};
|
|
67
|
+
if (typeof type === "function") {
|
|
68
|
+
if (type.prototype?.isReactComponent) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"Metadata image components must be stateless function components; React class components are not supported."
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return prepareMetadataImageNode(await type(props));
|
|
74
|
+
}
|
|
75
|
+
if (type && typeof type === "object") {
|
|
76
|
+
if (type.$$typeof === REACT_MEMO_TYPE) {
|
|
77
|
+
return prepareMetadataImageNode(import_react.default.createElement(type.type, props));
|
|
78
|
+
}
|
|
79
|
+
if (type.$$typeof === REACT_FORWARD_REF_TYPE) {
|
|
80
|
+
return prepareMetadataImageNode(await type.render(props, null));
|
|
81
|
+
}
|
|
82
|
+
if (type.$$typeof === REACT_LAZY_TYPE) {
|
|
83
|
+
return prepareMetadataImageNode(import_react.default.createElement(type._init(type._payload), props));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const preparedChildren = await prepareMetadataImageNode(props.children);
|
|
87
|
+
const preparedProps = { ...props };
|
|
88
|
+
if (typeof preparedProps.className === "string") {
|
|
89
|
+
preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(" ");
|
|
90
|
+
delete preparedProps.className;
|
|
91
|
+
}
|
|
92
|
+
delete preparedProps.children;
|
|
93
|
+
return import_react.default.createElement(type, {
|
|
94
|
+
...preparedProps,
|
|
95
|
+
key: element.key,
|
|
96
|
+
children: preparedChildren
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
__name(prepareMetadataImageNode, "prepareMetadataImageNode");
|
|
100
|
+
async function normalizeFonts(fonts) {
|
|
101
|
+
if (!fonts?.length) return void 0;
|
|
102
|
+
return Promise.all(
|
|
103
|
+
fonts.map(async (font) => {
|
|
104
|
+
const data = await font.data;
|
|
105
|
+
const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;
|
|
106
|
+
return { ...font, data: arrayBuffer };
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
__name(normalizeFonts, "normalizeFonts");
|
|
111
|
+
function resolveCacheControl(revalidate) {
|
|
112
|
+
if (revalidate === false) {
|
|
113
|
+
return "public, max-age=31536000, immutable";
|
|
114
|
+
}
|
|
115
|
+
if (typeof revalidate === "number" && Number.isFinite(revalidate) && revalidate > 0) {
|
|
116
|
+
return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;
|
|
117
|
+
}
|
|
118
|
+
return "public, max-age=0, must-revalidate";
|
|
119
|
+
}
|
|
120
|
+
__name(resolveCacheControl, "resolveCacheControl");
|
|
121
|
+
function toArrayBuffer(value) {
|
|
122
|
+
if (value instanceof ArrayBuffer) return value;
|
|
123
|
+
const bytes = new Uint8Array(value.byteLength);
|
|
124
|
+
bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
|
|
125
|
+
return bytes.buffer;
|
|
126
|
+
}
|
|
127
|
+
__name(toArrayBuffer, "toArrayBuffer");
|
|
128
|
+
async function createEntityTag(body) {
|
|
129
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", body);
|
|
130
|
+
const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 32);
|
|
131
|
+
return `"${hash}"`;
|
|
132
|
+
}
|
|
133
|
+
__name(createEntityTag, "createEntityTag");
|
|
134
|
+
async function finalizeMetadataImageResponse(body, headers, options) {
|
|
135
|
+
const responseHeaders = new Headers(headers);
|
|
136
|
+
const etag = await createEntityTag(body);
|
|
137
|
+
responseHeaders.set("ETag", etag);
|
|
138
|
+
responseHeaders.set("Content-Length", String(body.byteLength));
|
|
139
|
+
responseHeaders.set("X-Content-Type-Options", "nosniff");
|
|
140
|
+
const matchesEntityTag = options.ifNoneMatch?.trim() === "*" || options.ifNoneMatch?.split(",").some((candidate) => candidate.trim().replace(/^W\//, "") === etag);
|
|
141
|
+
if (matchesEntityTag) {
|
|
142
|
+
return new Response(null, { status: 304, headers: responseHeaders });
|
|
143
|
+
}
|
|
144
|
+
return new Response(options.method?.toUpperCase() === "HEAD" ? null : body, {
|
|
145
|
+
status: 200,
|
|
146
|
+
headers: responseHeaders
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
__name(finalizeMetadataImageResponse, "finalizeMetadataImageResponse");
|
|
150
|
+
async function createFarmMetadataImageResponse(value, imageModule, options = {}) {
|
|
151
|
+
const method = (options.method || "GET").toUpperCase();
|
|
152
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
153
|
+
return new Response(null, { status: 405, headers: { Allow: "GET, HEAD" } });
|
|
154
|
+
}
|
|
155
|
+
if (isResponse(value)) {
|
|
156
|
+
return method === "HEAD" ? new Response(null, { status: value.status, headers: value.headers }) : value;
|
|
157
|
+
}
|
|
158
|
+
const cacheControl = resolveCacheControl(imageModule.revalidate);
|
|
159
|
+
const explicitContentType = imageModule.contentType?.split(";", 1)[0]?.trim().toLowerCase();
|
|
160
|
+
if (import_react.default.isValidElement(value) && explicitContentType !== "image/svg+xml") {
|
|
161
|
+
const { ImageResponse } = await import("@vercel/og");
|
|
162
|
+
const element = await prepareMetadataImageNode(value);
|
|
163
|
+
const response = new ImageResponse(element, {
|
|
164
|
+
width: imageModule.size?.width || 1200,
|
|
165
|
+
height: imageModule.size?.height || 630,
|
|
166
|
+
fonts: await normalizeFonts(imageModule.fonts),
|
|
167
|
+
emoji: imageModule.emoji,
|
|
168
|
+
debug: imageModule.debug,
|
|
169
|
+
headers: { "cache-control": cacheControl }
|
|
170
|
+
});
|
|
171
|
+
const headers = new Headers(response.headers);
|
|
172
|
+
headers.set("Cache-Control", cacheControl);
|
|
173
|
+
return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);
|
|
174
|
+
}
|
|
175
|
+
let body;
|
|
176
|
+
if (typeof value === "string") {
|
|
177
|
+
body = toArrayBuffer(new TextEncoder().encode(value));
|
|
178
|
+
} else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
179
|
+
body = toArrayBuffer(value);
|
|
180
|
+
} else if (import_react.default.isValidElement(value)) {
|
|
181
|
+
body = toArrayBuffer(new TextEncoder().encode((0, import_server.renderToStaticMarkup)(value)));
|
|
182
|
+
} else {
|
|
183
|
+
throw new Error("Metadata image must return a Response, string, bytes, or React element");
|
|
184
|
+
}
|
|
185
|
+
return finalizeMetadataImageResponse(
|
|
186
|
+
body,
|
|
187
|
+
{
|
|
188
|
+
"Content-Type": imageModule.contentType || "image/svg+xml; charset=utf-8",
|
|
189
|
+
"Cache-Control": cacheControl
|
|
190
|
+
},
|
|
191
|
+
options
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
__name(createFarmMetadataImageResponse, "createFarmMetadataImageResponse");
|
|
195
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
196
|
+
0 && (module.exports = {
|
|
197
|
+
createFarmMetadataImageResponse
|
|
198
|
+
});
|
|
199
|
+
//# sourceMappingURL=metadata-image-runtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/metadata-image.ts"],"sourcesContent":["import React from \"react\";\nimport { renderToStaticMarkup } from \"react-dom/server\";\nimport type { ImageResponseOptions } from \"@vercel/og\";\n\nconst REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\nconst REACT_MEMO_TYPE = Symbol.for(\"react.memo\");\nconst REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\n\ntype MetadataImageSize = {\n width?: number;\n height?: number;\n};\n\ntype MetadataImageFont = Omit<NonNullable<ImageResponseOptions[\"fonts\"]>[number], \"data\"> & {\n data: ArrayBuffer | ArrayBufferView | Promise<ArrayBuffer | ArrayBufferView>;\n};\n\nexport type FarmMetadataImageModule = {\n size?: MetadataImageSize;\n contentType?: string;\n revalidate?: number | false;\n fonts?: MetadataImageFont[];\n emoji?: ImageResponseOptions[\"emoji\"];\n debug?: boolean;\n};\n\nexport type FarmMetadataImageResponseOptions = {\n method?: string;\n ifNoneMatch?: string | null;\n};\n\nfunction isResponse(value: unknown): value is Response {\n return (\n typeof Response !== \"undefined\" &&\n (value instanceof Response ||\n Boolean(\n value &&\n typeof value === \"object\" &&\n typeof (value as Response).arrayBuffer === \"function\" &&\n (value as Response).headers,\n ))\n );\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return Boolean(\n value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as PromiseLike<unknown>).then === \"function\",\n );\n}\n\nasync function prepareMetadataImageNode(node: unknown): Promise<unknown> {\n if (isThenable(node)) {\n return prepareMetadataImageNode(await node);\n }\n\n if (Array.isArray(node)) {\n return Promise.all(node.map((child) => prepareMetadataImageNode(child)));\n }\n\n if (!React.isValidElement(node)) {\n return node;\n }\n\n const element = node as React.ReactElement<Record<string, unknown>>;\n const type = element.type as any;\n const props = element.props || {};\n\n if (typeof type === \"function\") {\n if (type.prototype?.isReactComponent) {\n throw new Error(\n \"Metadata image components must be stateless function components; React class components are not supported.\",\n );\n }\n return prepareMetadataImageNode(await type(props));\n }\n\n if (type && typeof type === \"object\") {\n if (type.$$typeof === REACT_MEMO_TYPE) {\n return prepareMetadataImageNode(React.createElement(type.type, props));\n }\n if (type.$$typeof === REACT_FORWARD_REF_TYPE) {\n return prepareMetadataImageNode(await type.render(props, null));\n }\n if (type.$$typeof === REACT_LAZY_TYPE) {\n return prepareMetadataImageNode(React.createElement(type._init(type._payload), props));\n }\n }\n\n const preparedChildren = await prepareMetadataImageNode(props.children);\n const preparedProps: Record<string, unknown> = { ...props };\n\n if (typeof preparedProps.className === \"string\") {\n preparedProps.tw = [preparedProps.tw, preparedProps.className].filter(Boolean).join(\" \");\n delete preparedProps.className;\n }\n delete preparedProps.children;\n\n return React.createElement(type, {\n ...preparedProps,\n key: element.key,\n children: preparedChildren,\n });\n}\n\nasync function normalizeFonts(\n fonts: MetadataImageFont[] | undefined,\n): Promise<ImageResponseOptions[\"fonts\"] | undefined> {\n if (!fonts?.length) return undefined;\n\n return Promise.all(\n fonts.map(async (font) => {\n const data = await font.data;\n const arrayBuffer = ArrayBuffer.isView(data) ? toArrayBuffer(data) : data;\n return { ...font, data: arrayBuffer } as NonNullable<ImageResponseOptions[\"fonts\"]>[number];\n }),\n );\n}\n\nfunction resolveCacheControl(revalidate: number | false | undefined): string {\n if (revalidate === false) {\n return \"public, max-age=31536000, immutable\";\n }\n if (typeof revalidate === \"number\" && Number.isFinite(revalidate) && revalidate > 0) {\n return `public, s-maxage=${Math.floor(revalidate)}, stale-while-revalidate=300`;\n }\n return \"public, max-age=0, must-revalidate\";\n}\n\nfunction toArrayBuffer(value: ArrayBuffer | ArrayBufferView): ArrayBuffer {\n if (value instanceof ArrayBuffer) return value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return bytes.buffer;\n}\n\nasync function createEntityTag(body: ArrayBuffer): Promise<string> {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", body);\n const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\")\n .slice(0, 32);\n return `\"${hash}\"`;\n}\n\nasync function finalizeMetadataImageResponse(\n body: ArrayBuffer,\n headers: HeadersInit,\n options: FarmMetadataImageResponseOptions,\n): Promise<Response> {\n const responseHeaders = new Headers(headers);\n const etag = await createEntityTag(body);\n responseHeaders.set(\"ETag\", etag);\n responseHeaders.set(\"Content-Length\", String(body.byteLength));\n responseHeaders.set(\"X-Content-Type-Options\", \"nosniff\");\n\n const matchesEntityTag =\n options.ifNoneMatch?.trim() === \"*\" ||\n options.ifNoneMatch\n ?.split(\",\")\n .some((candidate) => candidate.trim().replace(/^W\\//, \"\") === etag);\n if (matchesEntityTag) {\n return new Response(null, { status: 304, headers: responseHeaders });\n }\n\n return new Response(options.method?.toUpperCase() === \"HEAD\" ? null : body, {\n status: 200,\n headers: responseHeaders,\n });\n}\n\n/** @internal */\nexport async function createFarmMetadataImageResponse(\n value: unknown,\n imageModule: FarmMetadataImageModule,\n options: FarmMetadataImageResponseOptions = {},\n): Promise<Response> {\n const method = (options.method || \"GET\").toUpperCase();\n if (method !== \"GET\" && method !== \"HEAD\") {\n return new Response(null, { status: 405, headers: { Allow: \"GET, HEAD\" } });\n }\n\n if (isResponse(value)) {\n return method === \"HEAD\"\n ? new Response(null, { status: value.status, headers: value.headers })\n : value;\n }\n\n const cacheControl = resolveCacheControl(imageModule.revalidate);\n const explicitContentType = imageModule.contentType?.split(\";\", 1)[0]?.trim().toLowerCase();\n\n if (React.isValidElement(value) && explicitContentType !== \"image/svg+xml\") {\n const { ImageResponse } = await import(\"@vercel/og\");\n const element = (await prepareMetadataImageNode(value)) as React.ReactElement;\n const response = new ImageResponse(element, {\n width: imageModule.size?.width || 1200,\n height: imageModule.size?.height || 630,\n fonts: await normalizeFonts(imageModule.fonts),\n emoji: imageModule.emoji,\n debug: imageModule.debug,\n headers: { \"cache-control\": cacheControl },\n });\n const headers = new Headers(response.headers);\n headers.set(\"Cache-Control\", cacheControl);\n return finalizeMetadataImageResponse(await response.arrayBuffer(), headers, options);\n }\n\n let body: ArrayBuffer;\n if (typeof value === \"string\") {\n body = toArrayBuffer(new TextEncoder().encode(value));\n } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n body = toArrayBuffer(value);\n } else if (React.isValidElement(value)) {\n body = toArrayBuffer(new TextEncoder().encode(renderToStaticMarkup(value)));\n } else {\n throw new Error(\"Metadata image must return a Response, string, bytes, or React element\");\n }\n\n return finalizeMetadataImageResponse(\n body,\n {\n \"Content-Type\": imageModule.contentType || \"image/svg+xml; charset=utf-8\",\n \"Cache-Control\": cacheControl,\n },\n options,\n );\n}\n"],"mappings":"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","names":["React"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -42,9 +42,13 @@ __export(production_runtime_exports, {
|
|
|
42
42
|
isFarmRedirectError: () => isFarmRedirectError,
|
|
43
43
|
localizeFarmHref: () => localizeFarmHref,
|
|
44
44
|
localizeFarmPathname: () => localizeFarmPathname,
|
|
45
|
+
manageFarmDocumentPreloads: () => manageFarmDocumentPreloads,
|
|
46
|
+
manageFarmHtmlPreloads: () => manageFarmHtmlPreloads,
|
|
47
|
+
manageFarmLinkHeaderPreloads: () => manageFarmLinkHeaderPreloads,
|
|
45
48
|
mergeMetadata: () => mergeMetadata,
|
|
46
49
|
normalizeRevalidatePath: () => normalizeRevalidatePath,
|
|
47
50
|
renderMetadataHead: () => renderMetadataHead,
|
|
51
|
+
reportFarmPreloadWarnings: () => reportFarmPreloadWarnings,
|
|
48
52
|
resolveFarmRouteContext: () => resolveFarmRouteContext,
|
|
49
53
|
stripFarmLocaleFromPathname: () => stripFarmLocaleFromPathname,
|
|
50
54
|
withFarmRouteContext: () => withFarmRouteContext
|
|
@@ -2142,6 +2146,308 @@ function withFarmRouteContext(props, context) {
|
|
|
2142
2146
|
}
|
|
2143
2147
|
__name(withFarmRouteContext, "withFarmRouteContext");
|
|
2144
2148
|
|
|
2149
|
+
// src/preload.ts
|
|
2150
|
+
var reportedWarnings = /* @__PURE__ */ new Map();
|
|
2151
|
+
var PRELOAD_WARNING_TTL_MS = 6e4;
|
|
2152
|
+
var MAX_REPORTED_PRELOAD_WARNINGS = 256;
|
|
2153
|
+
function manageFarmHtmlPreloads(html, config) {
|
|
2154
|
+
const elements = findHtmlLinkElements(html);
|
|
2155
|
+
const candidates = elements.flatMap((element, index) => {
|
|
2156
|
+
const kind = getHtmlPreloadKind(element.value);
|
|
2157
|
+
return kind ? [
|
|
2158
|
+
{
|
|
2159
|
+
index,
|
|
2160
|
+
kind,
|
|
2161
|
+
highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
|
|
2162
|
+
}
|
|
2163
|
+
] : [];
|
|
2164
|
+
});
|
|
2165
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
2166
|
+
if (config.mode === "warn" || budget.removed.size === 0) {
|
|
2167
|
+
return { value: html, warnings: budget.warnings };
|
|
2168
|
+
}
|
|
2169
|
+
return {
|
|
2170
|
+
value: removeHtmlLinkElements(html, elements, budget.removed),
|
|
2171
|
+
warnings: budget.warnings
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2174
|
+
__name(manageFarmHtmlPreloads, "manageFarmHtmlPreloads");
|
|
2175
|
+
function manageFarmLinkHeaderPreloads(value, config) {
|
|
2176
|
+
if (!value) return { value, warnings: [] };
|
|
2177
|
+
const links = splitLinkHeader(value);
|
|
2178
|
+
const candidates = links.flatMap((link, index) => {
|
|
2179
|
+
const kind = getLinkHeaderPreloadKind(link);
|
|
2180
|
+
return kind ? [
|
|
2181
|
+
{
|
|
2182
|
+
index,
|
|
2183
|
+
kind,
|
|
2184
|
+
highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
|
|
2185
|
+
}
|
|
2186
|
+
] : [];
|
|
2187
|
+
});
|
|
2188
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
2189
|
+
return {
|
|
2190
|
+
value: config.mode === "enforce" ? links.filter((_, index) => !budget.removed.has(index)).join(", ") : value,
|
|
2191
|
+
warnings: budget.warnings
|
|
2192
|
+
};
|
|
2193
|
+
}
|
|
2194
|
+
__name(manageFarmLinkHeaderPreloads, "manageFarmLinkHeaderPreloads");
|
|
2195
|
+
function manageFarmDocumentPreloads(html, linkHeader, config) {
|
|
2196
|
+
const elements = findHtmlLinkElements(html);
|
|
2197
|
+
const links = linkHeader ? splitLinkHeader(linkHeader) : [];
|
|
2198
|
+
const headerOffset = elements.length;
|
|
2199
|
+
const candidates = [];
|
|
2200
|
+
for (const [index, element] of elements.entries()) {
|
|
2201
|
+
const kind = getHtmlPreloadKind(element.value);
|
|
2202
|
+
if (!kind) continue;
|
|
2203
|
+
candidates.push({
|
|
2204
|
+
index,
|
|
2205
|
+
kind,
|
|
2206
|
+
highPriority: readHtmlAttribute(element.value, "fetchpriority")?.toLowerCase() === "high"
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2209
|
+
for (const [index, link] of links.entries()) {
|
|
2210
|
+
const kind = getLinkHeaderPreloadKind(link);
|
|
2211
|
+
if (!kind) continue;
|
|
2212
|
+
candidates.push({
|
|
2213
|
+
index: headerOffset + index,
|
|
2214
|
+
kind,
|
|
2215
|
+
highPriority: getLinkHeaderParameter(link, "fetchpriority")?.toLowerCase() === "high"
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
const budget = selectPreloadsWithinBudget(candidates, config);
|
|
2219
|
+
if (config.mode === "warn" || budget.removed.size === 0) {
|
|
2220
|
+
return { html, linkHeader, warnings: budget.warnings };
|
|
2221
|
+
}
|
|
2222
|
+
return {
|
|
2223
|
+
html: removeHtmlLinkElements(html, elements, budget.removed),
|
|
2224
|
+
linkHeader: links.filter((_, index) => !budget.removed.has(headerOffset + index)).join(", "),
|
|
2225
|
+
warnings: budget.warnings
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
__name(manageFarmDocumentPreloads, "manageFarmDocumentPreloads");
|
|
2229
|
+
function reportFarmPreloadWarnings(warnings, context = "the rendered document") {
|
|
2230
|
+
const now = Date.now();
|
|
2231
|
+
for (const [key, reportedAt] of reportedWarnings) {
|
|
2232
|
+
if (now - reportedAt >= PRELOAD_WARNING_TTL_MS) reportedWarnings.delete(key);
|
|
2233
|
+
}
|
|
2234
|
+
for (const warning of warnings) {
|
|
2235
|
+
const key = `${context}:${warning.kind}:${warning.count}:${warning.budget}:${warning.removed}`;
|
|
2236
|
+
const reportedAt = reportedWarnings.get(key);
|
|
2237
|
+
if (reportedAt !== void 0 && now - reportedAt < PRELOAD_WARNING_TTL_MS) continue;
|
|
2238
|
+
reportedWarnings.set(key, now);
|
|
2239
|
+
while (reportedWarnings.size > MAX_REPORTED_PRELOAD_WARNINGS) {
|
|
2240
|
+
const oldest = reportedWarnings.keys().next().value;
|
|
2241
|
+
if (oldest === void 0) break;
|
|
2242
|
+
reportedWarnings.delete(oldest);
|
|
2243
|
+
}
|
|
2244
|
+
const action = warning.removed > 0 ? ` Removed ${warning.removed} lower-priority hint(s).` : "";
|
|
2245
|
+
const recommendation = warning.kind === "image" ? ' Mark only the LCP image with `preload` or `fetchPriority="high"`.' : " Set `preload: false` on fonts that are not required above the fold.";
|
|
2246
|
+
console.warn(
|
|
2247
|
+
`[Farm.js] ${context} emitted ${warning.count} ${warning.kind} preload hints (budget: ${warning.budget}).${action}${recommendation}`
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
__name(reportFarmPreloadWarnings, "reportFarmPreloadWarnings");
|
|
2252
|
+
function selectPreloadsWithinBudget(candidates, config) {
|
|
2253
|
+
const removed = /* @__PURE__ */ new Set();
|
|
2254
|
+
const warnings = [];
|
|
2255
|
+
for (const kind of ["image", "font"]) {
|
|
2256
|
+
const matching = candidates.filter((candidate) => candidate.kind === kind);
|
|
2257
|
+
const limit = kind === "image" ? config.maxImages : config.maxFonts;
|
|
2258
|
+
if (matching.length <= limit) continue;
|
|
2259
|
+
const retained = new Set(
|
|
2260
|
+
[...matching].sort(
|
|
2261
|
+
(left, right) => Number(right.highPriority) - Number(left.highPriority) || left.index - right.index
|
|
2262
|
+
).slice(0, limit).map((candidate) => candidate.index)
|
|
2263
|
+
);
|
|
2264
|
+
if (config.mode === "enforce") {
|
|
2265
|
+
for (const candidate of matching) {
|
|
2266
|
+
if (!retained.has(candidate.index)) removed.add(candidate.index);
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
warnings.push({
|
|
2270
|
+
kind,
|
|
2271
|
+
count: matching.length,
|
|
2272
|
+
budget: limit,
|
|
2273
|
+
removed: config.mode === "enforce" ? matching.length - retained.size : 0
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
return { removed, warnings };
|
|
2277
|
+
}
|
|
2278
|
+
__name(selectPreloadsWithinBudget, "selectPreloadsWithinBudget");
|
|
2279
|
+
function getHtmlPreloadKind(link) {
|
|
2280
|
+
const rel = readHtmlAttribute(link, "rel")?.toLowerCase().split(/\s+/) || [];
|
|
2281
|
+
if (!rel.includes("preload")) return void 0;
|
|
2282
|
+
return normalizePreloadKind(readHtmlAttribute(link, "as"));
|
|
2283
|
+
}
|
|
2284
|
+
__name(getHtmlPreloadKind, "getHtmlPreloadKind");
|
|
2285
|
+
function getLinkHeaderPreloadKind(link) {
|
|
2286
|
+
const relations = getLinkHeaderParameter(link, "rel")?.toLowerCase().split(/\s+/) ?? [];
|
|
2287
|
+
if (!relations.includes("preload")) return void 0;
|
|
2288
|
+
return normalizePreloadKind(getLinkHeaderParameter(link, "as"));
|
|
2289
|
+
}
|
|
2290
|
+
__name(getLinkHeaderPreloadKind, "getLinkHeaderPreloadKind");
|
|
2291
|
+
function getLinkHeaderParameter(link, name) {
|
|
2292
|
+
const uriEnd = link.indexOf(">");
|
|
2293
|
+
if (uriEnd === -1) return void 0;
|
|
2294
|
+
for (const parameter of splitLinkParameters(link.slice(uriEnd + 1))) {
|
|
2295
|
+
const separator = parameter.indexOf("=");
|
|
2296
|
+
const parameterName = (separator === -1 ? parameter : parameter.slice(0, separator)).trim().toLowerCase();
|
|
2297
|
+
if (parameterName !== name.toLowerCase() || separator === -1) continue;
|
|
2298
|
+
const rawValue = parameter.slice(separator + 1).trim();
|
|
2299
|
+
if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
2300
|
+
return rawValue.slice(1, -1).replace(/\\([\\"])/g, "$1");
|
|
2301
|
+
}
|
|
2302
|
+
return rawValue;
|
|
2303
|
+
}
|
|
2304
|
+
return void 0;
|
|
2305
|
+
}
|
|
2306
|
+
__name(getLinkHeaderParameter, "getLinkHeaderParameter");
|
|
2307
|
+
function splitLinkParameters(value) {
|
|
2308
|
+
const parameters = [];
|
|
2309
|
+
let start = 0;
|
|
2310
|
+
let quoted = false;
|
|
2311
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
2312
|
+
const character = value[index];
|
|
2313
|
+
if (character === '"' && !isEscaped(value, index)) quoted = !quoted;
|
|
2314
|
+
else if (character === ";" && !quoted) {
|
|
2315
|
+
const parameter2 = value.slice(start, index).trim();
|
|
2316
|
+
if (parameter2) parameters.push(parameter2);
|
|
2317
|
+
start = index + 1;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
const parameter = value.slice(start).trim();
|
|
2321
|
+
if (parameter) parameters.push(parameter);
|
|
2322
|
+
return parameters;
|
|
2323
|
+
}
|
|
2324
|
+
__name(splitLinkParameters, "splitLinkParameters");
|
|
2325
|
+
function normalizePreloadKind(value) {
|
|
2326
|
+
const normalized = value?.toLowerCase();
|
|
2327
|
+
return normalized === "image" || normalized === "font" ? normalized : void 0;
|
|
2328
|
+
}
|
|
2329
|
+
__name(normalizePreloadKind, "normalizePreloadKind");
|
|
2330
|
+
function readHtmlAttribute(element, name) {
|
|
2331
|
+
const match = element.match(
|
|
2332
|
+
new RegExp(`\\s${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))`, "i")
|
|
2333
|
+
);
|
|
2334
|
+
return match?.[1] ?? match?.[2] ?? match?.[3];
|
|
2335
|
+
}
|
|
2336
|
+
__name(readHtmlAttribute, "readHtmlAttribute");
|
|
2337
|
+
function findHtmlLinkElements(html) {
|
|
2338
|
+
const elements = [];
|
|
2339
|
+
const lowerHtml = html.toLowerCase();
|
|
2340
|
+
let cursor = 0;
|
|
2341
|
+
while (cursor < html.length) {
|
|
2342
|
+
const start = html.indexOf("<", cursor);
|
|
2343
|
+
if (start === -1) break;
|
|
2344
|
+
if (lowerHtml.startsWith("<!--", start)) {
|
|
2345
|
+
const commentEnd = lowerHtml.indexOf("-->", start + 4);
|
|
2346
|
+
cursor = commentEnd === -1 ? html.length : commentEnd + 3;
|
|
2347
|
+
continue;
|
|
2348
|
+
}
|
|
2349
|
+
const rawText = lowerHtml.slice(start).match(/^<(script|style|template|textarea|title|noscript|svg)(?=[\s/>])/);
|
|
2350
|
+
if (rawText?.[1]) {
|
|
2351
|
+
const openingEnd = findHtmlTagEnd(html, start);
|
|
2352
|
+
if (openingEnd === -1) break;
|
|
2353
|
+
const closingStart = findHtmlClosingTag(lowerHtml, rawText[1], openingEnd);
|
|
2354
|
+
if (closingStart === -1) {
|
|
2355
|
+
cursor = html.length;
|
|
2356
|
+
continue;
|
|
2357
|
+
}
|
|
2358
|
+
const closingEnd = findHtmlTagEnd(html, closingStart);
|
|
2359
|
+
cursor = closingEnd === -1 ? html.length : closingEnd;
|
|
2360
|
+
continue;
|
|
2361
|
+
}
|
|
2362
|
+
if (/^<link(?=[\s/>])/i.test(html.slice(start))) {
|
|
2363
|
+
const end = findHtmlTagEnd(html, start);
|
|
2364
|
+
if (end === -1) break;
|
|
2365
|
+
elements.push({ start, end, value: html.slice(start, end) });
|
|
2366
|
+
cursor = end;
|
|
2367
|
+
continue;
|
|
2368
|
+
}
|
|
2369
|
+
if (/^<\/?[A-Za-z][\w:-]*(?=[\s/>])/.test(html.slice(start))) {
|
|
2370
|
+
const end = findHtmlTagEnd(html, start);
|
|
2371
|
+
cursor = end === -1 ? html.length : end;
|
|
2372
|
+
continue;
|
|
2373
|
+
}
|
|
2374
|
+
cursor = start + 1;
|
|
2375
|
+
}
|
|
2376
|
+
return elements;
|
|
2377
|
+
}
|
|
2378
|
+
__name(findHtmlLinkElements, "findHtmlLinkElements");
|
|
2379
|
+
function findHtmlClosingTag(html, tagName, start) {
|
|
2380
|
+
const prefix = `</${tagName}`;
|
|
2381
|
+
let candidate = html.indexOf(prefix, start);
|
|
2382
|
+
while (candidate !== -1) {
|
|
2383
|
+
const boundary = html[candidate + prefix.length];
|
|
2384
|
+
if (boundary === ">" || boundary === "/" || /\s/.test(boundary ?? "")) return candidate;
|
|
2385
|
+
candidate = html.indexOf(prefix, candidate + prefix.length);
|
|
2386
|
+
}
|
|
2387
|
+
return -1;
|
|
2388
|
+
}
|
|
2389
|
+
__name(findHtmlClosingTag, "findHtmlClosingTag");
|
|
2390
|
+
function findHtmlTagEnd(html, start) {
|
|
2391
|
+
let quote;
|
|
2392
|
+
for (let index = start + 1; index < html.length; index += 1) {
|
|
2393
|
+
const character = html[index];
|
|
2394
|
+
if (quote) {
|
|
2395
|
+
if (character === quote) quote = void 0;
|
|
2396
|
+
} else if (character === '"' || character === "'") {
|
|
2397
|
+
quote = character;
|
|
2398
|
+
} else if (character === ">") {
|
|
2399
|
+
return index + 1;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
return -1;
|
|
2403
|
+
}
|
|
2404
|
+
__name(findHtmlTagEnd, "findHtmlTagEnd");
|
|
2405
|
+
function removeHtmlLinkElements(html, elements, removed) {
|
|
2406
|
+
let cursor = 0;
|
|
2407
|
+
let output = "";
|
|
2408
|
+
for (const [index, element] of elements.entries()) {
|
|
2409
|
+
if (!removed.has(index)) continue;
|
|
2410
|
+
output += html.slice(cursor, element.start);
|
|
2411
|
+
cursor = element.end;
|
|
2412
|
+
}
|
|
2413
|
+
return output + html.slice(cursor);
|
|
2414
|
+
}
|
|
2415
|
+
__name(removeHtmlLinkElements, "removeHtmlLinkElements");
|
|
2416
|
+
function splitLinkHeader(value) {
|
|
2417
|
+
const links = [];
|
|
2418
|
+
let start = 0;
|
|
2419
|
+
let insideAngleBrackets = false;
|
|
2420
|
+
let quoted = false;
|
|
2421
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
2422
|
+
const character = value[index];
|
|
2423
|
+
if (quoted) {
|
|
2424
|
+
if (character === '"' && !isEscaped(value, index)) quoted = false;
|
|
2425
|
+
continue;
|
|
2426
|
+
}
|
|
2427
|
+
if (character === '"') {
|
|
2428
|
+
quoted = true;
|
|
2429
|
+
} else if (character === "<") {
|
|
2430
|
+
insideAngleBrackets = true;
|
|
2431
|
+
} else if (character === ">") {
|
|
2432
|
+
insideAngleBrackets = false;
|
|
2433
|
+
} else if (character === "," && !insideAngleBrackets) {
|
|
2434
|
+
links.push(value.slice(start, index).trim());
|
|
2435
|
+
start = index + 1;
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
links.push(value.slice(start).trim());
|
|
2439
|
+
return links.filter(Boolean);
|
|
2440
|
+
}
|
|
2441
|
+
__name(splitLinkHeader, "splitLinkHeader");
|
|
2442
|
+
function isEscaped(value, index) {
|
|
2443
|
+
let backslashes = 0;
|
|
2444
|
+
for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
|
|
2445
|
+
backslashes += 1;
|
|
2446
|
+
}
|
|
2447
|
+
return backslashes % 2 === 1;
|
|
2448
|
+
}
|
|
2449
|
+
__name(isEscaped, "isEscaped");
|
|
2450
|
+
|
|
2145
2451
|
// src/nitro/production-runtime.ts
|
|
2146
2452
|
function appendFarmLinkHeader(headers, value) {
|
|
2147
2453
|
const current = headers.get("Link");
|
|
@@ -2177,9 +2483,13 @@ __name(appendFarmLinkHeader, "appendFarmLinkHeader");
|
|
|
2177
2483
|
isFarmRedirectError,
|
|
2178
2484
|
localizeFarmHref,
|
|
2179
2485
|
localizeFarmPathname,
|
|
2486
|
+
manageFarmDocumentPreloads,
|
|
2487
|
+
manageFarmHtmlPreloads,
|
|
2488
|
+
manageFarmLinkHeaderPreloads,
|
|
2180
2489
|
mergeMetadata,
|
|
2181
2490
|
normalizeRevalidatePath,
|
|
2182
2491
|
renderMetadataHead,
|
|
2492
|
+
reportFarmPreloadWarnings,
|
|
2183
2493
|
resolveFarmRouteContext,
|
|
2184
2494
|
stripFarmLocaleFromPathname,
|
|
2185
2495
|
withFarmRouteContext
|