1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.raw = exports.transform = void 0;
|
4 | const schema = require("./schema.json");
|
5 | const schema_utils_1 = require("schema-utils");
|
6 | const utils_1 = require("./utils");
|
7 | const cache_1 = require("./cache");
|
8 | const interpolateName_1 = require("./interpolateName");
|
9 | const parseQuery_1 = require("./parseQuery");
|
10 | const DEFAULTS = {
|
11 | quality: 85,
|
12 | placeholder: false,
|
13 | placeholderSize: 40,
|
14 | name: '[hash]-[width].[ext]',
|
15 | steps: 4,
|
16 | esModule: false,
|
17 | emitFile: true,
|
18 | rotate: 0,
|
19 | cacheDirectory: false,
|
20 | cacheCompression: true,
|
21 | cacheIdentifier: '',
|
22 | };
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | function loader(content) {
|
34 | const loaderCallback = this.async();
|
35 | if (typeof loaderCallback == 'undefined') {
|
36 | new Error('Responsive loader callback error');
|
37 | return;
|
38 | }
|
39 |
|
40 | const parsedResourceQuery = this.resourceQuery ? (0, parseQuery_1.parseQuery)(this.resourceQuery) : {};
|
41 |
|
42 | const options = { ...DEFAULTS, ...this.getOptions(), ...parsedResourceQuery };
|
43 | (0, schema_utils_1.validate)(schema, options, { name: 'Responsive Loader' });
|
44 | const outputContext = options.context || this.rootContext;
|
45 | const { mime, ext, name, sizes, outputPlaceholder, placeholderSize, imageOptions, cacheOptions } = (0, utils_1.parseOptions)(this.resourcePath, options);
|
46 | if (!mime) {
|
47 | loaderCallback(new Error('No mime type for file with extension ' + ext + ' supported'));
|
48 | return;
|
49 | }
|
50 | const createFile = ({ data, width, height }) => {
|
51 | const fileName = (0, interpolateName_1.default)(this.resourcePath, this.resourceQuery, name, {
|
52 | context: outputContext,
|
53 | content: data.toString(),
|
54 | })
|
55 | .replace(/\[width\]/gi, width + '')
|
56 | .replace(/\[height\]/gi, height + '');
|
57 | const { outputPath, publicPath } = (0, utils_1.getOutputAndPublicPath)(fileName, {
|
58 | outputPath: options.outputPath,
|
59 | publicPath: options.publicPath,
|
60 | });
|
61 | if (options.emitFile) {
|
62 | this.emitFile(outputPath, data);
|
63 | }
|
64 | return {
|
65 | src: publicPath + `+${JSON.stringify(` ${width}w`)}`,
|
66 | path: publicPath,
|
67 | width: width,
|
68 | height: height,
|
69 | };
|
70 | };
|
71 | |
72 |
|
73 |
|
74 | if (options.disable) {
|
75 | const { path } = createFile({ data: content, width: 100, height: 100 });
|
76 | loaderCallback(null, `${options.esModule ? 'export default' : 'module.exports ='} {
|
77 | srcSet: ${path},
|
78 | images: [{path:${path},width:100,height:100}],
|
79 | src: ${path},
|
80 | toString: function(){return ${path}}
|
81 | }`);
|
82 | return;
|
83 | }
|
84 |
|
85 | const adapterOptions = Object.assign({}, options, imageOptions);
|
86 | const transformParams = {
|
87 | adapterModule: options.adapter,
|
88 | resourcePath: this.resourcePath,
|
89 | adapterOptions,
|
90 | createFile,
|
91 | outputPlaceholder,
|
92 | placeholderSize,
|
93 | mime,
|
94 | sizes,
|
95 | esModule: options.esModule,
|
96 | };
|
97 | orchestrate({ cacheOptions, transformParams })
|
98 | .then((result) => loaderCallback(null, result))
|
99 | .catch((err) => loaderCallback(err));
|
100 | }
|
101 | exports.default = loader;
|
102 | async function orchestrate(params) {
|
103 |
|
104 | let result;
|
105 | const { transformParams, cacheOptions } = params;
|
106 | if (cacheOptions.cacheDirectory) {
|
107 | result = await (0, cache_1.cache)(cacheOptions, transformParams);
|
108 | }
|
109 | else {
|
110 | result = await transform(transformParams);
|
111 | }
|
112 | return result;
|
113 | }
|
114 |
|
115 | async function transform({ adapterModule, resourcePath, createFile, sizes, mime, outputPlaceholder, placeholderSize, adapterOptions, esModule, }) {
|
116 | const adapter = adapterModule || require('./adapters/sharp');
|
117 | const img = adapter(resourcePath);
|
118 | const results = await transformations({ img, sizes, mime, outputPlaceholder, placeholderSize, adapterOptions });
|
119 | let placeholder;
|
120 | let files;
|
121 | if (outputPlaceholder) {
|
122 | files = results.slice(0, -1).map(createFile);
|
123 | placeholder = (0, utils_1.createPlaceholder)(results[results.length - 1], mime);
|
124 | }
|
125 | else {
|
126 | files = results.map(createFile);
|
127 | }
|
128 | const srcset = files.map((f) => f.src).join('+","+');
|
129 | const images = files.map((f) => `{path: ${f.path},width: ${f.width},height: ${f.height}}`).join(',');
|
130 | const defaultImage = outputPlaceholder ? files[files.length - 2] : files[files.length - 1];
|
131 | return `${esModule ? 'export default' : 'module.exports ='} {
|
132 | srcSet: ${srcset},
|
133 | images: [${images}],
|
134 | src: ${defaultImage.path},
|
135 | toString: function(){return ${defaultImage.path}},
|
136 | ${placeholder ? 'placeholder: ' + placeholder + ',' : ''}
|
137 | width: ${defaultImage.width},
|
138 | height: ${defaultImage.height}
|
139 | }`;
|
140 | }
|
141 | exports.transform = transform;
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | async function transformations({ img, sizes, mime, outputPlaceholder, placeholderSize, adapterOptions, }) {
|
149 | const metadata = await img.metadata();
|
150 | const promises = [];
|
151 | const widthsToGenerate = new Set();
|
152 | sizes.forEach((size) => {
|
153 | const width = Math.min(metadata.width, size);
|
154 |
|
155 | if (!widthsToGenerate.has(width)) {
|
156 | widthsToGenerate.add(width);
|
157 | promises.push(img.resize({
|
158 | width,
|
159 | mime,
|
160 | options: adapterOptions,
|
161 | }));
|
162 | }
|
163 | });
|
164 | if (outputPlaceholder) {
|
165 | promises.push(img.resize({
|
166 | width: placeholderSize,
|
167 | options: adapterOptions,
|
168 | mime,
|
169 | }));
|
170 | }
|
171 | return Promise.all(promises);
|
172 | }
|
173 | exports.raw = true;
|