@farm.js/core 0.1.17 → 0.1.18
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 +12 -225
- package/dist/agent-runtime.cjs +83 -2800
- package/dist/api/client.cjs +17 -4060
- package/dist/api/route-manager.cjs +34 -4354
- package/dist/api/runtime.cjs +29 -2696
- package/dist/api.cjs +88 -8434
- package/dist/app-markdown.cjs +39 -280
- package/dist/cache.cjs +38 -1560
- package/dist/chunk-22GUSVNJ.cjs +351 -0
- package/dist/chunk-2CQ74SP6.cjs +13 -0
- package/dist/chunk-2SJ4RQ6P.cjs +57 -0
- package/dist/chunk-3376ZTRC.cjs +1 -0
- package/dist/{chunk-YD4J4XCI.mjs → chunk-3XG26Z3J.mjs} +1 -1
- package/dist/chunk-4PNUXIVU.cjs +472 -0
- package/dist/chunk-4PPEPOZZ.cjs +21 -0
- package/dist/chunk-4ZFL5GFN.cjs +520 -0
- package/dist/chunk-5OVTOKGH.cjs +65 -0
- package/dist/chunk-5QIKR7RR.cjs +224 -0
- package/dist/chunk-5ZSWG4UX.cjs +127 -0
- package/dist/chunk-62YJ2IEB.cjs +238 -0
- package/dist/chunk-6EODJYCX.cjs +183 -0
- package/dist/chunk-6EXBPJ24.cjs +434 -0
- package/dist/chunk-6QQDAAAZ.cjs +38 -0
- package/dist/chunk-6V4TDWEC.cjs +455 -0
- package/dist/chunk-72ADZ6GQ.cjs +19 -0
- package/dist/chunk-75BRBIFP.cjs +172 -0
- package/dist/chunk-7W3CPVXS.cjs +24 -0
- package/dist/chunk-A6WIQH5Z.cjs +31 -0
- package/dist/chunk-AFOD3LYZ.cjs +377 -0
- package/dist/chunk-AMDMVWMI.cjs +39 -0
- package/dist/chunk-AORPIPNB.cjs +552 -0
- package/dist/chunk-ARJWXNQL.cjs +256 -0
- package/dist/chunk-AWRISO2H.cjs +2199 -0
- package/dist/chunk-AYJR42WX.cjs +711 -0
- package/dist/chunk-B4CH33IG.cjs +644 -0
- package/dist/chunk-BIDYX3SL.cjs +91 -0
- package/dist/chunk-BSTRERPP.cjs +40 -0
- package/dist/chunk-BYODCJD6.cjs +663 -0
- package/dist/chunk-C3VRMB6H.cjs +85 -0
- package/dist/chunk-C5GUTBZK.cjs +173 -0
- package/dist/chunk-CIAGU2X4.cjs +337 -0
- package/dist/chunk-CMGMGHUZ.cjs +27 -0
- package/dist/chunk-CXP5U3RW.cjs +54 -0
- package/dist/chunk-D2ULAULS.cjs +166 -0
- package/dist/chunk-D7JTOLFK.cjs +285 -0
- package/dist/chunk-DVM4FKZL.cjs +169 -0
- package/dist/chunk-DYEJQTDN.cjs +49 -0
- package/dist/chunk-E2BMSZ2W.cjs +151 -0
- package/dist/chunk-E3UK5IIB.cjs +593 -0
- package/dist/chunk-EM6SBQKM.cjs +470 -0
- package/dist/chunk-FJSWYIR7.cjs +482 -0
- package/dist/chunk-FK6GO24V.cjs +54 -0
- package/dist/chunk-FXUUWYAX.cjs +654 -0
- package/dist/chunk-G3HRIVEY.cjs +395 -0
- package/dist/chunk-G643DQCH.cjs +13 -0
- package/dist/chunk-G7HXGLEC.cjs +175 -0
- package/dist/chunk-GDSHDTJ4.cjs +152 -0
- package/dist/chunk-GNEO2XOF.cjs +2040 -0
- package/dist/{chunk-56DAX2BE.mjs → chunk-GYKJCFTS.mjs} +1 -1
- package/dist/chunk-H6G5INWM.cjs +1094 -0
- package/dist/chunk-HBTUGXHS.cjs +180 -0
- package/dist/chunk-HREOKQWT.cjs +45 -0
- package/dist/chunk-I4J452B7.cjs +435 -0
- package/dist/chunk-I57LW5VZ.cjs +94 -0
- package/dist/chunk-I7PUUDGY.cjs +389 -0
- package/dist/chunk-IAMRBF3Z.cjs +86 -0
- package/dist/chunk-IKNRN4VS.cjs +14214 -0
- package/dist/chunk-IQXFRNY2.cjs +169 -0
- package/dist/chunk-IXTFU4PL.cjs +2355 -0
- package/dist/chunk-J2OP5GG3.cjs +725 -0
- package/dist/chunk-J3LOGE4T.cjs +42 -0
- package/dist/chunk-J7FSKED3.cjs +93 -0
- package/dist/chunk-JDNHKPTD.cjs +22 -0
- package/dist/chunk-JSROZYYO.cjs +164 -0
- package/dist/chunk-K6FNHVDR.cjs +696 -0
- package/dist/chunk-KGZIORNL.cjs +43 -0
- package/dist/{chunk-MVIWBEJF.mjs → chunk-KPNVGRBL.mjs} +1 -1
- package/dist/chunk-KR6CKSXT.cjs +15 -0
- package/dist/chunk-KROWKCUH.cjs +185 -0
- package/dist/chunk-KVFPGF2M.cjs +46 -0
- package/dist/chunk-LCCBO7PJ.cjs +46 -0
- package/dist/chunk-LIUGYUX3.cjs +22 -0
- package/dist/chunk-LTNGXMQ6.cjs +55 -0
- package/dist/chunk-M2L4MYDQ.cjs +14 -0
- package/dist/chunk-MCJLA63J.cjs +1 -0
- package/dist/chunk-MKB2EGIR.cjs +148 -0
- package/dist/chunk-MQ3H6LT5.cjs +202 -0
- package/dist/chunk-MT763TDW.cjs +43 -0
- package/dist/chunk-MWSK6C4J.cjs +18 -0
- package/dist/chunk-MWWVKDW3.cjs +169 -0
- package/dist/chunk-NO3WWW3N.cjs +192 -0
- package/dist/chunk-NV3A5DXM.cjs +862 -0
- package/dist/chunk-NWOD6NIT.cjs +9 -0
- package/dist/chunk-NZKJGRB3.cjs +230 -0
- package/dist/chunk-OAVTUMJP.cjs +1496 -0
- package/dist/chunk-OHY2ZWUG.cjs +25 -0
- package/dist/chunk-OI6CMLWX.cjs +47 -0
- package/dist/chunk-OIEOCXKG.cjs +453 -0
- package/dist/chunk-OWOUTKIJ.cjs +558 -0
- package/dist/chunk-OX6O6WVA.cjs +74 -0
- package/dist/chunk-OXSIH4D6.cjs +476 -0
- package/dist/chunk-OYEUREB6.cjs +35 -0
- package/dist/chunk-PCOTGFSM.cjs +139 -0
- package/dist/chunk-PZYCPSCC.cjs +35 -0
- package/dist/chunk-QBK2AA4U.cjs +445 -0
- package/dist/chunk-QBPXNZGV.cjs +487 -0
- package/dist/chunk-QNPEUFHQ.cjs +27 -0
- package/dist/chunk-QZRVZSPN.cjs +236 -0
- package/dist/chunk-R5A5KNVX.cjs +20 -0
- package/dist/chunk-R5JIFR6B.cjs +42 -0
- package/dist/chunk-R6AIILII.cjs +193 -0
- package/dist/chunk-RG3ZOTG5.cjs +34 -0
- package/dist/chunk-ROUTX2E5.cjs +390 -0
- package/dist/chunk-RTHIVJ2G.cjs +54 -0
- package/dist/chunk-S3A45T7F.cjs +166 -0
- package/dist/chunk-S3JO3N4H.cjs +17 -0
- package/dist/chunk-SK35NQKK.cjs +27 -0
- package/dist/chunk-SU7MH53P.cjs +180 -0
- package/dist/chunk-SVRTJOUF.cjs +113 -0
- package/dist/chunk-SWN467MP.cjs +18 -0
- package/dist/chunk-SYQ3MOWW.cjs +73 -0
- package/dist/chunk-T5CERMEH.cjs +417 -0
- package/dist/chunk-TFAXUHWX.cjs +206 -0
- package/dist/chunk-TIWHTW3Q.cjs +24 -0
- package/dist/chunk-TKJZFIML.cjs +20 -0
- package/dist/chunk-TKNSDBBN.cjs +193 -0
- package/dist/chunk-TWGMSEHX.cjs +525 -0
- package/dist/chunk-TYQUSXUG.cjs +1357 -0
- package/dist/chunk-U4KT7QP3.cjs +23 -0
- package/dist/chunk-UJ2C4ICS.cjs +277 -0
- package/dist/chunk-UN5GHC5V.cjs +10244 -0
- package/dist/chunk-UQZ4AYTH.cjs +168 -0
- package/dist/chunk-US2QVW3E.cjs +36 -0
- package/dist/chunk-VB6UCX3V.cjs +421 -0
- package/dist/chunk-VEKFLAQM.cjs +300 -0
- package/dist/chunk-VQDBNVOO.cjs +14 -0
- package/dist/chunk-W4E7WMXE.cjs +71 -0
- package/dist/chunk-WJ3HK3LJ.cjs +1102 -0
- package/dist/chunk-WMAPPDMM.cjs +28 -0
- package/dist/chunk-WMOGFOUJ.cjs +223 -0
- package/dist/chunk-WPYFSQKK.cjs +37 -0
- package/dist/chunk-WZMNW2IW.cjs +1415 -0
- package/dist/chunk-XGC343EY.cjs +443 -0
- package/dist/chunk-XSKZORAS.cjs +727 -0
- package/dist/chunk-XWAWFQFS.cjs +82 -0
- package/dist/chunk-Y4YMF2NQ.cjs +460 -0
- package/dist/chunk-Y4YWHNKU.cjs +250 -0
- package/dist/chunk-Y53ZSFN6.cjs +504 -0
- package/dist/chunk-YA6LLTIJ.cjs +411 -0
- package/dist/chunk-YFPGHF5F.cjs +202 -0
- package/dist/chunk-YJRZR7VU.cjs +28 -0
- package/dist/chunk-YTAABQEV.cjs +1 -0
- package/dist/chunk-YX3DBN4M.cjs +18 -0
- package/dist/chunk-YZTASLPQ.cjs +64 -0
- package/dist/chunk-Z5HIWVDP.cjs +2173 -0
- package/dist/chunk-ZEG3OPIB.cjs +93 -0
- package/dist/chunk-ZMN3H73H.cjs +155 -0
- package/dist/client/lifecycle.cjs +6 -35
- package/dist/client-plugins.cjs +7 -448
- package/dist/client.cjs +171 -9808
- package/dist/config.cjs +8 -36
- package/dist/cron.cjs +24 -491
- package/dist/deferred.cjs +26 -475
- package/dist/deployment.cjs +39 -210
- package/dist/devtools-OUIPHVV6.cjs +388 -0
- package/dist/devtools-client-4WAPJY5L.cjs +254 -0
- package/dist/devtools-ui-5GBDIGMK.cjs +1296 -0
- package/dist/docs.cjs +46 -5657
- package/dist/env-types.cjs +5 -226
- package/dist/env.cjs +21 -338
- package/dist/environment/vite.cjs +8 -372
- package/dist/environment.cjs +12 -94
- package/dist/font.cjs +13 -63
- package/dist/headers.cjs +7 -123
- package/dist/i18n/client.cjs +55 -294
- package/dist/i18n/index.cjs +22 -209
- package/dist/i18n/server.cjs +22 -745
- package/dist/image/server.cjs +13 -729
- package/dist/image/sharp.cjs +33 -171
- package/dist/image.cjs +41 -85
- package/dist/index.cjs +1151 -68080
- package/dist/index.mjs +3 -3
- package/dist/instrumentation.cjs +12 -138
- package/dist/integration-orm-55F7CII5.cjs +13 -0
- package/dist/integrations.cjs +55 -4090
- package/dist/internal/app-markdown-runtime.cjs +27 -224
- package/dist/internal/build-runtime.cjs +120 -52259
- package/dist/internal/build-runtime.mjs +3 -3
- package/dist/internal/cli-runtime.cjs +67 -13811
- package/dist/internal/client-error-overlay.cjs +80 -733
- package/dist/internal/client-error-overlay.mjs +1 -1
- package/dist/internal/client-runtime.cjs +81 -913
- package/dist/internal/compression-runtime.cjs +8 -214
- package/dist/internal/config-runtime.cjs +42 -6547
- package/dist/internal/docs-precompiled-runtime.cjs +26 -46
- package/dist/internal/infra-analytics-runtime.cjs +10 -536
- package/dist/internal/isolated-boundary.cjs +14 -414
- package/dist/internal/metadata-image-runtime.cjs +7 -285
- package/dist/internal/product-telemetry-runtime.cjs +42 -97
- package/dist/internal/product-telemetry-runtime.mjs +1 -1
- package/dist/internal/production-node-env.cjs +6 -63
- package/dist/internal/production-runtime.cjs +418 -7133
- package/dist/internal/request-cookies.cjs +6 -54
- package/dist/json-ld.cjs +24 -50
- package/dist/layers-E4WPJNY5.cjs +17 -0
- package/dist/manager-G4B2IPYE.cjs +14 -0
- package/dist/markdown.cjs +21 -547
- package/dist/middleware.cjs +36 -2995
- package/dist/navigation.cjs +22 -2588
- package/dist/nitro-4I2MYLY2.cjs +652 -0
- package/dist/observability.cjs +22 -614
- package/dist/og.cjs +5 -28
- package/dist/plugin.cjs +106 -37442
- package/dist/plugin.mjs +2 -2
- package/dist/query/client.cjs +113 -449
- package/dist/query/index.cjs +26 -288
- package/dist/query/parsers.cjs +23 -247
- package/dist/query/server.cjs +36 -298
- package/dist/renderer/react/client.cjs +9 -43
- package/dist/renderer/react/server.cjs +40 -103
- package/dist/renderer/react/vite.cjs +7 -29
- package/dist/renderer-client.cjs +126 -4295
- package/dist/renderer.cjs +31 -249
- package/dist/request.cjs +5 -68
- package/dist/router.cjs +11 -474
- package/dist/routes.cjs +42 -2461
- package/dist/schema-dev-notice-MXSZMVDG.cjs +56 -0
- package/dist/schema.cjs +6 -33
- package/dist/search-client-G3RICOFU.cjs +13 -0
- package/dist/server-action-security.cjs +25 -541
- package/dist/server-fn-client.cjs +6 -337
- package/dist/server-fn.cjs +32 -1841
- package/dist/server-plugins.cjs +15 -884
- package/dist/server-query-client.cjs +15 -1883
- package/dist/server-query.cjs +16 -1838
- package/dist/server.cjs +296 -44681
- package/dist/server.mjs +2 -2
- package/dist/storage.cjs +57 -576
- package/dist/testing.cjs +89 -3186
- package/dist/theme/client.cjs +13 -108
- package/dist/theme/index.cjs +6 -68
- package/dist/theme/runtime.cjs +13 -78
- package/dist/theme/server.cjs +10 -179
- package/dist/version.cjs +4 -32
- package/dist/version.mjs +1 -1
- package/dist/vite.cjs +119 -37773
- package/dist/vite.mjs +2 -2
- package/dist/workflows.cjs +19 -1040
- package/package.json +1 -1
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkEM6SBQKMcjs = require('./chunk-EM6SBQKM.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkS3JO3N4Hcjs = require('./chunk-S3JO3N4H.cjs');
|
|
7
|
+
|
|
8
|
+
// src/image-pattern.ts
|
|
9
|
+
var compiledPatterns = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
function matchesImagePathPattern(value, pattern) {
|
|
11
|
+
const pathname = _nullishCoalesce(pattern.pathname, () => ( "/**"));
|
|
12
|
+
let compiled = compiledPatterns.get(pattern);
|
|
13
|
+
if (!compiled || compiled.pathname !== pathname) {
|
|
14
|
+
const escaped = pathname.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
15
|
+
const source = escaped.replace(/\*\*/g, "\0").replace(/\*/g, "[^/]*").replace(/\0/g, ".*");
|
|
16
|
+
compiled = { pathname, matcher: new RegExp(`^${source}$`) };
|
|
17
|
+
compiledPatterns.set(pattern, compiled);
|
|
18
|
+
}
|
|
19
|
+
return compiled.matcher.test(value);
|
|
20
|
+
}
|
|
21
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, matchesImagePathPattern, "matchesImagePathPattern");
|
|
22
|
+
|
|
23
|
+
// src/image-server.ts
|
|
24
|
+
var _FarmImageRequestError = class _FarmImageRequestError extends Error {
|
|
25
|
+
constructor(code, status, message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "FarmImageRequestError";
|
|
28
|
+
this.code = code;
|
|
29
|
+
this.status = status;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, _FarmImageRequestError, "FarmImageRequestError");
|
|
33
|
+
var FarmImageRequestError = _FarmImageRequestError;
|
|
34
|
+
function createFarmImageHandler(config, options) {
|
|
35
|
+
const fetcher = _nullishCoalesce(options.fetch, () => ( globalThis.fetch));
|
|
36
|
+
const cache = new FarmImageMemoryCache(_nullishCoalesce(options.cacheEntries, () => ( 100)));
|
|
37
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
38
|
+
const allowedWidths = /* @__PURE__ */ new Set([...config.deviceSizes, ...config.imageSizes]);
|
|
39
|
+
const allowedQualities = new Set(config.qualities);
|
|
40
|
+
return /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, async function handleFarmImage(request, context) {
|
|
41
|
+
const requestUrl = new URL(request.url);
|
|
42
|
+
if (requestUrl.pathname !== config.path) return null;
|
|
43
|
+
try {
|
|
44
|
+
const trustedLocalOrigin = resolveTrustedLocalOrigin(
|
|
45
|
+
_nullishCoalesce(_optionalChain([context, 'optionalAccess', _ => _.trustedLocalOrigin]), () => ( options.trustedLocalOrigin))
|
|
46
|
+
);
|
|
47
|
+
if (config.provider === "none") {
|
|
48
|
+
throw new FarmImageRequestError(
|
|
49
|
+
"DISALLOWED_SOURCE",
|
|
50
|
+
404,
|
|
51
|
+
"The Farm image optimizer is disabled"
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
55
|
+
throw new FarmImageRequestError(
|
|
56
|
+
"INVALID_METHOD",
|
|
57
|
+
405,
|
|
58
|
+
"The Farm image optimizer only accepts GET and HEAD"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const sourceUrl = await resolveImageSourceUrl(
|
|
62
|
+
requestUrl,
|
|
63
|
+
trustedLocalOrigin,
|
|
64
|
+
config,
|
|
65
|
+
options.validateRemoteUrl
|
|
66
|
+
);
|
|
67
|
+
const width = parseAllowedInteger(requestUrl.searchParams.get("w"), allowedWidths, "width");
|
|
68
|
+
const quality = parseAllowedInteger(
|
|
69
|
+
requestUrl.searchParams.get("q"),
|
|
70
|
+
allowedQualities,
|
|
71
|
+
"quality"
|
|
72
|
+
);
|
|
73
|
+
const accept = _nullishCoalesce(request.headers.get("accept"), () => ( ""));
|
|
74
|
+
const negotiatedFormat = _nullishCoalesce(selectOutputFormat(accept, config.formats), () => ( ""));
|
|
75
|
+
const cacheKey = `${sourceUrl.href}
|
|
76
|
+
${width}
|
|
77
|
+
${quality}
|
|
78
|
+
${negotiatedFormat}`;
|
|
79
|
+
let optimized = cache.get(cacheKey);
|
|
80
|
+
if (!optimized) {
|
|
81
|
+
optimized = await runCoalesced(inflight, cacheKey, request.signal, async (signal) => {
|
|
82
|
+
const fetchedSource = await fetchImageSource(
|
|
83
|
+
sourceUrl,
|
|
84
|
+
requestUrl.origin,
|
|
85
|
+
trustedLocalOrigin,
|
|
86
|
+
config,
|
|
87
|
+
fetcher,
|
|
88
|
+
options.fetchRemote,
|
|
89
|
+
options.validateRemoteUrl,
|
|
90
|
+
signal
|
|
91
|
+
);
|
|
92
|
+
const source = await readResponseWithLimit(
|
|
93
|
+
fetchedSource.response,
|
|
94
|
+
config.maximumResponseBody
|
|
95
|
+
);
|
|
96
|
+
const sourceType = detectImageContentType(source);
|
|
97
|
+
validateSourceType(sourceType, config);
|
|
98
|
+
throwIfAborted(signal);
|
|
99
|
+
const result = await options.transform({
|
|
100
|
+
source,
|
|
101
|
+
sourceUrl: fetchedSource.url,
|
|
102
|
+
sourceType,
|
|
103
|
+
width,
|
|
104
|
+
quality,
|
|
105
|
+
accept,
|
|
106
|
+
formats: config.formats,
|
|
107
|
+
signal,
|
|
108
|
+
maximumResponseBody: config.maximumResponseBody
|
|
109
|
+
});
|
|
110
|
+
throwIfAborted(signal);
|
|
111
|
+
validateTransformedResult(result, config);
|
|
112
|
+
const entry = {
|
|
113
|
+
...result,
|
|
114
|
+
etag: createImageEtag(result.body),
|
|
115
|
+
cacheControl: `public, max-age=${config.minimumCacheTTL}, stale-while-revalidate=${Math.max(
|
|
116
|
+
config.minimumCacheTTL,
|
|
117
|
+
60
|
|
118
|
+
)}`,
|
|
119
|
+
expiresAt: Date.now() + config.minimumCacheTTL * 1e3
|
|
120
|
+
};
|
|
121
|
+
cache.set(cacheKey, entry);
|
|
122
|
+
return entry;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return createOptimizedImageResponse(request, optimized, config);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (!(error instanceof FarmImageRequestError) && !isAbortError(error)) {
|
|
128
|
+
try {
|
|
129
|
+
_optionalChain([options, 'access', _2 => _2.onError, 'optionalCall', _3 => _3(error, request)]);
|
|
130
|
+
} catch (e) {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return createFarmImageErrorResponse(error);
|
|
134
|
+
}
|
|
135
|
+
}, "handleFarmImage");
|
|
136
|
+
}
|
|
137
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, createFarmImageHandler, "createFarmImageHandler");
|
|
138
|
+
var DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT = 10 * 1024 * 1024;
|
|
139
|
+
function createCloudflareImageTransformer(fetcher = globalThis.fetch) {
|
|
140
|
+
return async ({ sourceUrl, width, quality, accept, formats, signal, maximumResponseBody }) => {
|
|
141
|
+
const format = selectOutputFormat(accept, formats);
|
|
142
|
+
const response = await fetcher(sourceUrl, {
|
|
143
|
+
signal,
|
|
144
|
+
redirect: "manual",
|
|
145
|
+
headers: { accept: "image/*" },
|
|
146
|
+
cf: {
|
|
147
|
+
image: {
|
|
148
|
+
fit: "scale-down",
|
|
149
|
+
width,
|
|
150
|
+
quality,
|
|
151
|
+
...format ? { format: format === "image/avif" ? "avif" : "webp" } : {}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
if (response.status >= 300 && response.status < 400) {
|
|
156
|
+
void cancelResponseBody(response);
|
|
157
|
+
throw new FarmImageRequestError(
|
|
158
|
+
"UNSUPPORTED_IMAGE",
|
|
159
|
+
502,
|
|
160
|
+
"Source image redirected after validation"
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (!response.ok) {
|
|
164
|
+
throw new FarmImageRequestError(
|
|
165
|
+
"UNSUPPORTED_IMAGE",
|
|
166
|
+
response.status === 404 ? 404 : 502,
|
|
167
|
+
"Cloudflare could not transform the source image"
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
const body = await readResponseWithLimit(
|
|
171
|
+
response,
|
|
172
|
+
_nullishCoalesce(maximumResponseBody, () => ( DEFAULT_IMAGE_TRANSFORM_BODY_LIMIT))
|
|
173
|
+
);
|
|
174
|
+
return {
|
|
175
|
+
body,
|
|
176
|
+
contentType: normalizeImageContentType(response.headers.get("content-type")) || detectImageContentType(body)
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, createCloudflareImageTransformer, "createCloudflareImageTransformer");
|
|
181
|
+
function selectOutputFormat(accept, formats) {
|
|
182
|
+
const qualityByFormat = /* @__PURE__ */ new Map();
|
|
183
|
+
for (const range of accept.split(",")) {
|
|
184
|
+
const [rawType, ...parameters] = range.split(";");
|
|
185
|
+
const type = rawType.trim().toLowerCase();
|
|
186
|
+
if (!type) continue;
|
|
187
|
+
let quality = 1;
|
|
188
|
+
for (const parameter of parameters) {
|
|
189
|
+
const [rawName, rawValue] = parameter.split("=", 2);
|
|
190
|
+
if (rawName.trim().toLowerCase() !== "q") continue;
|
|
191
|
+
const parsed = Number(_optionalChain([rawValue, 'optionalAccess', _4 => _4.trim, 'call', _5 => _5()]));
|
|
192
|
+
quality = Number.isFinite(parsed) && parsed >= 0 && parsed <= 1 ? parsed : 0;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
qualityByFormat.set(type, Math.max(_nullishCoalesce(qualityByFormat.get(type), () => ( 0)), quality));
|
|
196
|
+
}
|
|
197
|
+
let selected;
|
|
198
|
+
let selectedQuality = 0;
|
|
199
|
+
for (const format of formats) {
|
|
200
|
+
const quality = _nullishCoalesce(qualityByFormat.get(format), () => ( 0));
|
|
201
|
+
if (quality > selectedQuality) {
|
|
202
|
+
selected = format;
|
|
203
|
+
selectedQuality = quality;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return selected;
|
|
207
|
+
}
|
|
208
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, selectOutputFormat, "selectOutputFormat");
|
|
209
|
+
function parseIpv6Hextets(value) {
|
|
210
|
+
let text = _nullishCoalesce(value.split("%", 1)[0], () => ( ""));
|
|
211
|
+
if (!text.includes(":")) return null;
|
|
212
|
+
let tail = [];
|
|
213
|
+
const lastColon = text.lastIndexOf(":");
|
|
214
|
+
const candidate = text.slice(lastColon + 1);
|
|
215
|
+
if (candidate.includes(".")) {
|
|
216
|
+
const octets = parseIpv4Octets(candidate);
|
|
217
|
+
if (!octets) return null;
|
|
218
|
+
tail = [octets[0] << 8 | octets[1], octets[2] << 8 | octets[3]];
|
|
219
|
+
text = text.slice(0, lastColon);
|
|
220
|
+
if (text === "") return null;
|
|
221
|
+
}
|
|
222
|
+
const compressionParts = text.split("::");
|
|
223
|
+
if (compressionParts.length > 2) return null;
|
|
224
|
+
const parseGroup = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, (group) => {
|
|
225
|
+
if (group === "") return [];
|
|
226
|
+
const hextets = [];
|
|
227
|
+
for (const part of group.split(":")) {
|
|
228
|
+
if (!/^[0-9a-f]{1,4}$/.test(part)) return null;
|
|
229
|
+
hextets.push(Number.parseInt(part, 16));
|
|
230
|
+
}
|
|
231
|
+
return hextets;
|
|
232
|
+
}, "parseGroup");
|
|
233
|
+
const head = parseGroup(_nullishCoalesce(compressionParts[0], () => ( "")));
|
|
234
|
+
const rest = parseGroup(_nullishCoalesce(compressionParts[1], () => ( "")));
|
|
235
|
+
if (!head || !rest) return null;
|
|
236
|
+
const explicit = [...head, ...rest, ...tail];
|
|
237
|
+
if (compressionParts.length === 1) {
|
|
238
|
+
return explicit.length === 8 ? explicit : null;
|
|
239
|
+
}
|
|
240
|
+
if (explicit.length >= 8) return null;
|
|
241
|
+
const zeros = Array.from({ length: 8 - explicit.length }, () => 0);
|
|
242
|
+
return [...head, ...zeros, ...rest, ...tail];
|
|
243
|
+
}
|
|
244
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, parseIpv6Hextets, "parseIpv6Hextets");
|
|
245
|
+
function parseIpv4Octets(value) {
|
|
246
|
+
const parts = value.split(".");
|
|
247
|
+
if (parts.length !== 4 || parts.some((part) => !/^\d{1,3}$/.test(part))) return null;
|
|
248
|
+
const octets = parts.map(Number);
|
|
249
|
+
return octets.some((part) => part > 255) ? null : octets;
|
|
250
|
+
}
|
|
251
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, parseIpv4Octets, "parseIpv4Octets");
|
|
252
|
+
function isPrivateIpv4(octets) {
|
|
253
|
+
const [a, b] = octets;
|
|
254
|
+
return a === 0 || a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31 || a === 192 && (b === 0 || b === 168) || a === 198 && (b === 18 || b === 19) || a >= 224;
|
|
255
|
+
}
|
|
256
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, isPrivateIpv4, "isPrivateIpv4");
|
|
257
|
+
function isPrivateImageAddress(address) {
|
|
258
|
+
const value = address.trim().toLowerCase().replace(/^\[|\]$/g, "");
|
|
259
|
+
const hextets = parseIpv6Hextets(value);
|
|
260
|
+
if (hextets) {
|
|
261
|
+
const [h0, h1, h2, h3, h4, h5, h6, h7] = hextets;
|
|
262
|
+
const zeroPrefix = h0 === 0 && h1 === 0 && h2 === 0 && h3 === 0;
|
|
263
|
+
const embedsIpv4 = zeroPrefix && (h4 === 0 && h5 === 65535 || h4 === 65535 && h5 === 0 || h4 === 0 && h5 === 0);
|
|
264
|
+
if (embedsIpv4 && (h6 !== 0 || h7 !== 0)) {
|
|
265
|
+
return isPrivateIpv4([h6 >> 8, h6 & 255, h7 >> 8, h7 & 255]);
|
|
266
|
+
}
|
|
267
|
+
if (zeroPrefix && h4 === 0 && h5 === 0 && h6 === 0 && (h7 === 0 || h7 === 1)) return true;
|
|
268
|
+
if ((h0 & 65024) === 64512) return true;
|
|
269
|
+
if ((h0 & 65472) === 65152) return true;
|
|
270
|
+
if ((h0 & 65280) === 65280) return true;
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
const octets = parseIpv4Octets(value);
|
|
274
|
+
return octets ? isPrivateIpv4(octets) : false;
|
|
275
|
+
}
|
|
276
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, isPrivateImageAddress, "isPrivateImageAddress");
|
|
277
|
+
function parseAllowedInteger(raw, allowed, name) {
|
|
278
|
+
if (!raw || !/^\d+$/.test(raw)) {
|
|
279
|
+
throw new FarmImageRequestError(
|
|
280
|
+
"INVALID_PARAMETER",
|
|
281
|
+
400,
|
|
282
|
+
`Image ${name} must be an allowed integer`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
const value = Number(raw);
|
|
286
|
+
if (!allowed.has(value)) {
|
|
287
|
+
throw new FarmImageRequestError("INVALID_PARAMETER", 400, `Image ${name} is not configured`);
|
|
288
|
+
}
|
|
289
|
+
return value;
|
|
290
|
+
}
|
|
291
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, parseAllowedInteger, "parseAllowedInteger");
|
|
292
|
+
async function resolveImageSourceUrl(requestUrl, trustedLocalOrigin, config, validateRemoteUrl) {
|
|
293
|
+
const raw = requestUrl.searchParams.get("url");
|
|
294
|
+
if (!raw || raw.length > 4096 || raw.startsWith("//")) {
|
|
295
|
+
throw new FarmImageRequestError("INVALID_PARAMETER", 400, "Invalid image source URL");
|
|
296
|
+
}
|
|
297
|
+
let sourceUrl;
|
|
298
|
+
try {
|
|
299
|
+
sourceUrl = raw.startsWith("/") ? new URL(raw, _nullishCoalesce(trustedLocalOrigin, () => ( requestUrl.origin))) : new URL(raw);
|
|
300
|
+
} catch (e2) {
|
|
301
|
+
throw new FarmImageRequestError("INVALID_PARAMETER", 400, "Invalid image source URL");
|
|
302
|
+
}
|
|
303
|
+
await validateImageSourceUrl(
|
|
304
|
+
sourceUrl,
|
|
305
|
+
requestUrl.origin,
|
|
306
|
+
trustedLocalOrigin,
|
|
307
|
+
config,
|
|
308
|
+
validateRemoteUrl
|
|
309
|
+
);
|
|
310
|
+
return sourceUrl;
|
|
311
|
+
}
|
|
312
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, resolveImageSourceUrl, "resolveImageSourceUrl");
|
|
313
|
+
async function validateImageSourceUrl(sourceUrl, requestOrigin, trustedLocalOrigin, config, validateRemoteUrl) {
|
|
314
|
+
if (sourceUrl.protocol !== "http:" && sourceUrl.protocol !== "https:") {
|
|
315
|
+
throw new FarmImageRequestError("DISALLOWED_SOURCE", 400, "Unsupported image protocol");
|
|
316
|
+
}
|
|
317
|
+
if (sourceUrl.username || sourceUrl.password || sourceUrl.hash) {
|
|
318
|
+
throw new FarmImageRequestError("DISALLOWED_SOURCE", 400, "Unsafe image source URL");
|
|
319
|
+
}
|
|
320
|
+
const isLocalSource = sourceUrl.origin === requestOrigin || sourceUrl.origin === trustedLocalOrigin;
|
|
321
|
+
if (isLocalSource) {
|
|
322
|
+
if (sourceUrl.pathname === config.path || !matchesLocalPatterns(sourceUrl, config.localPatterns)) {
|
|
323
|
+
throw new FarmImageRequestError(
|
|
324
|
+
"DISALLOWED_SOURCE",
|
|
325
|
+
400,
|
|
326
|
+
"Local image source is not allowed"
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
if (sourceUrl.origin === trustedLocalOrigin) return;
|
|
330
|
+
} else if (!matchesRemoteSource(sourceUrl, config)) {
|
|
331
|
+
throw new FarmImageRequestError("DISALLOWED_SOURCE", 400, "Remote image source is not allowed");
|
|
332
|
+
}
|
|
333
|
+
if (!config.dangerouslyAllowLocalIP && isPrivateImageAddress(sourceUrl.hostname)) {
|
|
334
|
+
throw new FarmImageRequestError("PRIVATE_SOURCE", 400, "Private image source is not allowed");
|
|
335
|
+
}
|
|
336
|
+
if (!config.dangerouslyAllowLocalIP) {
|
|
337
|
+
await _optionalChain([validateRemoteUrl, 'optionalCall', _6 => _6(sourceUrl)]);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, validateImageSourceUrl, "validateImageSourceUrl");
|
|
341
|
+
async function fetchImageSource(initialUrl, requestOrigin, trustedLocalOrigin, config, fetcher, fetchRemote, validateRemoteUrl, signal) {
|
|
342
|
+
let currentUrl = initialUrl;
|
|
343
|
+
for (let redirectCount = 0; ; redirectCount += 1) {
|
|
344
|
+
throwIfAborted(signal);
|
|
345
|
+
const sourceFetcher = currentUrl.origin === trustedLocalOrigin ? fetcher : _nullishCoalesce(fetchRemote, () => ( fetcher));
|
|
346
|
+
const response = await sourceFetcher(currentUrl, {
|
|
347
|
+
method: "GET",
|
|
348
|
+
redirect: "manual",
|
|
349
|
+
signal,
|
|
350
|
+
headers: {
|
|
351
|
+
accept: "image/avif,image/webp,image/*,*/*;q=0.8",
|
|
352
|
+
"user-agent": "Farm.js Image Optimizer"
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
if (![301, 302, 303, 307, 308].includes(response.status)) {
|
|
356
|
+
if (!response.ok) {
|
|
357
|
+
await cancelResponseBody(response);
|
|
358
|
+
throw new FarmImageRequestError(
|
|
359
|
+
"UNSUPPORTED_IMAGE",
|
|
360
|
+
response.status === 404 ? 404 : 502,
|
|
361
|
+
"Could not fetch source image"
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
return { response, url: currentUrl };
|
|
365
|
+
}
|
|
366
|
+
if (redirectCount >= config.maximumRedirects) {
|
|
367
|
+
await cancelResponseBody(response);
|
|
368
|
+
throw new FarmImageRequestError(
|
|
369
|
+
"TOO_MANY_REDIRECTS",
|
|
370
|
+
400,
|
|
371
|
+
"Source image exceeded the redirect limit"
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
const location = response.headers.get("location");
|
|
375
|
+
if (!location) {
|
|
376
|
+
await cancelResponseBody(response);
|
|
377
|
+
throw new FarmImageRequestError("UNSUPPORTED_IMAGE", 502, "Invalid image redirect");
|
|
378
|
+
}
|
|
379
|
+
await cancelResponseBody(response);
|
|
380
|
+
currentUrl = new URL(location, currentUrl);
|
|
381
|
+
await validateImageSourceUrl(
|
|
382
|
+
currentUrl,
|
|
383
|
+
requestOrigin,
|
|
384
|
+
trustedLocalOrigin,
|
|
385
|
+
config,
|
|
386
|
+
validateRemoteUrl
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, fetchImageSource, "fetchImageSource");
|
|
391
|
+
function resolveTrustedLocalOrigin(configured) {
|
|
392
|
+
const value = typeof configured === "function" ? configured() : configured;
|
|
393
|
+
if (!value) return void 0;
|
|
394
|
+
const url = new URL(value);
|
|
395
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
396
|
+
throw new TypeError("trustedLocalOrigin must use http or https");
|
|
397
|
+
}
|
|
398
|
+
return url.origin;
|
|
399
|
+
}
|
|
400
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, resolveTrustedLocalOrigin, "resolveTrustedLocalOrigin");
|
|
401
|
+
async function runCoalesced(inflight, key, requestSignal, run) {
|
|
402
|
+
let entry = inflight.get(key);
|
|
403
|
+
if (!entry) {
|
|
404
|
+
const controller = new AbortController();
|
|
405
|
+
const created = {
|
|
406
|
+
controller,
|
|
407
|
+
waiters: 0,
|
|
408
|
+
promise: void 0
|
|
409
|
+
};
|
|
410
|
+
created.promise = run(controller.signal).finally(() => {
|
|
411
|
+
if (inflight.get(key) === created) inflight.delete(key);
|
|
412
|
+
});
|
|
413
|
+
created.promise.catch(() => {
|
|
414
|
+
});
|
|
415
|
+
inflight.set(key, created);
|
|
416
|
+
entry = created;
|
|
417
|
+
}
|
|
418
|
+
const pending = entry;
|
|
419
|
+
pending.waiters += 1;
|
|
420
|
+
try {
|
|
421
|
+
return await raceRequestAbort(pending.promise, requestSignal);
|
|
422
|
+
} finally {
|
|
423
|
+
pending.waiters -= 1;
|
|
424
|
+
if (pending.waiters === 0 && inflight.get(key) === pending) {
|
|
425
|
+
inflight.delete(key);
|
|
426
|
+
pending.controller.abort();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, runCoalesced, "runCoalesced");
|
|
431
|
+
function raceRequestAbort(promise, signal) {
|
|
432
|
+
if (!signal) return promise;
|
|
433
|
+
if (signal.aborted) return Promise.reject(_nullishCoalesce(signal.reason, () => ( new Error("Aborted"))));
|
|
434
|
+
return new Promise((resolve, reject) => {
|
|
435
|
+
const onAbort = /* @__PURE__ */ _chunkS3JO3N4Hcjs.__name.call(void 0, () => reject(_nullishCoalesce(signal.reason, () => ( new Error("Aborted")))), "onAbort");
|
|
436
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
437
|
+
promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, raceRequestAbort, "raceRequestAbort");
|
|
441
|
+
async function readResponseWithLimit(response, limit) {
|
|
442
|
+
const contentLength = response.headers.get("content-length");
|
|
443
|
+
if (contentLength && Number(contentLength) > limit) {
|
|
444
|
+
void cancelResponseBody(response);
|
|
445
|
+
throw new FarmImageRequestError("BODY_TOO_LARGE", 413, "Source image is too large");
|
|
446
|
+
}
|
|
447
|
+
if (!response.body) return new Uint8Array();
|
|
448
|
+
const reader = response.body.getReader();
|
|
449
|
+
const chunks = [];
|
|
450
|
+
let byteLength = 0;
|
|
451
|
+
try {
|
|
452
|
+
while (true) {
|
|
453
|
+
const { done, value } = await reader.read();
|
|
454
|
+
if (done) break;
|
|
455
|
+
byteLength += value.byteLength;
|
|
456
|
+
if (byteLength > limit) {
|
|
457
|
+
const error = new FarmImageRequestError("BODY_TOO_LARGE", 413, "Source image is too large");
|
|
458
|
+
void reader.cancel(error).catch(() => {
|
|
459
|
+
});
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
chunks.push(value);
|
|
463
|
+
}
|
|
464
|
+
} finally {
|
|
465
|
+
reader.releaseLock();
|
|
466
|
+
}
|
|
467
|
+
const result = new Uint8Array(byteLength);
|
|
468
|
+
let offset = 0;
|
|
469
|
+
for (const chunk of chunks) {
|
|
470
|
+
result.set(chunk, offset);
|
|
471
|
+
offset += chunk.byteLength;
|
|
472
|
+
}
|
|
473
|
+
return result;
|
|
474
|
+
}
|
|
475
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, readResponseWithLimit, "readResponseWithLimit");
|
|
476
|
+
async function cancelResponseBody(response) {
|
|
477
|
+
try {
|
|
478
|
+
await _optionalChain([response, 'access', _7 => _7.body, 'optionalAccess', _8 => _8.cancel, 'call', _9 => _9()]);
|
|
479
|
+
} catch (e3) {
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, cancelResponseBody, "cancelResponseBody");
|
|
483
|
+
function detectImageContentType(bytes) {
|
|
484
|
+
if (bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) {
|
|
485
|
+
return "image/png";
|
|
486
|
+
}
|
|
487
|
+
if (bytes.length >= 3 && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) {
|
|
488
|
+
return "image/jpeg";
|
|
489
|
+
}
|
|
490
|
+
if (bytes.length >= 6) {
|
|
491
|
+
const signature = new TextDecoder().decode(bytes.slice(0, 6));
|
|
492
|
+
if (signature === "GIF87a" || signature === "GIF89a") return "image/gif";
|
|
493
|
+
}
|
|
494
|
+
if (bytes.length >= 12) {
|
|
495
|
+
const riff = new TextDecoder().decode(bytes.slice(0, 4));
|
|
496
|
+
const webp = new TextDecoder().decode(bytes.slice(8, 12));
|
|
497
|
+
if (riff === "RIFF" && webp === "WEBP") return "image/webp";
|
|
498
|
+
const box = new TextDecoder().decode(bytes.slice(4, 12));
|
|
499
|
+
if (box.startsWith("ftypavif") || box.startsWith("ftypavis")) return "image/avif";
|
|
500
|
+
}
|
|
501
|
+
const prefix = new TextDecoder().decode(bytes.slice(0, 512)).trimStart().toLowerCase();
|
|
502
|
+
if (prefix.startsWith("<svg") || prefix.startsWith("<?xml") && prefix.includes("<svg")) {
|
|
503
|
+
return "image/svg+xml";
|
|
504
|
+
}
|
|
505
|
+
return "";
|
|
506
|
+
}
|
|
507
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, detectImageContentType, "detectImageContentType");
|
|
508
|
+
function validateSourceType(type, config) {
|
|
509
|
+
if (!type || type === "image/svg+xml" && !config.dangerouslyAllowSVG) {
|
|
510
|
+
throw new FarmImageRequestError("UNSUPPORTED_IMAGE", 415, "Unsupported source image");
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, validateSourceType, "validateSourceType");
|
|
514
|
+
function validateTransformedResult(result, config) {
|
|
515
|
+
if (!(result.body instanceof Uint8Array) || result.body.byteLength === 0) {
|
|
516
|
+
throw new Error("The image transformer returned an empty response");
|
|
517
|
+
}
|
|
518
|
+
if (result.body.byteLength > config.maximumResponseBody) {
|
|
519
|
+
throw new FarmImageRequestError("BODY_TOO_LARGE", 413, "Optimized image is too large");
|
|
520
|
+
}
|
|
521
|
+
const contentType = normalizeImageContentType(result.contentType);
|
|
522
|
+
if (!contentType || contentType === "image/svg+xml" && !config.dangerouslyAllowSVG) {
|
|
523
|
+
throw new Error("The image transformer returned an unsupported content type");
|
|
524
|
+
}
|
|
525
|
+
result.contentType = contentType;
|
|
526
|
+
}
|
|
527
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, validateTransformedResult, "validateTransformedResult");
|
|
528
|
+
function normalizeImageContentType(value) {
|
|
529
|
+
const type = _nullishCoalesce(_optionalChain([value, 'optionalAccess', _10 => _10.split, 'call', _11 => _11(";", 1), 'access', _12 => _12[0], 'access', _13 => _13.trim, 'call', _14 => _14(), 'access', _15 => _15.toLowerCase, 'call', _16 => _16()]), () => ( ""));
|
|
530
|
+
return type.startsWith("image/") ? type : "";
|
|
531
|
+
}
|
|
532
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, normalizeImageContentType, "normalizeImageContentType");
|
|
533
|
+
function matchesRemoteSource(url, config) {
|
|
534
|
+
if (config.domains.includes(url.hostname.toLowerCase())) return true;
|
|
535
|
+
return config.remotePatterns.some((pattern) => matchesRemotePattern(url, pattern));
|
|
536
|
+
}
|
|
537
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, matchesRemoteSource, "matchesRemoteSource");
|
|
538
|
+
function matchesRemotePattern(url, pattern) {
|
|
539
|
+
return (!pattern.protocol || url.protocol === `${pattern.protocol}:`) && matchesHostname(url.hostname, pattern.hostname) && (pattern.port === void 0 || url.port === pattern.port) && matchesImagePathPattern(url.pathname, pattern) && (pattern.search === void 0 || url.search === pattern.search);
|
|
540
|
+
}
|
|
541
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, matchesRemotePattern, "matchesRemotePattern");
|
|
542
|
+
function matchesLocalPatterns(url, patterns) {
|
|
543
|
+
return patterns.some(
|
|
544
|
+
(pattern) => matchesImagePathPattern(url.pathname, pattern) && (pattern.search === void 0 || url.search === pattern.search)
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, matchesLocalPatterns, "matchesLocalPatterns");
|
|
548
|
+
function matchesHostname(hostname, pattern) {
|
|
549
|
+
const normalizedHostname = hostname.toLowerCase();
|
|
550
|
+
const normalizedPattern = pattern.toLowerCase();
|
|
551
|
+
if (normalizedPattern.startsWith("**.")) {
|
|
552
|
+
const suffix = normalizedPattern.slice(3);
|
|
553
|
+
return normalizedHostname === suffix || normalizedHostname.endsWith(`.${suffix}`);
|
|
554
|
+
}
|
|
555
|
+
if (normalizedPattern.startsWith("*.")) {
|
|
556
|
+
const suffix = normalizedPattern.slice(2);
|
|
557
|
+
const prefix = normalizedHostname.slice(0, -(suffix.length + 1));
|
|
558
|
+
return normalizedHostname.endsWith(`.${suffix}`) && !!prefix && !prefix.includes(".");
|
|
559
|
+
}
|
|
560
|
+
return normalizedHostname === normalizedPattern;
|
|
561
|
+
}
|
|
562
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, matchesHostname, "matchesHostname");
|
|
563
|
+
function createOptimizedImageResponse(request, image, config) {
|
|
564
|
+
const headers = new Headers({
|
|
565
|
+
"cache-control": image.cacheControl,
|
|
566
|
+
"content-type": image.contentType,
|
|
567
|
+
"content-length": String(image.body.byteLength),
|
|
568
|
+
"content-disposition": "inline",
|
|
569
|
+
etag: image.etag,
|
|
570
|
+
vary: "Accept",
|
|
571
|
+
"x-content-type-options": "nosniff"
|
|
572
|
+
});
|
|
573
|
+
if (image.contentType === "image/svg+xml" && config.dangerouslyAllowSVG) {
|
|
574
|
+
headers.set("content-security-policy", "default-src 'none'; sandbox");
|
|
575
|
+
}
|
|
576
|
+
if (_chunkEM6SBQKMcjs.matchesFarmIfNoneMatch.call(void 0, request.headers.get("if-none-match"), image.etag)) {
|
|
577
|
+
headers.delete("content-length");
|
|
578
|
+
return new Response(null, { status: 304, headers });
|
|
579
|
+
}
|
|
580
|
+
const body = request.method === "HEAD" ? null : image.body.buffer.slice(
|
|
581
|
+
image.body.byteOffset,
|
|
582
|
+
image.body.byteOffset + image.body.byteLength
|
|
583
|
+
);
|
|
584
|
+
return new Response(body, { status: 200, headers });
|
|
585
|
+
}
|
|
586
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, createOptimizedImageResponse, "createOptimizedImageResponse");
|
|
587
|
+
function createFarmImageErrorResponse(error) {
|
|
588
|
+
const status = error instanceof FarmImageRequestError ? error.status : isAbortError(error) ? 499 : 500;
|
|
589
|
+
const headers = new Headers({
|
|
590
|
+
"cache-control": "no-store",
|
|
591
|
+
"content-type": "text/plain; charset=utf-8",
|
|
592
|
+
"x-content-type-options": "nosniff"
|
|
593
|
+
});
|
|
594
|
+
if (status === 405) headers.set("allow", "GET, HEAD");
|
|
595
|
+
const message = status === 400 ? "Invalid image request" : status === 404 ? "Image not found" : status === 405 ? "Method not allowed" : status === 413 ? "Image is too large" : status === 415 ? "Unsupported image" : status === 499 ? "Image request cancelled" : "Image optimization failed";
|
|
596
|
+
return new Response(message, { status, headers });
|
|
597
|
+
}
|
|
598
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, createFarmImageErrorResponse, "createFarmImageErrorResponse");
|
|
599
|
+
function createImageEtag(bytes) {
|
|
600
|
+
let hash = 2166136261;
|
|
601
|
+
for (const byte of bytes) {
|
|
602
|
+
hash ^= byte;
|
|
603
|
+
hash = Math.imul(hash, 16777619);
|
|
604
|
+
}
|
|
605
|
+
return `W/"farm-${bytes.byteLength.toString(16)}-${(hash >>> 0).toString(16)}"`;
|
|
606
|
+
}
|
|
607
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, createImageEtag, "createImageEtag");
|
|
608
|
+
function throwIfAborted(signal) {
|
|
609
|
+
if (signal.aborted) {
|
|
610
|
+
throw signal.reason instanceof Error ? signal.reason : new DOMException("The image request was aborted", "AbortError");
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, throwIfAborted, "throwIfAborted");
|
|
614
|
+
function isAbortError(error) {
|
|
615
|
+
return error instanceof Error && error.name === "AbortError";
|
|
616
|
+
}
|
|
617
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, isAbortError, "isAbortError");
|
|
618
|
+
var _FarmImageMemoryCache = class _FarmImageMemoryCache {
|
|
619
|
+
constructor(capacity) {
|
|
620
|
+
this.capacity = capacity;
|
|
621
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
622
|
+
}
|
|
623
|
+
get(key) {
|
|
624
|
+
const value = this.entries.get(key);
|
|
625
|
+
if (!value) return void 0;
|
|
626
|
+
if (value.expiresAt <= Date.now()) {
|
|
627
|
+
this.entries.delete(key);
|
|
628
|
+
return void 0;
|
|
629
|
+
}
|
|
630
|
+
this.entries.delete(key);
|
|
631
|
+
this.entries.set(key, value);
|
|
632
|
+
return value;
|
|
633
|
+
}
|
|
634
|
+
set(key, value) {
|
|
635
|
+
if (this.capacity <= 0) return;
|
|
636
|
+
this.entries.delete(key);
|
|
637
|
+
this.entries.set(key, value);
|
|
638
|
+
while (this.entries.size > this.capacity) {
|
|
639
|
+
const oldestKey = this.entries.keys().next().value;
|
|
640
|
+
if (oldestKey === void 0) break;
|
|
641
|
+
this.entries.delete(oldestKey);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
_chunkS3JO3N4Hcjs.__name.call(void 0, _FarmImageMemoryCache, "FarmImageMemoryCache");
|
|
646
|
+
var FarmImageMemoryCache = _FarmImageMemoryCache;
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
exports.FarmImageRequestError = FarmImageRequestError; exports.createFarmImageHandler = createFarmImageHandler; exports.createCloudflareImageTransformer = createCloudflareImageTransformer; exports.selectOutputFormat = selectOutputFormat; exports.isPrivateImageAddress = isPrivateImageAddress;
|