@lens-image/core 0.1.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.
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/cjs/adapters/memory.d.ts +55 -0
- package/dist/cjs/adapters/memory.d.ts.map +1 -0
- package/dist/cjs/adapters/memory.js +84 -0
- package/dist/cjs/adapters/memory.js.map +1 -0
- package/dist/cjs/browser.d.ts +46 -0
- package/dist/cjs/browser.d.ts.map +1 -0
- package/dist/cjs/browser.js +79 -0
- package/dist/cjs/browser.js.map +1 -0
- package/dist/cjs/bytes.d.ts +18 -0
- package/dist/cjs/bytes.d.ts.map +1 -0
- package/dist/cjs/bytes.js +31 -0
- package/dist/cjs/bytes.js.map +1 -0
- package/dist/cjs/cache.d.ts +43 -0
- package/dist/cjs/cache.d.ts.map +1 -0
- package/dist/cjs/cache.js +77 -0
- package/dist/cjs/cache.js.map +1 -0
- package/dist/cjs/concurrency.d.ts +35 -0
- package/dist/cjs/concurrency.d.ts.map +1 -0
- package/dist/cjs/concurrency.js +82 -0
- package/dist/cjs/concurrency.js.map +1 -0
- package/dist/cjs/engines/index.d.ts +20 -0
- package/dist/cjs/engines/index.d.ts.map +1 -0
- package/dist/cjs/engines/index.js +38 -0
- package/dist/cjs/engines/index.js.map +1 -0
- package/dist/cjs/engines/passthrough.d.ts +41 -0
- package/dist/cjs/engines/passthrough.d.ts.map +1 -0
- package/dist/cjs/engines/passthrough.js +66 -0
- package/dist/cjs/engines/passthrough.js.map +1 -0
- package/dist/cjs/engines/sharp.d.ts +58 -0
- package/dist/cjs/engines/sharp.d.ts.map +1 -0
- package/dist/cjs/engines/sharp.js +243 -0
- package/dist/cjs/engines/sharp.js.map +1 -0
- package/dist/cjs/errors.d.ts +90 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +97 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/format.d.ts +33 -0
- package/dist/cjs/format.d.ts.map +1 -0
- package/dist/cjs/format.js +102 -0
- package/dist/cjs/format.js.map +1 -0
- package/dist/cjs/hash.d.ts +19 -0
- package/dist/cjs/hash.d.ts.map +1 -0
- package/dist/cjs/hash.js +43 -0
- package/dist/cjs/hash.js.map +1 -0
- package/dist/cjs/index.d.ts +56 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +110 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/naming.d.ts +48 -0
- package/dist/cjs/naming.d.ts.map +1 -0
- package/dist/cjs/naming.js +95 -0
- package/dist/cjs/naming.js.map +1 -0
- package/dist/cjs/optimizer.d.ts +89 -0
- package/dist/cjs/optimizer.d.ts.map +1 -0
- package/dist/cjs/optimizer.js +667 -0
- package/dist/cjs/optimizer.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/retry.d.ts +55 -0
- package/dist/cjs/retry.d.ts.map +1 -0
- package/dist/cjs/retry.js +129 -0
- package/dist/cjs/retry.js.map +1 -0
- package/dist/cjs/server/handler.d.ts +80 -0
- package/dist/cjs/server/handler.d.ts.map +1 -0
- package/dist/cjs/server/handler.js +155 -0
- package/dist/cjs/server/handler.js.map +1 -0
- package/dist/cjs/sniff.d.ts +37 -0
- package/dist/cjs/sniff.d.ts.map +1 -0
- package/dist/cjs/sniff.js +442 -0
- package/dist/cjs/sniff.js.map +1 -0
- package/dist/cjs/source.d.ts +45 -0
- package/dist/cjs/source.d.ts.map +1 -0
- package/dist/cjs/source.js +221 -0
- package/dist/cjs/source.js.map +1 -0
- package/dist/cjs/srcset.d.ts +66 -0
- package/dist/cjs/srcset.d.ts.map +1 -0
- package/dist/cjs/srcset.js +81 -0
- package/dist/cjs/srcset.js.map +1 -0
- package/dist/cjs/types.d.ts +441 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +12 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/validation.d.ts +38 -0
- package/dist/cjs/validation.d.ts.map +1 -0
- package/dist/cjs/validation.js +79 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/adapters/memory.d.ts +55 -0
- package/dist/esm/adapters/memory.d.ts.map +1 -0
- package/dist/esm/adapters/memory.js +80 -0
- package/dist/esm/adapters/memory.js.map +1 -0
- package/dist/esm/browser.d.ts +46 -0
- package/dist/esm/browser.d.ts.map +1 -0
- package/dist/esm/browser.js +49 -0
- package/dist/esm/browser.js.map +1 -0
- package/dist/esm/bytes.d.ts +18 -0
- package/dist/esm/bytes.d.ts.map +1 -0
- package/dist/esm/bytes.js +28 -0
- package/dist/esm/bytes.js.map +1 -0
- package/dist/esm/cache.d.ts +43 -0
- package/dist/esm/cache.d.ts.map +1 -0
- package/dist/esm/cache.js +73 -0
- package/dist/esm/cache.js.map +1 -0
- package/dist/esm/concurrency.d.ts +35 -0
- package/dist/esm/concurrency.d.ts.map +1 -0
- package/dist/esm/concurrency.js +78 -0
- package/dist/esm/concurrency.js.map +1 -0
- package/dist/esm/engines/index.d.ts +20 -0
- package/dist/esm/engines/index.d.ts.map +1 -0
- package/dist/esm/engines/index.js +30 -0
- package/dist/esm/engines/index.js.map +1 -0
- package/dist/esm/engines/passthrough.d.ts +41 -0
- package/dist/esm/engines/passthrough.d.ts.map +1 -0
- package/dist/esm/engines/passthrough.js +63 -0
- package/dist/esm/engines/passthrough.js.map +1 -0
- package/dist/esm/engines/sharp.d.ts +58 -0
- package/dist/esm/engines/sharp.d.ts.map +1 -0
- package/dist/esm/engines/sharp.js +206 -0
- package/dist/esm/engines/sharp.js.map +1 -0
- package/dist/esm/errors.d.ts +90 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +91 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/format.d.ts +33 -0
- package/dist/esm/format.d.ts.map +1 -0
- package/dist/esm/format.js +93 -0
- package/dist/esm/format.js.map +1 -0
- package/dist/esm/hash.d.ts +19 -0
- package/dist/esm/hash.d.ts.map +1 -0
- package/dist/esm/hash.js +38 -0
- package/dist/esm/hash.js.map +1 -0
- package/dist/esm/index.d.ts +56 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +54 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/naming.d.ts +48 -0
- package/dist/esm/naming.d.ts.map +1 -0
- package/dist/esm/naming.js +88 -0
- package/dist/esm/naming.js.map +1 -0
- package/dist/esm/optimizer.d.ts +89 -0
- package/dist/esm/optimizer.d.ts.map +1 -0
- package/dist/esm/optimizer.js +663 -0
- package/dist/esm/optimizer.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/retry.d.ts +55 -0
- package/dist/esm/retry.d.ts.map +1 -0
- package/dist/esm/retry.js +123 -0
- package/dist/esm/retry.js.map +1 -0
- package/dist/esm/server/handler.d.ts +80 -0
- package/dist/esm/server/handler.d.ts.map +1 -0
- package/dist/esm/server/handler.js +151 -0
- package/dist/esm/server/handler.js.map +1 -0
- package/dist/esm/sniff.d.ts +37 -0
- package/dist/esm/sniff.d.ts.map +1 -0
- package/dist/esm/sniff.js +435 -0
- package/dist/esm/sniff.js.map +1 -0
- package/dist/esm/source.d.ts +45 -0
- package/dist/esm/source.d.ts.map +1 -0
- package/dist/esm/source.js +183 -0
- package/dist/esm/source.js.map +1 -0
- package/dist/esm/srcset.d.ts +66 -0
- package/dist/esm/srcset.d.ts.map +1 -0
- package/dist/esm/srcset.js +76 -0
- package/dist/esm/srcset.js.map +1 -0
- package/dist/esm/types.d.ts +441 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +11 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/validation.d.ts +38 -0
- package/dist/esm/validation.d.ts.map +1 -0
- package/dist/esm/validation.js +74 -0
- package/dist/esm/validation.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Turning the many shapes of "an image" into bytes plus a filename.
|
|
4
|
+
*
|
|
5
|
+
* Node builtins only - `node:fs/promises` for paths, global `fetch` for remote
|
|
6
|
+
* URLs (Node 18+), and manual concatenation for async iterables.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.formatBytes = void 0;
|
|
43
|
+
exports.resolveSource = resolveSource;
|
|
44
|
+
exports.stem = stem;
|
|
45
|
+
const node_path_1 = require("node:path");
|
|
46
|
+
const node_url_1 = require("node:url");
|
|
47
|
+
const bytes_js_1 = require("./bytes.js");
|
|
48
|
+
Object.defineProperty(exports, "formatBytes", { enumerable: true, get: function () { return bytes_js_1.formatBytes; } });
|
|
49
|
+
const errors_js_1 = require("./errors.js");
|
|
50
|
+
const isAsyncIterable = (value) => typeof value === 'object' && value !== null && Symbol.asyncIterator in value;
|
|
51
|
+
/**
|
|
52
|
+
* Normalises any {@link ImageSource} into a buffer.
|
|
53
|
+
*
|
|
54
|
+
* @throws {LensError} `INVALID_SOURCE` for an unrecognised shape,
|
|
55
|
+
* `SOURCE_UNREADABLE` when the read itself fails,
|
|
56
|
+
* `VALIDATION_FAILED` when `maxBytes` is exceeded mid-read.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* await resolveSource('./photo.jpg');
|
|
61
|
+
* await resolveSource(request.body, { filename: 'upload.png', maxBytes: 5_000_000 });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
async function resolveSource(source, options = {}) {
|
|
65
|
+
const { filename: override } = options;
|
|
66
|
+
// { data, filename } wrapper - unwrap and recurse, keeping the inner filename
|
|
67
|
+
// unless the caller supplied an explicit override.
|
|
68
|
+
if (typeof source === 'object' &&
|
|
69
|
+
source !== null &&
|
|
70
|
+
!(source instanceof URL) &&
|
|
71
|
+
!ArrayBuffer.isView(source) &&
|
|
72
|
+
!isAsyncIterable(source) &&
|
|
73
|
+
'data' in source) {
|
|
74
|
+
const wrapper = source;
|
|
75
|
+
const inner = await resolveSource(wrapper.data, {
|
|
76
|
+
...options,
|
|
77
|
+
filename: override ?? wrapper.filename,
|
|
78
|
+
});
|
|
79
|
+
return wrapper.contentType ? { ...inner, contentType: wrapper.contentType } : inner;
|
|
80
|
+
}
|
|
81
|
+
if (typeof source === 'string') {
|
|
82
|
+
return readPath(source, override, options);
|
|
83
|
+
}
|
|
84
|
+
if (source instanceof URL) {
|
|
85
|
+
if (source.protocol === 'file:') {
|
|
86
|
+
return readPath((0, node_url_1.fileURLToPath)(source), override, options);
|
|
87
|
+
}
|
|
88
|
+
if (source.protocol === 'http:' || source.protocol === 'https:') {
|
|
89
|
+
return readRemote(source, override, options);
|
|
90
|
+
}
|
|
91
|
+
throw new errors_js_1.LensError('INVALID_SOURCE', `Unsupported URL protocol "${source.protocol}". Use a file:, http: or https: URL.`);
|
|
92
|
+
}
|
|
93
|
+
if (ArrayBuffer.isView(source)) {
|
|
94
|
+
const data = toUint8(source);
|
|
95
|
+
assertUnderLimit(data.byteLength, options.maxBytes);
|
|
96
|
+
return { data, filename: normalizeFilename(override ?? 'image'), origin: 'buffer' };
|
|
97
|
+
}
|
|
98
|
+
if (isAsyncIterable(source)) {
|
|
99
|
+
const data = await collect(source, options.maxBytes, options.signal);
|
|
100
|
+
return { data, filename: normalizeFilename(override ?? 'image'), origin: 'stream' };
|
|
101
|
+
}
|
|
102
|
+
throw new errors_js_1.LensError('INVALID_SOURCE', 'source must be a file path, URL, Uint8Array, async iterable of chunks, or { data, filename }. ' +
|
|
103
|
+
`Received ${describe(source)}.`);
|
|
104
|
+
}
|
|
105
|
+
async function readPath(path, override, options) {
|
|
106
|
+
const { readFile, stat } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
|
|
107
|
+
try {
|
|
108
|
+
if (options.maxBytes !== undefined) {
|
|
109
|
+
// Check the size before reading so an oversized file never lands in memory.
|
|
110
|
+
const info = await stat(path);
|
|
111
|
+
assertUnderLimit(info.size, options.maxBytes, path);
|
|
112
|
+
}
|
|
113
|
+
const buffer = await readFile(path, options.signal ? { signal: options.signal } : undefined);
|
|
114
|
+
return {
|
|
115
|
+
data: toUint8(buffer),
|
|
116
|
+
filename: normalizeFilename(override ?? (0, node_path_1.basename)(path)),
|
|
117
|
+
origin: 'path',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (errors_js_1.LensError.is(error))
|
|
122
|
+
throw error;
|
|
123
|
+
if (error?.name === 'AbortError') {
|
|
124
|
+
throw new errors_js_1.LensError('ABORTED', `Reading "${path}" was aborted.`, { cause: error });
|
|
125
|
+
}
|
|
126
|
+
throw (0, errors_js_1.wrapError)('SOURCE_UNREADABLE', `Could not read image at "${path}"`, error, { path });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function readRemote(url, override, options) {
|
|
130
|
+
if (!options.allowRemote) {
|
|
131
|
+
throw new errors_js_1.LensError('INVALID_SOURCE', `Refusing to fetch "${url.href}". Remote sources are disabled by default because they are ` +
|
|
132
|
+
'an SSRF surface; pass `allowRemote: true` to the optimizer once you have validated the host.', { details: { url: url.href } });
|
|
133
|
+
}
|
|
134
|
+
let response;
|
|
135
|
+
try {
|
|
136
|
+
response = await fetch(url, options.signal ? { signal: options.signal } : {});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw (0, errors_js_1.wrapError)('SOURCE_UNREADABLE', `Fetching "${url.href}" failed`, error, { url: url.href });
|
|
140
|
+
}
|
|
141
|
+
if (!response.ok) {
|
|
142
|
+
throw new errors_js_1.LensError('SOURCE_UNREADABLE', `Fetching "${url.href}" returned HTTP ${response.status} ${response.statusText}.`, { details: { url: url.href, status: response.status } });
|
|
143
|
+
}
|
|
144
|
+
const declared = Number(response.headers.get('content-length'));
|
|
145
|
+
if (Number.isFinite(declared) && declared > 0) {
|
|
146
|
+
assertUnderLimit(declared, options.maxBytes, url.href);
|
|
147
|
+
}
|
|
148
|
+
const data = toUint8(new Uint8Array(await response.arrayBuffer()));
|
|
149
|
+
assertUnderLimit(data.byteLength, options.maxBytes, url.href);
|
|
150
|
+
const contentType = response.headers.get('content-type') ?? undefined;
|
|
151
|
+
const derived = (0, node_path_1.basename)(url.pathname) || 'image';
|
|
152
|
+
return {
|
|
153
|
+
data,
|
|
154
|
+
filename: normalizeFilename(override ?? derived),
|
|
155
|
+
...(contentType ? { contentType } : {}),
|
|
156
|
+
origin: 'url',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Drains an async iterable into one buffer, enforcing `maxBytes` as it goes. */
|
|
160
|
+
async function collect(stream, maxBytes, signal) {
|
|
161
|
+
const chunks = [];
|
|
162
|
+
let total = 0;
|
|
163
|
+
try {
|
|
164
|
+
for await (const chunk of stream) {
|
|
165
|
+
if (signal?.aborted) {
|
|
166
|
+
throw new errors_js_1.LensError('ABORTED', 'Reading the source stream was aborted.');
|
|
167
|
+
}
|
|
168
|
+
const bytes = toUint8(chunk);
|
|
169
|
+
total += bytes.byteLength;
|
|
170
|
+
assertUnderLimit(total, maxBytes);
|
|
171
|
+
chunks.push(bytes);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
throw (0, errors_js_1.wrapError)('SOURCE_UNREADABLE', 'Reading the source stream failed', error);
|
|
176
|
+
}
|
|
177
|
+
const out = new Uint8Array(total);
|
|
178
|
+
let offset = 0;
|
|
179
|
+
for (const chunk of chunks) {
|
|
180
|
+
out.set(chunk, offset);
|
|
181
|
+
offset += chunk.byteLength;
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
function assertUnderLimit(size, maxBytes, what) {
|
|
186
|
+
if (maxBytes !== undefined && size > maxBytes) {
|
|
187
|
+
throw new errors_js_1.LensError('VALIDATION_FAILED', `Image is ${(0, bytes_js_1.formatBytes)(size)}${what ? ` ("${what}")` : ''}, over the ${(0, bytes_js_1.formatBytes)(maxBytes)} limit.`, { details: { limit: maxBytes, actual: size } });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Views any ArrayBufferView as a Uint8Array without copying.
|
|
192
|
+
*
|
|
193
|
+
* The byteOffset/byteLength dance matters: Node often hands you a Buffer that
|
|
194
|
+
* is a window onto a larger pooled allocation, and ignoring that ships the
|
|
195
|
+
* neighbouring bytes too.
|
|
196
|
+
*/
|
|
197
|
+
function toUint8(view) {
|
|
198
|
+
return view instanceof Uint8Array && view.byteOffset === 0 && view.byteLength === view.buffer.byteLength
|
|
199
|
+
? view
|
|
200
|
+
: new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
201
|
+
}
|
|
202
|
+
/** Strips directory separators and control characters from a filename. */
|
|
203
|
+
function normalizeFilename(name) {
|
|
204
|
+
const cleaned = name.split(/[\\/]/).pop() ?? 'image';
|
|
205
|
+
// eslint-disable-next-line no-control-regex
|
|
206
|
+
const safe = cleaned.replace(/[\x00-\x1f\x7f]/g, '').trim();
|
|
207
|
+
return safe.length > 0 ? safe : 'image';
|
|
208
|
+
}
|
|
209
|
+
/** Filename without its extension. */
|
|
210
|
+
function stem(filename) {
|
|
211
|
+
const ext = (0, node_path_1.extname)(filename);
|
|
212
|
+
return ext ? filename.slice(0, -ext.length) : filename;
|
|
213
|
+
}
|
|
214
|
+
function describe(value) {
|
|
215
|
+
if (value === null)
|
|
216
|
+
return 'null';
|
|
217
|
+
if (Array.isArray(value))
|
|
218
|
+
return 'an array';
|
|
219
|
+
return typeof value;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for getting an {@link OptimizeResult} into HTML.
|
|
3
|
+
*
|
|
4
|
+
* These are pure functions over the result object, deliberately framework-free
|
|
5
|
+
* so they work in Express templates, Next.js, Astro or a string concatenation
|
|
6
|
+
* in a cron job.
|
|
7
|
+
*/
|
|
8
|
+
import type { ImageFormat, OptimizeResult, Variant } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Builds a `srcset` attribute value from variants.
|
|
11
|
+
*
|
|
12
|
+
* Variants without a URL (process-only mode) and zero-width variants are
|
|
13
|
+
* skipped, and the list is sorted ascending so browsers pick sensibly.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* buildSrcset(result.formats.webp!.variants);
|
|
18
|
+
* // 'https://cdn/…-300w.webp 300w, https://cdn/…-600w.webp 600w'
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildSrcset(variants: readonly Variant[]): string;
|
|
22
|
+
/** One `<source>` element's worth of data. */
|
|
23
|
+
export interface PictureSource {
|
|
24
|
+
readonly type: string;
|
|
25
|
+
readonly srcset: string;
|
|
26
|
+
readonly sizes?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Everything needed to render a `<picture>`. */
|
|
29
|
+
export interface PictureData {
|
|
30
|
+
/** In the order given to `optimize`, which is the order they should be tried. */
|
|
31
|
+
readonly sources: readonly PictureSource[];
|
|
32
|
+
/** `src` for the `<img>` fallback - the widest variant of the last format. */
|
|
33
|
+
readonly src: string;
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
readonly alt: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reshapes a result into `<picture>`-ready data.
|
|
40
|
+
*
|
|
41
|
+
* Source order is the order formats were requested, which matters: the browser
|
|
42
|
+
* takes the first `<source>` it supports. Request `['avif', 'webp', 'jpeg']`
|
|
43
|
+
* and you get exactly the progressive-enhancement ladder you wanted.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* const pic = toPicture(result, { alt: 'Cabin at dusk', sizes: '(max-width: 768px) 100vw, 50vw' });
|
|
48
|
+
*
|
|
49
|
+
* <picture>
|
|
50
|
+
* {pic.sources.map((s) => <source key={s.type} type={s.type} srcSet={s.srcset} sizes={s.sizes} />)}
|
|
51
|
+
* <img src={pic.src} width={pic.width} height={pic.height} alt={pic.alt} loading="lazy" />
|
|
52
|
+
* </picture>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function toPicture(result: OptimizeResult, options?: {
|
|
56
|
+
alt?: string;
|
|
57
|
+
sizes?: string;
|
|
58
|
+
}): PictureData;
|
|
59
|
+
/**
|
|
60
|
+
* Picks the variant closest to a target width without going under it, so the
|
|
61
|
+
* rendered image is never upscaled.
|
|
62
|
+
*
|
|
63
|
+
* @example `pickVariant(result, 800, 'webp')`
|
|
64
|
+
*/
|
|
65
|
+
export declare function pickVariant(result: OptimizeResult, targetWidth: number, format?: ImageFormat): Variant | undefined;
|
|
66
|
+
//# sourceMappingURL=srcset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"srcset.d.ts","sourceRoot":"","sources":["../../src/srcset.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAgB,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAMhE;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,WAAW,CAsBb;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,GAAG,SAAS,CAIrB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Helpers for getting an {@link OptimizeResult} into HTML.
|
|
4
|
+
*
|
|
5
|
+
* These are pure functions over the result object, deliberately framework-free
|
|
6
|
+
* so they work in Express templates, Next.js, Astro or a string concatenation
|
|
7
|
+
* in a cron job.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildSrcset = buildSrcset;
|
|
11
|
+
exports.toPicture = toPicture;
|
|
12
|
+
exports.pickVariant = pickVariant;
|
|
13
|
+
const sniff_js_1 = require("./sniff.js");
|
|
14
|
+
/**
|
|
15
|
+
* Builds a `srcset` attribute value from variants.
|
|
16
|
+
*
|
|
17
|
+
* Variants without a URL (process-only mode) and zero-width variants are
|
|
18
|
+
* skipped, and the list is sorted ascending so browsers pick sensibly.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* buildSrcset(result.formats.webp!.variants);
|
|
23
|
+
* // 'https://cdn/…-300w.webp 300w, https://cdn/…-600w.webp 600w'
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
function buildSrcset(variants) {
|
|
27
|
+
return [...variants]
|
|
28
|
+
.filter((v) => v.url && v.width > 0)
|
|
29
|
+
.sort((a, b) => a.width - b.width)
|
|
30
|
+
.map((v) => `${v.url} ${v.width}w`)
|
|
31
|
+
.join(', ');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Reshapes a result into `<picture>`-ready data.
|
|
35
|
+
*
|
|
36
|
+
* Source order is the order formats were requested, which matters: the browser
|
|
37
|
+
* takes the first `<source>` it supports. Request `['avif', 'webp', 'jpeg']`
|
|
38
|
+
* and you get exactly the progressive-enhancement ladder you wanted.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* const pic = toPicture(result, { alt: 'Cabin at dusk', sizes: '(max-width: 768px) 100vw, 50vw' });
|
|
43
|
+
*
|
|
44
|
+
* <picture>
|
|
45
|
+
* {pic.sources.map((s) => <source key={s.type} type={s.type} srcSet={s.srcset} sizes={s.sizes} />)}
|
|
46
|
+
* <img src={pic.src} width={pic.width} height={pic.height} alt={pic.alt} loading="lazy" />
|
|
47
|
+
* </picture>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
function toPicture(result, options = {}) {
|
|
51
|
+
const groups = Object.values(result.formats).filter(Boolean);
|
|
52
|
+
const sources = groups
|
|
53
|
+
.filter((group) => group.srcset.length > 0)
|
|
54
|
+
.map((group) => ({
|
|
55
|
+
type: (0, sniff_js_1.mimeTypeFor)(group.format),
|
|
56
|
+
srcset: group.srcset,
|
|
57
|
+
...(options.sizes ? { sizes: options.sizes } : {}),
|
|
58
|
+
}));
|
|
59
|
+
// The <img> fallback should be the most compatible format available, which is
|
|
60
|
+
// the last one requested in a properly ordered format list.
|
|
61
|
+
const fallback = groups[groups.length - 1]?.largest;
|
|
62
|
+
return {
|
|
63
|
+
sources,
|
|
64
|
+
src: fallback?.url ?? '',
|
|
65
|
+
width: fallback?.width ?? result.source.width,
|
|
66
|
+
height: fallback?.height ?? result.source.height,
|
|
67
|
+
alt: options.alt ?? '',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Picks the variant closest to a target width without going under it, so the
|
|
72
|
+
* rendered image is never upscaled.
|
|
73
|
+
*
|
|
74
|
+
* @example `pickVariant(result, 800, 'webp')`
|
|
75
|
+
*/
|
|
76
|
+
function pickVariant(result, targetWidth, format) {
|
|
77
|
+
const pool = format ? (result.formats[format]?.variants ?? []) : result.variants;
|
|
78
|
+
const sorted = [...pool].sort((a, b) => a.width - b.width);
|
|
79
|
+
return sorted.find((v) => v.width >= targetWidth) ?? sorted[sorted.length - 1];
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=srcset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"srcset.js","sourceRoot":"","sources":["../../src/srcset.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAiBH,kCAMC;AAqCD,8BAyBC;AAQD,kCAQC;AAnGD,yCAAyC;AAGzC;;;;;;;;;;;GAWG;AACH,SAAgB,WAAW,CAAC,QAA4B;IACtD,OAAO,CAAC,GAAG,QAAQ,CAAC;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;SACnC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAoBD;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,SAAS,CACvB,MAAsB,EACtB,UAA4C,EAAE;IAE9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAmB,CAAC;IAE/E,MAAM,OAAO,GAAG,MAAM;SACnB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;SAC1C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,IAAA,sBAAW,EAAC,KAAK,CAAC,MAAM,CAAC;QAC/B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnD,CAAC,CAAC,CAAC;IAEN,8EAA8E;IAC9E,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;IAEpD,OAAO;QACL,OAAO;QACP,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE;QACxB,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK;QAC7C,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM;QAChD,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;KACvB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,MAAsB,EACtB,WAAmB,EACnB,MAAoB;IAEpB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACjF,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjF,CAAC"}
|