@openuiai/next 16.2.0 → 16.3.0

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.
Files changed (221) hide show
  1. package/dist/bin/next +2 -2
  2. package/dist/build/get-babel-loader-config.js +1 -1
  3. package/dist/build/get-babel-loader-config.js.map +1 -1
  4. package/dist/build/index.js +3 -3
  5. package/dist/build/webpack-config.js +6 -4
  6. package/dist/build/webpack-config.js.map +1 -1
  7. package/dist/cache/cache-control.js +22 -0
  8. package/dist/cache/cache-control.js.map +1 -0
  9. package/dist/cache/clone-response.js +77 -0
  10. package/dist/cache/clone-response.js.map +1 -0
  11. package/dist/cache/dedupe-fetch.js +123 -0
  12. package/dist/cache/dedupe-fetch.js.map +1 -0
  13. package/dist/cache/lazy-result.js +46 -0
  14. package/dist/cache/lazy-result.js.map +1 -0
  15. package/dist/cache/lru-cache.js +177 -0
  16. package/dist/cache/lru-cache.js.map +1 -0
  17. package/dist/client/app-bootstrap.js +1 -1
  18. package/dist/client/index.js +1 -1
  19. package/dist/compiled/next-server/server.runtime.prod.js.map +1 -1
  20. package/dist/concurrency/batcher.js +65 -0
  21. package/dist/concurrency/batcher.js.map +1 -0
  22. package/dist/concurrency/coalesced-function.js +39 -0
  23. package/dist/concurrency/coalesced-function.js.map +1 -0
  24. package/dist/concurrency/scheduler.js +64 -0
  25. package/dist/concurrency/scheduler.js.map +1 -0
  26. package/dist/concurrency/wait.js +19 -0
  27. package/dist/concurrency/wait.js.map +1 -0
  28. package/dist/concurrency/with-promise-cache.js +24 -0
  29. package/dist/concurrency/with-promise-cache.js.map +1 -0
  30. package/dist/config/detect-typo.js +51 -0
  31. package/dist/config/detect-typo.js.map +1 -0
  32. package/dist/config/find-config.js +102 -0
  33. package/dist/config/find-config.js.map +1 -0
  34. package/dist/config/get-package-version.js +118 -0
  35. package/dist/config/get-package-version.js.map +1 -0
  36. package/dist/config/get-project-dir.js +51 -0
  37. package/dist/config/get-project-dir.js.map +1 -0
  38. package/dist/config/install-dependencies.js +40 -0
  39. package/dist/config/install-dependencies.js.map +1 -0
  40. package/dist/config/needs-experimental-react.js +16 -0
  41. package/dist/config/needs-experimental-react.js.map +1 -0
  42. package/dist/config/static-env.js +92 -0
  43. package/dist/config/static-env.js.map +1 -0
  44. package/dist/constants/constants.js +397 -0
  45. package/dist/constants/constants.js.map +1 -0
  46. package/dist/errors/compile-error.js +14 -0
  47. package/dist/errors/compile-error.js.map +1 -0
  48. package/dist/errors/error-source.js +36 -0
  49. package/dist/errors/error-source.js.map +1 -0
  50. package/dist/errors/error-telemetry-utils.js +42 -0
  51. package/dist/errors/error-telemetry-utils.js.map +1 -0
  52. package/dist/errors/fatal-error.js +14 -0
  53. package/dist/errors/fatal-error.js.map +1 -0
  54. package/dist/errors/format-server-error.js +74 -0
  55. package/dist/errors/format-server-error.js.map +1 -0
  56. package/dist/errors/invariant-error.js +18 -0
  57. package/dist/errors/invariant-error.js.map +1 -0
  58. package/dist/errors/is-error.js +65 -0
  59. package/dist/errors/is-error.js.map +1 -0
  60. package/dist/errors/no-fallback-error.js +18 -0
  61. package/dist/errors/no-fallback-error.js.map +1 -0
  62. package/dist/esm/build/get-babel-loader-config.js +1 -1
  63. package/dist/esm/build/get-babel-loader-config.js.map +1 -1
  64. package/dist/esm/build/index.js +3 -3
  65. package/dist/esm/build/webpack-config.js +6 -4
  66. package/dist/esm/build/webpack-config.js.map +1 -1
  67. package/dist/esm/client/app-bootstrap.js +1 -1
  68. package/dist/esm/client/index.js +1 -1
  69. package/dist/esm/lib/metadata/resolvers/resolve-url.js +1 -1
  70. package/dist/esm/lib/metadata/resolvers/resolve-url.js.map +1 -1
  71. package/dist/esm/lib/worker.js +1 -1
  72. package/dist/esm/lib/worker.js.map +1 -1
  73. package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
  74. package/dist/esm/server/lib/app-info-log.js +1 -1
  75. package/dist/esm/server/lib/start-server.js +1 -1
  76. package/dist/esm/server/websocket/setup.js +1 -1
  77. package/dist/esm/server/websocket/setup.js.map +1 -1
  78. package/dist/esm/server/websocket/types.js +1 -1
  79. package/dist/esm/server/websocket/types.js.map +1 -1
  80. package/dist/esm/shared/lib/errors/canary-only-config-error.js +1 -1
  81. package/dist/filesystem/file-exists.js +53 -0
  82. package/dist/filesystem/file-exists.js.map +1 -0
  83. package/dist/filesystem/find-pages-dir.js +65 -0
  84. package/dist/filesystem/find-pages-dir.js.map +1 -0
  85. package/dist/filesystem/find-root.js +118 -0
  86. package/dist/filesystem/find-root.js.map +1 -0
  87. package/dist/filesystem/get-files-in-dir.js +33 -0
  88. package/dist/filesystem/get-files-in-dir.js.map +1 -0
  89. package/dist/filesystem/multi-file-writer.js +75 -0
  90. package/dist/filesystem/multi-file-writer.js.map +1 -0
  91. package/dist/filesystem/realpath.js +20 -0
  92. package/dist/filesystem/realpath.js.map +1 -0
  93. package/dist/filesystem/recursive-copy.js +76 -0
  94. package/dist/filesystem/recursive-copy.js.map +1 -0
  95. package/dist/filesystem/recursive-delete.js +137 -0
  96. package/dist/filesystem/recursive-delete.js.map +1 -0
  97. package/dist/filesystem/recursive-readdir.js +124 -0
  98. package/dist/filesystem/recursive-readdir.js.map +1 -0
  99. package/dist/filesystem/rename.js +87 -0
  100. package/dist/filesystem/rename.js.map +1 -0
  101. package/dist/filesystem/write-atomic.js +28 -0
  102. package/dist/filesystem/write-atomic.js.map +1 -0
  103. package/dist/fonts/font-utils.js +43 -0
  104. package/dist/fonts/font-utils.js.map +1 -0
  105. package/dist/fonts/get-preloadable-fonts.js +39 -0
  106. package/dist/fonts/get-preloadable-fonts.js.map +1 -0
  107. package/dist/hash/bloom-filter.js +85 -0
  108. package/dist/hash/bloom-filter.js.map +1 -0
  109. package/dist/hash/etag.js +56 -0
  110. package/dist/hash/etag.js.map +1 -0
  111. package/dist/hash/fnv1a.js +56 -0
  112. package/dist/hash/fnv1a.js.map +1 -0
  113. package/dist/hash/hash.js +39 -0
  114. package/dist/hash/hash.js.map +1 -0
  115. package/dist/hostname/format-hostname.js +16 -0
  116. package/dist/hostname/format-hostname.js.map +1 -0
  117. package/dist/hostname/get-hostname.js +23 -0
  118. package/dist/hostname/get-hostname.js.map +1 -0
  119. package/dist/hostname/get-network-host.js +44 -0
  120. package/dist/hostname/get-network-host.js.map +1 -0
  121. package/dist/hostname/is-ipv6.js +41 -0
  122. package/dist/hostname/is-ipv6.js.map +1 -0
  123. package/dist/image/find-closest-quality.js +19 -0
  124. package/dist/image/find-closest-quality.js.map +1 -0
  125. package/dist/image/get-img-props.js +573 -0
  126. package/dist/image/get-img-props.js.map +1 -0
  127. package/dist/image/image-blur-svg.js +22 -0
  128. package/dist/image/image-blur-svg.js.map +1 -0
  129. package/dist/image/image-config-context.shared-runtime.js +19 -0
  130. package/dist/image/image-config-context.shared-runtime.js.map +1 -0
  131. package/dist/image/image-config.js +74 -0
  132. package/dist/image/image-config.js.map +1 -0
  133. package/dist/image/image-loader.js +91 -0
  134. package/dist/image/image-loader.js.map +1 -0
  135. package/dist/image/image-optimizer.js +1019 -0
  136. package/dist/image/image-optimizer.js.map +1 -0
  137. package/dist/image/match-local-pattern.js +46 -0
  138. package/dist/image/match-local-pattern.js.map +1 -0
  139. package/dist/image/match-remote-pattern.js +63 -0
  140. package/dist/image/match-remote-pattern.js.map +1 -0
  141. package/dist/image/mime-type.js +20 -0
  142. package/dist/image/mime-type.js.map +1 -0
  143. package/dist/lib/metadata/resolvers/resolve-url.js +1 -1
  144. package/dist/lib/metadata/resolvers/resolve-url.js.map +1 -1
  145. package/dist/lib/worker.js +1 -1
  146. package/dist/lib/worker.js.map +1 -1
  147. package/dist/memory/gc-observer.js +53 -0
  148. package/dist/memory/gc-observer.js.map +1 -0
  149. package/dist/memory/shutdown.js +29 -0
  150. package/dist/memory/shutdown.js.map +1 -0
  151. package/dist/memory/startup.js +47 -0
  152. package/dist/memory/startup.js.map +1 -0
  153. package/dist/memory/trace.js +109 -0
  154. package/dist/memory/trace.js.map +1 -0
  155. package/dist/module/client-and-server-references.js +54 -0
  156. package/dist/module/client-and-server-references.js.map +1 -0
  157. package/dist/module/format-dynamic-import-path.js +24 -0
  158. package/dist/module/format-dynamic-import-path.js.map +1 -0
  159. package/dist/module/interop-default.js +15 -0
  160. package/dist/module/interop-default.js.map +1 -0
  161. package/dist/module/resolve-from.js +79 -0
  162. package/dist/module/resolve-from.js.map +1 -0
  163. package/dist/module/semver-noop.js +18 -0
  164. package/dist/module/semver-noop.js.map +1 -0
  165. package/dist/object/deep-freeze.js +30 -0
  166. package/dist/object/deep-freeze.js.map +1 -0
  167. package/dist/object/deep-readonly.js +10 -0
  168. package/dist/object/deep-readonly.js.map +1 -0
  169. package/dist/object/is-plain-object.js +42 -0
  170. package/dist/object/is-plain-object.js.map +1 -0
  171. package/dist/object/non-nullable.js +15 -0
  172. package/dist/object/non-nullable.js.map +1 -0
  173. package/dist/object/pick.js +19 -0
  174. package/dist/object/pick.js.map +1 -0
  175. package/dist/process/setup-exception-listeners.js +11 -0
  176. package/dist/process/setup-exception-listeners.js.map +1 -0
  177. package/dist/promise/detached-promise.js +32 -0
  178. package/dist/promise/detached-promise.js.map +1 -0
  179. package/dist/promise/is-thenable.js +20 -0
  180. package/dist/promise/is-thenable.js.map +1 -0
  181. package/dist/promise/promise-with-resolvers.js +26 -0
  182. package/dist/promise/promise-with-resolvers.js.map +1 -0
  183. package/dist/server/dev/hot-reloader-webpack.js +1 -1
  184. package/dist/server/lib/app-info-log.js +1 -1
  185. package/dist/server/lib/start-server.js +1 -1
  186. package/dist/server/websocket/setup.js +1 -1
  187. package/dist/server/websocket/setup.js.map +1 -1
  188. package/dist/server/websocket/types.js +1 -1
  189. package/dist/server/websocket/types.js.map +1 -1
  190. package/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  191. package/dist/string/encode-uri-path.js +15 -0
  192. package/dist/string/encode-uri-path.js.map +1 -0
  193. package/dist/string/escape-regexp.js +22 -0
  194. package/dist/string/escape-regexp.js.map +1 -0
  195. package/dist/string/normalize-path.js +21 -0
  196. package/dist/string/normalize-path.js.map +1 -0
  197. package/dist/string/oxford-comma-list.js +15 -0
  198. package/dist/string/oxford-comma-list.js.map +1 -0
  199. package/dist/string/pretty-bytes.js +74 -0
  200. package/dist/string/pretty-bytes.js.map +1 -0
  201. package/dist/telemetry/anonymous-meta.js +1 -1
  202. package/dist/telemetry/events/session-stopped.js +2 -2
  203. package/dist/telemetry/events/version.js +2 -2
  204. package/dist/typescript/diagnosticFormatter.js +240 -0
  205. package/dist/typescript/diagnosticFormatter.js.map +1 -0
  206. package/dist/typescript/getTypeScriptConfiguration.js +73 -0
  207. package/dist/typescript/getTypeScriptConfiguration.js.map +1 -0
  208. package/dist/typescript/getTypeScriptIntent.js +52 -0
  209. package/dist/typescript/getTypeScriptIntent.js.map +1 -0
  210. package/dist/typescript/missingDependencyError.js +27 -0
  211. package/dist/typescript/missingDependencyError.js.map +1 -0
  212. package/dist/typescript/runTypeCheck.js +95 -0
  213. package/dist/typescript/runTypeCheck.js.map +1 -0
  214. package/dist/typescript/writeAppTypeDeclarations.js +65 -0
  215. package/dist/typescript/writeAppTypeDeclarations.js.map +1 -0
  216. package/dist/typescript/writeConfigurationDefaults.js +403 -0
  217. package/dist/typescript/writeConfigurationDefaults.js.map +1 -0
  218. package/dist/validation/is-serializable-props.js +106 -0
  219. package/dist/validation/is-serializable-props.js.map +1 -0
  220. package/index.d.ts +2 -2
  221. package/package.json +2 -1
@@ -0,0 +1,1019 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ 0 && (module.exports = {
6
+ ImageError: null,
7
+ ImageOptimizerCache: null,
8
+ detectContentType: null,
9
+ extractEtag: null,
10
+ fetchExternalImage: null,
11
+ fetchInternalImage: null,
12
+ getHash: null,
13
+ getImageEtag: null,
14
+ getImageSize: null,
15
+ getMaxAge: null,
16
+ getPreviouslyCachedImageOrNull: null,
17
+ getSharp: null,
18
+ imageOptimizer: null,
19
+ optimizeImage: null,
20
+ sendResponse: null
21
+ });
22
+ function _export(target, all) {
23
+ for(var name in all)Object.defineProperty(target, name, {
24
+ enumerable: true,
25
+ get: all[name]
26
+ });
27
+ }
28
+ _export(exports, {
29
+ ImageError: function() {
30
+ return ImageError;
31
+ },
32
+ ImageOptimizerCache: function() {
33
+ return ImageOptimizerCache;
34
+ },
35
+ detectContentType: function() {
36
+ return detectContentType;
37
+ },
38
+ extractEtag: function() {
39
+ return extractEtag;
40
+ },
41
+ fetchExternalImage: function() {
42
+ return fetchExternalImage;
43
+ },
44
+ fetchInternalImage: function() {
45
+ return fetchInternalImage;
46
+ },
47
+ getHash: function() {
48
+ return getHash;
49
+ },
50
+ getImageEtag: function() {
51
+ return getImageEtag;
52
+ },
53
+ getImageSize: function() {
54
+ return getImageSize;
55
+ },
56
+ getMaxAge: function() {
57
+ return getMaxAge;
58
+ },
59
+ getPreviouslyCachedImageOrNull: function() {
60
+ return getPreviouslyCachedImageOrNull;
61
+ },
62
+ getSharp: function() {
63
+ return getSharp;
64
+ },
65
+ imageOptimizer: function() {
66
+ return imageOptimizer;
67
+ },
68
+ optimizeImage: function() {
69
+ return optimizeImage;
70
+ },
71
+ sendResponse: function() {
72
+ return sendResponse;
73
+ }
74
+ });
75
+ const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
76
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
77
+ const _crypto = require("crypto");
78
+ const _fs = require("fs");
79
+ const _accept = require("next/dist/compiled/@hapi/accept");
80
+ const _contentdisposition = /*#__PURE__*/ _interop_require_default._(require("next/dist/compiled/content-disposition"));
81
+ const _imagesize = /*#__PURE__*/ _interop_require_default._(require("next/dist/compiled/image-size"));
82
+ const _detector = require("next/dist/compiled/image-detector/detector.js");
83
+ const _isanimated = /*#__PURE__*/ _interop_require_default._(require("next/dist/compiled/is-animated"));
84
+ const _islocaladdress = /*#__PURE__*/ _interop_require_default._(require("next/dist/compiled/is-local-address"));
85
+ const _path = require("path");
86
+ const _url = /*#__PURE__*/ _interop_require_default._(require("url"));
87
+ const _imageblursvg = require("./image-blur-svg");
88
+ const _matchlocalpattern = require("./match-local-pattern");
89
+ const _matchremotepattern = require("./match-remote-pattern");
90
+ const _mockrequest = require("../server/lib/mock-request");
91
+ const _responsecache = require("../server/response-cache");
92
+ const _sendpayload = require("../server/send-payload");
93
+ const _servestatic = require("../server/serve-static");
94
+ const _log = /*#__PURE__*/ _interop_require_wildcard._(require("../build/output/log"));
95
+ const _iserror = /*#__PURE__*/ _interop_require_default._(require("../lib/is-error"));
96
+ const _url1 = require("../lib/url");
97
+ const _invarianterror = require("../shared/lib/invariant-error");
98
+ const _promises = require("dns/promises");
99
+ const _net = require("net");
100
+ const _dns = require("dns");
101
+ const AVIF = 'image/avif';
102
+ const WEBP = 'image/webp';
103
+ const PNG = 'image/png';
104
+ const JPEG = 'image/jpeg';
105
+ const JXL = 'image/jxl';
106
+ const JP2 = 'image/jp2';
107
+ const HEIC = 'image/heic';
108
+ const GIF = 'image/gif';
109
+ const SVG = 'image/svg+xml';
110
+ const ICO = 'image/x-icon';
111
+ const ICNS = 'image/x-icns';
112
+ const TIFF = 'image/tiff';
113
+ const BMP = 'image/bmp';
114
+ const PDF = 'application/pdf';
115
+ const CACHE_VERSION = 4;
116
+ const ANIMATABLE_TYPES = [
117
+ WEBP,
118
+ PNG,
119
+ GIF
120
+ ];
121
+ const BYPASS_TYPES = [
122
+ SVG,
123
+ ICO,
124
+ ICNS,
125
+ BMP,
126
+ JXL,
127
+ HEIC
128
+ ];
129
+ const BLUR_IMG_SIZE = 8 // should match `next-image-loader`
130
+ ;
131
+ const BLUR_QUALITY = 70 // should match `next-image-loader`
132
+ ;
133
+ let _sharp;
134
+ function getSharp(concurrency) {
135
+ if (_sharp) {
136
+ return _sharp;
137
+ }
138
+ try {
139
+ _sharp = require('sharp');
140
+ if (_sharp && _sharp.concurrency() > 1) {
141
+ // Reducing concurrency should reduce the memory usage too.
142
+ // We more aggressively reduce in dev but also reduce in prod.
143
+ // https://sharp.pixelplumbing.com/api-utility#concurrency
144
+ const divisor = process.env.NODE_ENV === 'development' ? 4 : 2;
145
+ _sharp.concurrency(concurrency ?? Math.floor(Math.max(_sharp.concurrency() / divisor, 1)));
146
+ }
147
+ } catch (e) {
148
+ if ((0, _iserror.default)(e) && e.code === 'MODULE_NOT_FOUND') {
149
+ throw Object.defineProperty(new Error('Module `sharp` not found. Please run `npm install --cpu=wasm32 sharp` to install it.'), "__NEXT_ERROR_CODE", {
150
+ value: "E47",
151
+ enumerable: false,
152
+ configurable: true
153
+ });
154
+ }
155
+ throw e;
156
+ }
157
+ return _sharp;
158
+ }
159
+ function getSupportedMimeType(options, accept = '') {
160
+ const mimeType = (0, _accept.mediaType)(accept, options);
161
+ return accept.includes(mimeType) ? mimeType : '';
162
+ }
163
+ function getHash(items) {
164
+ const hash = (0, _crypto.createHash)('sha256');
165
+ for (let item of items){
166
+ if (typeof item === 'number') hash.update(String(item));
167
+ else {
168
+ hash.update(item);
169
+ }
170
+ }
171
+ // See https://en.wikipedia.org/wiki/Base64#URL_applications
172
+ return hash.digest('base64url');
173
+ }
174
+ function extractEtag(etag, imageBuffer) {
175
+ if (etag) {
176
+ // upstream etag needs to be base64url encoded due to weak etag signature
177
+ // as we store this in the cache-entry file name.
178
+ return Buffer.from(etag).toString('base64url');
179
+ }
180
+ return getImageEtag(imageBuffer);
181
+ }
182
+ function getImageEtag(image) {
183
+ return getHash([
184
+ image
185
+ ]);
186
+ }
187
+ async function writeToCacheDir(dir, extension, maxAge, expireAt, buffer, etag, upstreamEtag) {
188
+ const filename = (0, _path.join)(dir, `${maxAge}.${expireAt}.${etag}.${upstreamEtag}.${extension}`);
189
+ await _fs.promises.rm(dir, {
190
+ recursive: true,
191
+ force: true
192
+ }).catch(()=>{});
193
+ await _fs.promises.mkdir(dir, {
194
+ recursive: true
195
+ });
196
+ await _fs.promises.writeFile(filename, buffer);
197
+ }
198
+ async function detectContentType(buffer, skipMetadata, concurrency) {
199
+ if (buffer.byteLength === 0) {
200
+ return null;
201
+ }
202
+ if ([
203
+ 0xff,
204
+ 0xd8,
205
+ 0xff
206
+ ].every((b, i)=>buffer[i] === b)) {
207
+ return JPEG;
208
+ }
209
+ if ([
210
+ 0x89,
211
+ 0x50,
212
+ 0x4e,
213
+ 0x47,
214
+ 0x0d,
215
+ 0x0a,
216
+ 0x1a,
217
+ 0x0a
218
+ ].every((b, i)=>buffer[i] === b)) {
219
+ return PNG;
220
+ }
221
+ if ([
222
+ 0x47,
223
+ 0x49,
224
+ 0x46,
225
+ 0x38
226
+ ].every((b, i)=>buffer[i] === b)) {
227
+ return GIF;
228
+ }
229
+ if ([
230
+ 0x52,
231
+ 0x49,
232
+ 0x46,
233
+ 0x46,
234
+ 0,
235
+ 0,
236
+ 0,
237
+ 0,
238
+ 0x57,
239
+ 0x45,
240
+ 0x42,
241
+ 0x50
242
+ ].every((b, i)=>!b || buffer[i] === b)) {
243
+ return WEBP;
244
+ }
245
+ if ([
246
+ 0x3c,
247
+ 0x3f,
248
+ 0x78,
249
+ 0x6d,
250
+ 0x6c
251
+ ].every((b, i)=>buffer[i] === b)) {
252
+ return SVG;
253
+ }
254
+ if ([
255
+ 0x3c,
256
+ 0x73,
257
+ 0x76,
258
+ 0x67
259
+ ].every((b, i)=>buffer[i] === b)) {
260
+ return SVG;
261
+ }
262
+ if ([
263
+ 0,
264
+ 0,
265
+ 0,
266
+ 0,
267
+ 0x66,
268
+ 0x74,
269
+ 0x79,
270
+ 0x70,
271
+ 0x61,
272
+ 0x76,
273
+ 0x69,
274
+ 0x66
275
+ ].every((b, i)=>!b || buffer[i] === b)) {
276
+ return AVIF;
277
+ }
278
+ if ([
279
+ 0x00,
280
+ 0x00,
281
+ 0x01,
282
+ 0x00
283
+ ].every((b, i)=>buffer[i] === b)) {
284
+ return ICO;
285
+ }
286
+ if ([
287
+ 0x69,
288
+ 0x63,
289
+ 0x6e,
290
+ 0x73
291
+ ].every((b, i)=>buffer[i] === b)) {
292
+ return ICNS;
293
+ }
294
+ if ([
295
+ 0x49,
296
+ 0x49,
297
+ 0x2a,
298
+ 0x00
299
+ ].every((b, i)=>buffer[i] === b)) {
300
+ return TIFF;
301
+ }
302
+ if ([
303
+ 0x42,
304
+ 0x4d
305
+ ].every((b, i)=>buffer[i] === b)) {
306
+ return BMP;
307
+ }
308
+ if ([
309
+ 0xff,
310
+ 0x0a
311
+ ].every((b, i)=>buffer[i] === b)) {
312
+ return JXL;
313
+ }
314
+ if ([
315
+ 0x00,
316
+ 0x00,
317
+ 0x00,
318
+ 0x0c,
319
+ 0x4a,
320
+ 0x58,
321
+ 0x4c,
322
+ 0x20,
323
+ 0x0d,
324
+ 0x0a,
325
+ 0x87,
326
+ 0x0a
327
+ ].every((b, i)=>buffer[i] === b)) {
328
+ return JXL;
329
+ }
330
+ if ([
331
+ 0,
332
+ 0,
333
+ 0,
334
+ 0,
335
+ 0x66,
336
+ 0x74,
337
+ 0x79,
338
+ 0x70,
339
+ 0x68,
340
+ 0x65,
341
+ 0x69,
342
+ 0x63
343
+ ].every((b, i)=>!b || buffer[i] === b)) {
344
+ return HEIC;
345
+ }
346
+ if ([
347
+ 0x25,
348
+ 0x50,
349
+ 0x44,
350
+ 0x46,
351
+ 0x2d
352
+ ].every((b, i)=>buffer[i] === b)) {
353
+ return PDF;
354
+ }
355
+ if ([
356
+ 0x00,
357
+ 0x00,
358
+ 0x00,
359
+ 0x0c,
360
+ 0x6a,
361
+ 0x50,
362
+ 0x20,
363
+ 0x20,
364
+ 0x0d,
365
+ 0x0a,
366
+ 0x87,
367
+ 0x0a
368
+ ].every((b, i)=>buffer[i] === b)) {
369
+ return JP2;
370
+ }
371
+ let format;
372
+ format = (0, _detector.detector)(buffer);
373
+ if (!format && !skipMetadata) {
374
+ const sharp = getSharp(concurrency);
375
+ const meta = await sharp(buffer).metadata().catch((_)=>null);
376
+ format = meta?.format;
377
+ }
378
+ switch(format){
379
+ case 'avif':
380
+ return AVIF;
381
+ case 'webp':
382
+ return WEBP;
383
+ case 'png':
384
+ return PNG;
385
+ case 'jpeg':
386
+ case 'jpg':
387
+ return JPEG;
388
+ case 'gif':
389
+ return GIF;
390
+ case 'svg':
391
+ return SVG;
392
+ case 'jxl':
393
+ case 'jxl-stream':
394
+ return JXL;
395
+ case 'jp2':
396
+ return JP2;
397
+ case 'tiff':
398
+ case 'tif':
399
+ return TIFF;
400
+ case 'pdf':
401
+ return PDF;
402
+ case 'bmp':
403
+ return BMP;
404
+ case 'ico':
405
+ return ICO;
406
+ case 'icns':
407
+ return ICNS;
408
+ case 'dcraw':
409
+ case 'dz':
410
+ case 'exr':
411
+ case 'fits':
412
+ case 'heif':
413
+ case 'input':
414
+ case 'magick':
415
+ case 'openslide':
416
+ case 'ppm':
417
+ case 'rad':
418
+ case 'raw':
419
+ case 'v':
420
+ case 'cur':
421
+ case 'dds':
422
+ case 'j2c':
423
+ case 'ktx':
424
+ case 'pnm':
425
+ case 'psd':
426
+ case 'tga':
427
+ case undefined:
428
+ default:
429
+ return null;
430
+ }
431
+ }
432
+ class ImageOptimizerCache {
433
+ static validateParams(req, query, nextConfig, isDev) {
434
+ const imageData = nextConfig.images;
435
+ const { deviceSizes = [], imageSizes = [], domains = [], minimumCacheTTL = 14400, formats = [
436
+ 'image/webp'
437
+ ] } = imageData;
438
+ const remotePatterns = nextConfig.images?.remotePatterns || [];
439
+ const localPatterns = nextConfig.images?.localPatterns;
440
+ const qualities = nextConfig.images?.qualities;
441
+ const { url, w, q } = query;
442
+ let href;
443
+ if (domains.length > 0) {
444
+ _log.warnOnce('The "images.domains" configuration is deprecated. Please use "images.remotePatterns" configuration instead.');
445
+ }
446
+ if (!url) {
447
+ return {
448
+ errorMessage: '"url" parameter is required'
449
+ };
450
+ } else if (Array.isArray(url)) {
451
+ return {
452
+ errorMessage: '"url" parameter cannot be an array'
453
+ };
454
+ }
455
+ if (url.length > 3072) {
456
+ return {
457
+ errorMessage: '"url" parameter is too long'
458
+ };
459
+ }
460
+ if (url.startsWith('//')) {
461
+ return {
462
+ errorMessage: '"url" parameter cannot be a protocol-relative URL (//)'
463
+ };
464
+ }
465
+ let isAbsolute;
466
+ if (url.startsWith('/')) {
467
+ href = url;
468
+ isAbsolute = false;
469
+ if (/\/_next\/image($|\/)/.test(decodeURIComponent((0, _url1.parseUrl)(url)?.pathname ?? ''))) {
470
+ return {
471
+ errorMessage: '"url" parameter cannot be recursive'
472
+ };
473
+ }
474
+ if (!(0, _matchlocalpattern.hasLocalMatch)(localPatterns, url)) {
475
+ return {
476
+ errorMessage: '"url" parameter is not allowed'
477
+ };
478
+ }
479
+ } else {
480
+ let hrefParsed;
481
+ try {
482
+ hrefParsed = new URL(url);
483
+ href = hrefParsed.toString();
484
+ isAbsolute = true;
485
+ } catch (_error) {
486
+ return {
487
+ errorMessage: '"url" parameter is invalid'
488
+ };
489
+ }
490
+ if (![
491
+ 'http:',
492
+ 'https:'
493
+ ].includes(hrefParsed.protocol)) {
494
+ return {
495
+ errorMessage: '"url" parameter is invalid'
496
+ };
497
+ }
498
+ if (!(0, _matchremotepattern.hasRemoteMatch)(domains, remotePatterns, hrefParsed)) {
499
+ return {
500
+ errorMessage: '"url" parameter is not allowed'
501
+ };
502
+ }
503
+ }
504
+ if (!w) {
505
+ return {
506
+ errorMessage: '"w" parameter (width) is required'
507
+ };
508
+ } else if (Array.isArray(w)) {
509
+ return {
510
+ errorMessage: '"w" parameter (width) cannot be an array'
511
+ };
512
+ } else if (!/^[0-9]+$/.test(w)) {
513
+ return {
514
+ errorMessage: '"w" parameter (width) must be an integer greater than 0'
515
+ };
516
+ }
517
+ if (!q) {
518
+ return {
519
+ errorMessage: '"q" parameter (quality) is required'
520
+ };
521
+ } else if (Array.isArray(q)) {
522
+ return {
523
+ errorMessage: '"q" parameter (quality) cannot be an array'
524
+ };
525
+ } else if (!/^[0-9]+$/.test(q)) {
526
+ return {
527
+ errorMessage: '"q" parameter (quality) must be an integer between 1 and 100'
528
+ };
529
+ }
530
+ const width = parseInt(w, 10);
531
+ if (width <= 0 || isNaN(width)) {
532
+ return {
533
+ errorMessage: '"w" parameter (width) must be an integer greater than 0'
534
+ };
535
+ }
536
+ const sizes = [
537
+ ...deviceSizes || [],
538
+ ...imageSizes || []
539
+ ];
540
+ if (isDev) {
541
+ sizes.push(BLUR_IMG_SIZE);
542
+ }
543
+ const isValidSize = sizes.includes(width) || isDev && width <= BLUR_IMG_SIZE;
544
+ if (!isValidSize) {
545
+ return {
546
+ errorMessage: `"w" parameter (width) of ${width} is not allowed`
547
+ };
548
+ }
549
+ const quality = parseInt(q, 10);
550
+ if (isNaN(quality) || quality < 1 || quality > 100) {
551
+ return {
552
+ errorMessage: '"q" parameter (quality) must be an integer between 1 and 100'
553
+ };
554
+ }
555
+ if (qualities) {
556
+ if (isDev) {
557
+ qualities.push(BLUR_QUALITY);
558
+ }
559
+ if (!qualities.includes(quality)) {
560
+ return {
561
+ errorMessage: `"q" parameter (quality) of ${q} is not allowed`
562
+ };
563
+ }
564
+ }
565
+ const mimeType = getSupportedMimeType(formats || [], req.headers['accept']);
566
+ const isStatic = url.startsWith(`${nextConfig.basePath || ''}/_next/static/media`);
567
+ return {
568
+ href,
569
+ sizes,
570
+ isAbsolute,
571
+ isStatic,
572
+ width,
573
+ quality,
574
+ mimeType,
575
+ minimumCacheTTL
576
+ };
577
+ }
578
+ static getCacheKey({ href, width, quality, mimeType }) {
579
+ return getHash([
580
+ CACHE_VERSION,
581
+ href,
582
+ width,
583
+ quality,
584
+ mimeType
585
+ ]);
586
+ }
587
+ constructor({ distDir, nextConfig }){
588
+ this.cacheDir = (0, _path.join)(distDir, 'cache', 'images');
589
+ this.nextConfig = nextConfig;
590
+ }
591
+ async get(cacheKey) {
592
+ try {
593
+ const cacheDir = (0, _path.join)(this.cacheDir, cacheKey);
594
+ const files = await _fs.promises.readdir(cacheDir);
595
+ const now = Date.now();
596
+ for (const file of files){
597
+ const [maxAgeSt, expireAtSt, etag, upstreamEtag, extension] = file.split('.', 5);
598
+ const buffer = await _fs.promises.readFile((0, _path.join)(cacheDir, file));
599
+ const expireAt = Number(expireAtSt);
600
+ const maxAge = Number(maxAgeSt);
601
+ return {
602
+ value: {
603
+ kind: _responsecache.CachedRouteKind.IMAGE,
604
+ etag,
605
+ buffer,
606
+ extension,
607
+ upstreamEtag
608
+ },
609
+ revalidateAfter: Math.max(maxAge, this.nextConfig.images.minimumCacheTTL) * 1000 + Date.now(),
610
+ cacheControl: {
611
+ revalidate: maxAge,
612
+ expire: undefined
613
+ },
614
+ isStale: now > expireAt
615
+ };
616
+ }
617
+ } catch (_) {
618
+ // failed to read from cache dir, treat as cache miss
619
+ }
620
+ return null;
621
+ }
622
+ async set(cacheKey, value, { cacheControl }) {
623
+ if (!this.nextConfig.experimental.isrFlushToDisk) {
624
+ return;
625
+ }
626
+ if (value?.kind !== _responsecache.CachedRouteKind.IMAGE) {
627
+ throw Object.defineProperty(new Error('invariant attempted to set non-image to image-cache'), "__NEXT_ERROR_CODE", {
628
+ value: "E366",
629
+ enumerable: false,
630
+ configurable: true
631
+ });
632
+ }
633
+ const revalidate = cacheControl?.revalidate;
634
+ if (typeof revalidate !== 'number') {
635
+ throw Object.defineProperty(new _invarianterror.InvariantError('revalidate must be a number for image-cache'), "__NEXT_ERROR_CODE", {
636
+ value: "E657",
637
+ enumerable: false,
638
+ configurable: true
639
+ });
640
+ }
641
+ const expireAt = Math.max(revalidate, this.nextConfig.images.minimumCacheTTL) * 1000 + Date.now();
642
+ try {
643
+ await writeToCacheDir((0, _path.join)(this.cacheDir, cacheKey), value.extension, revalidate, expireAt, value.buffer, value.etag, value.upstreamEtag);
644
+ } catch (err) {
645
+ _log.error(`Failed to write image to cache ${cacheKey}`, err);
646
+ }
647
+ }
648
+ }
649
+ class ImageError extends Error {
650
+ constructor(statusCode, message){
651
+ super(message);
652
+ // ensure an error status is used > 400
653
+ if (statusCode >= 400) {
654
+ this.statusCode = statusCode;
655
+ } else {
656
+ this.statusCode = 500;
657
+ }
658
+ }
659
+ }
660
+ function parseCacheControl(str) {
661
+ const map = new Map();
662
+ if (!str) {
663
+ return map;
664
+ }
665
+ for (let directive of str.split(',')){
666
+ let [key, value] = directive.trim().split('=', 2);
667
+ key = key.toLowerCase();
668
+ if (value) {
669
+ value = value.toLowerCase();
670
+ }
671
+ map.set(key, value);
672
+ }
673
+ return map;
674
+ }
675
+ function getMaxAge(str) {
676
+ const map = parseCacheControl(str);
677
+ if (map) {
678
+ let age = map.get('s-maxage') || map.get('max-age') || '';
679
+ if (age.startsWith('"') && age.endsWith('"')) {
680
+ age = age.slice(1, -1);
681
+ }
682
+ const n = parseInt(age, 10);
683
+ if (!isNaN(n)) {
684
+ return n;
685
+ }
686
+ }
687
+ return 0;
688
+ }
689
+ function getPreviouslyCachedImageOrNull(upstreamImage, previousCacheEntry) {
690
+ if (previousCacheEntry?.value?.kind === 'IMAGE' && // Images that are SVGs, animated or failed the optimization previously end up using upstreamEtag as their etag as well,
691
+ // in these cases we want to trigger a new "optimization" attempt.
692
+ previousCacheEntry.value.upstreamEtag !== previousCacheEntry.value.etag && // and the upstream etag is the same as the previous cache entry's
693
+ upstreamImage.etag === previousCacheEntry.value.upstreamEtag) {
694
+ return previousCacheEntry.value;
695
+ }
696
+ return null;
697
+ }
698
+ async function optimizeImage({ buffer, contentType, quality, width, height, concurrency, limitInputPixels, sequentialRead, timeoutInSeconds }) {
699
+ const sharp = getSharp(concurrency);
700
+ const transformer = sharp(buffer, {
701
+ limitInputPixels,
702
+ sequentialRead: sequentialRead ?? undefined
703
+ }).timeout({
704
+ seconds: timeoutInSeconds ?? 7
705
+ }).rotate();
706
+ if (height) {
707
+ transformer.resize(width, height);
708
+ } else {
709
+ transformer.resize(width, undefined, {
710
+ withoutEnlargement: true
711
+ });
712
+ }
713
+ if (contentType === AVIF) {
714
+ transformer.avif({
715
+ quality: Math.max(quality - 20, 1),
716
+ effort: 3
717
+ });
718
+ } else if (contentType === WEBP) {
719
+ transformer.webp({
720
+ quality
721
+ });
722
+ } else if (contentType === PNG) {
723
+ transformer.png({
724
+ quality
725
+ });
726
+ } else if (contentType === JPEG) {
727
+ transformer.jpeg({
728
+ quality,
729
+ mozjpeg: true
730
+ });
731
+ }
732
+ const optimizedBuffer = await transformer.toBuffer();
733
+ return optimizedBuffer;
734
+ }
735
+ function isRedirect(statusCode) {
736
+ return [
737
+ 301,
738
+ 302,
739
+ 303,
740
+ 307,
741
+ 308
742
+ ].includes(statusCode);
743
+ }
744
+ async function fetchExternalImage(href, dangerouslyAllowLocalIP, count = 3) {
745
+ if (!dangerouslyAllowLocalIP) {
746
+ const { hostname } = new URL(href);
747
+ let ips = [
748
+ hostname
749
+ ];
750
+ if (!(0, _net.isIP)(hostname)) {
751
+ const records = await (0, _promises.lookup)(hostname, {
752
+ family: 0,
753
+ all: true,
754
+ hints: _dns.ALL
755
+ }).catch((_)=>[
756
+ {
757
+ address: hostname
758
+ }
759
+ ]);
760
+ ips = records.map((record)=>record.address);
761
+ }
762
+ const privateIps = ips.filter((ip)=>(0, _islocaladdress.default)(ip));
763
+ if (privateIps.length > 0) {
764
+ _log.error('upstream image', href, 'resolved to private ip', JSON.stringify(privateIps));
765
+ throw Object.defineProperty(new ImageError(400, '"url" parameter is not allowed'), "__NEXT_ERROR_CODE", {
766
+ value: "E394",
767
+ enumerable: false,
768
+ configurable: true
769
+ });
770
+ }
771
+ }
772
+ const res = await fetch(href, {
773
+ signal: AbortSignal.timeout(7000),
774
+ redirect: 'manual'
775
+ }).catch((err)=>err);
776
+ if (res instanceof Error) {
777
+ const err = res;
778
+ if (err.name === 'TimeoutError') {
779
+ _log.error('upstream image response timed out for', href);
780
+ throw Object.defineProperty(new ImageError(504, '"url" parameter is valid but upstream response timed out'), "__NEXT_ERROR_CODE", {
781
+ value: "E394",
782
+ enumerable: false,
783
+ configurable: true
784
+ });
785
+ }
786
+ throw err;
787
+ }
788
+ const locationHeader = res.headers.get('Location');
789
+ if (isRedirect(res.status) && locationHeader && URL.canParse(locationHeader, href)) {
790
+ if (count === 0) {
791
+ _log.error('upstream image response had too many redirects', href);
792
+ throw Object.defineProperty(new ImageError(508, '"url" parameter is valid but upstream response is invalid'), "__NEXT_ERROR_CODE", {
793
+ value: "E394",
794
+ enumerable: false,
795
+ configurable: true
796
+ });
797
+ }
798
+ const redirect = new URL(locationHeader, href).href;
799
+ return fetchExternalImage(redirect, dangerouslyAllowLocalIP, count - 1);
800
+ }
801
+ if (!res.ok) {
802
+ _log.error('upstream image response failed for', href, res.status);
803
+ throw Object.defineProperty(new ImageError(res.status, '"url" parameter is valid but upstream response is invalid'), "__NEXT_ERROR_CODE", {
804
+ value: "E394",
805
+ enumerable: false,
806
+ configurable: true
807
+ });
808
+ }
809
+ const buffer = Buffer.from(await res.arrayBuffer());
810
+ const contentType = res.headers.get('Content-Type');
811
+ const cacheControl = res.headers.get('Cache-Control');
812
+ const etag = extractEtag(res.headers.get('ETag'), buffer);
813
+ return {
814
+ buffer,
815
+ contentType,
816
+ cacheControl,
817
+ etag
818
+ };
819
+ }
820
+ async function fetchInternalImage(href, _req, _res, handleRequest) {
821
+ try {
822
+ const mocked = (0, _mockrequest.createRequestResponseMocks)({
823
+ url: href,
824
+ method: _req.method || 'GET',
825
+ socket: _req.socket
826
+ });
827
+ await handleRequest(mocked.req, mocked.res, _url.default.parse(href, true));
828
+ await mocked.res.hasStreamed;
829
+ if (!mocked.res.statusCode) {
830
+ _log.error('image response failed for', href, mocked.res.statusCode);
831
+ throw Object.defineProperty(new ImageError(mocked.res.statusCode, '"url" parameter is valid but internal response is invalid'), "__NEXT_ERROR_CODE", {
832
+ value: "E394",
833
+ enumerable: false,
834
+ configurable: true
835
+ });
836
+ }
837
+ const buffer = Buffer.concat(mocked.res.buffers);
838
+ const contentType = mocked.res.getHeader('Content-Type');
839
+ const cacheControl = mocked.res.getHeader('Cache-Control');
840
+ const etag = extractEtag(mocked.res.getHeader('ETag'), buffer);
841
+ return {
842
+ buffer,
843
+ contentType,
844
+ cacheControl,
845
+ etag
846
+ };
847
+ } catch (err) {
848
+ _log.error('upstream image response failed for', href, err);
849
+ throw Object.defineProperty(new ImageError(500, '"url" parameter is valid but upstream response is invalid'), "__NEXT_ERROR_CODE", {
850
+ value: "E394",
851
+ enumerable: false,
852
+ configurable: true
853
+ });
854
+ }
855
+ }
856
+ async function imageOptimizer(imageUpstream, paramsResult, nextConfig, opts) {
857
+ const { href, quality, width, mimeType } = paramsResult;
858
+ const { buffer: upstreamBuffer, etag: upstreamEtag } = imageUpstream;
859
+ const maxAge = Math.max(nextConfig.images.minimumCacheTTL, getMaxAge(imageUpstream.cacheControl));
860
+ const upstreamType = await detectContentType(upstreamBuffer, nextConfig.experimental.imgOptSkipMetadata, nextConfig.experimental.imgOptConcurrency);
861
+ if (!upstreamType || !upstreamType.startsWith('image/') || upstreamType.includes(',')) {
862
+ if (!opts.silent) {
863
+ _log.error("The requested resource isn't a valid image for", href, 'received', upstreamType);
864
+ }
865
+ throw Object.defineProperty(new ImageError(400, "The requested resource isn't a valid image."), "__NEXT_ERROR_CODE", {
866
+ value: "E394",
867
+ enumerable: false,
868
+ configurable: true
869
+ });
870
+ }
871
+ if (upstreamType.startsWith('image/svg') && !nextConfig.images.dangerouslyAllowSVG) {
872
+ if (!opts.silent) {
873
+ _log.error(`The requested resource "${href}" has type "${upstreamType}" but dangerouslyAllowSVG is disabled. Consider adding the "unoptimized" property to the <Image>.`);
874
+ }
875
+ throw Object.defineProperty(new ImageError(400, '"url" parameter is valid but image type is not allowed'), "__NEXT_ERROR_CODE", {
876
+ value: "E394",
877
+ enumerable: false,
878
+ configurable: true
879
+ });
880
+ }
881
+ if (ANIMATABLE_TYPES.includes(upstreamType) && (0, _isanimated.default)(upstreamBuffer)) {
882
+ if (!opts.silent) {
883
+ _log.warnOnce(`The requested resource "${href}" is an animated image so it will not be optimized. Consider adding the "unoptimized" property to the <Image>.`);
884
+ }
885
+ return {
886
+ buffer: upstreamBuffer,
887
+ contentType: upstreamType,
888
+ maxAge,
889
+ etag: upstreamEtag,
890
+ upstreamEtag
891
+ };
892
+ }
893
+ if (BYPASS_TYPES.includes(upstreamType)) {
894
+ return {
895
+ buffer: upstreamBuffer,
896
+ contentType: upstreamType,
897
+ maxAge,
898
+ etag: upstreamEtag,
899
+ upstreamEtag
900
+ };
901
+ }
902
+ let contentType;
903
+ if (mimeType) {
904
+ contentType = mimeType;
905
+ } else if ((0, _servestatic.getExtension)(upstreamType) && upstreamType !== WEBP && upstreamType !== AVIF) {
906
+ contentType = upstreamType;
907
+ } else {
908
+ contentType = JPEG;
909
+ }
910
+ const previouslyCachedImage = getPreviouslyCachedImageOrNull(imageUpstream, opts.previousCacheEntry);
911
+ if (previouslyCachedImage) {
912
+ return {
913
+ buffer: previouslyCachedImage.buffer,
914
+ contentType,
915
+ maxAge: opts?.previousCacheEntry?.cacheControl?.revalidate || maxAge,
916
+ etag: previouslyCachedImage.etag,
917
+ upstreamEtag: previouslyCachedImage.upstreamEtag
918
+ };
919
+ }
920
+ try {
921
+ let optimizedBuffer = await optimizeImage({
922
+ buffer: upstreamBuffer,
923
+ contentType,
924
+ quality,
925
+ width,
926
+ concurrency: nextConfig.experimental.imgOptConcurrency,
927
+ limitInputPixels: nextConfig.experimental.imgOptMaxInputPixels,
928
+ sequentialRead: nextConfig.experimental.imgOptSequentialRead,
929
+ timeoutInSeconds: nextConfig.experimental.imgOptTimeoutInSeconds
930
+ });
931
+ if (opts.isDev && width <= BLUR_IMG_SIZE && quality === BLUR_QUALITY) {
932
+ // During `next dev`, we don't want to generate blur placeholders with webpack
933
+ // because it can delay starting the dev server. Instead, `next-image-loader.js`
934
+ // will inline a special url to lazily generate the blur placeholder at request time.
935
+ const meta = await getImageSize(optimizedBuffer);
936
+ const blurOpts = {
937
+ blurWidth: meta.width,
938
+ blurHeight: meta.height,
939
+ blurDataURL: `data:${contentType};base64,${optimizedBuffer.toString('base64')}`
940
+ };
941
+ optimizedBuffer = Buffer.from(unescape((0, _imageblursvg.getImageBlurSvg)(blurOpts)));
942
+ contentType = 'image/svg+xml';
943
+ }
944
+ return {
945
+ buffer: optimizedBuffer,
946
+ contentType,
947
+ maxAge,
948
+ etag: getImageEtag(optimizedBuffer),
949
+ upstreamEtag
950
+ };
951
+ } catch (error) {
952
+ if (upstreamType) {
953
+ // If we fail to optimize, fallback to the original image
954
+ return {
955
+ buffer: upstreamBuffer,
956
+ contentType: upstreamType,
957
+ maxAge: nextConfig.images.minimumCacheTTL,
958
+ etag: upstreamEtag,
959
+ upstreamEtag,
960
+ error
961
+ };
962
+ } else {
963
+ throw Object.defineProperty(new ImageError(400, 'Unable to optimize image and unable to fallback to upstream image'), "__NEXT_ERROR_CODE", {
964
+ value: "E394",
965
+ enumerable: false,
966
+ configurable: true
967
+ });
968
+ }
969
+ }
970
+ }
971
+ function getFileNameWithExtension(url, contentType) {
972
+ const [urlWithoutQueryParams] = url.split('?', 1);
973
+ const fileNameWithExtension = urlWithoutQueryParams.split('/').pop();
974
+ if (!contentType || !fileNameWithExtension) {
975
+ return 'image.bin';
976
+ }
977
+ const [fileName] = fileNameWithExtension.split('.', 1);
978
+ const extension = (0, _servestatic.getExtension)(contentType);
979
+ return `${fileName}.${extension}`;
980
+ }
981
+ function setResponseHeaders(req, res, url, etag, contentType, isStatic, xCache, imagesConfig, maxAge, isDev) {
982
+ res.setHeader('Vary', 'Accept');
983
+ res.setHeader('Cache-Control', isStatic ? 'public, max-age=315360000, immutable' : `public, max-age=${isDev ? 0 : maxAge}, must-revalidate`);
984
+ if ((0, _sendpayload.sendEtagResponse)(req, res, etag)) {
985
+ // already called res.end() so we're finished
986
+ return {
987
+ finished: true
988
+ };
989
+ }
990
+ if (contentType) {
991
+ res.setHeader('Content-Type', contentType);
992
+ }
993
+ const fileName = getFileNameWithExtension(url, contentType);
994
+ res.setHeader('Content-Disposition', (0, _contentdisposition.default)(fileName, {
995
+ type: imagesConfig.contentDispositionType
996
+ }));
997
+ res.setHeader('Content-Security-Policy', imagesConfig.contentSecurityPolicy);
998
+ res.setHeader('X-Nextjs-Cache', xCache);
999
+ return {
1000
+ finished: false
1001
+ };
1002
+ }
1003
+ function sendResponse(req, res, url, extension, buffer, etag, isStatic, xCache, imagesConfig, maxAge, isDev) {
1004
+ const contentType = (0, _servestatic.getContentType)(extension);
1005
+ const result = setResponseHeaders(req, res, url, etag, contentType, isStatic, xCache, imagesConfig, maxAge, isDev);
1006
+ if (!result.finished) {
1007
+ res.setHeader('Content-Length', Buffer.byteLength(buffer));
1008
+ res.end(buffer);
1009
+ }
1010
+ }
1011
+ async function getImageSize(buffer) {
1012
+ const { width, height } = (0, _imagesize.default)(buffer);
1013
+ return {
1014
+ width,
1015
+ height
1016
+ };
1017
+ }
1018
+
1019
+ //# sourceMappingURL=image-optimizer.js.map