@deenruv/asset-server-plugin 1.0.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 +23 -0
- package/README.md +103 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +21 -0
- package/lib/index.js.map +1 -0
- package/lib/src/common.d.ts +4 -0
- package/lib/src/common.js +42 -0
- package/lib/src/common.js.map +1 -0
- package/lib/src/constants.d.ts +2 -0
- package/lib/src/constants.js +6 -0
- package/lib/src/constants.js.map +1 -0
- package/lib/src/default-asset-storage-strategy-factory.d.ts +6 -0
- package/lib/src/default-asset-storage-strategy-factory.js +24 -0
- package/lib/src/default-asset-storage-strategy-factory.js.map +1 -0
- package/lib/src/file-icon.png +0 -0
- package/lib/src/hashed-asset-naming-strategy.d.ts +21 -0
- package/lib/src/hashed-asset-naming-strategy.js +39 -0
- package/lib/src/hashed-asset-naming-strategy.js.map +1 -0
- package/lib/src/local-asset-storage-strategy.d.ts +28 -0
- package/lib/src/local-asset-storage-strategy.js +68 -0
- package/lib/src/local-asset-storage-strategy.js.map +1 -0
- package/lib/src/plugin.d.ts +167 -0
- package/lib/src/plugin.js +394 -0
- package/lib/src/plugin.js.map +1 -0
- package/lib/src/s3-asset-storage-strategy.d.ts +159 -0
- package/lib/src/s3-asset-storage-strategy.js +289 -0
- package/lib/src/s3-asset-storage-strategy.js.map +1 -0
- package/lib/src/sharp-asset-preview-strategy.d.ts +99 -0
- package/lib/src/sharp-asset-preview-strategy.js +121 -0
- package/lib/src/sharp-asset-preview-strategy.js.map +1 -0
- package/lib/src/transform-image.d.ts +25 -0
- package/lib/src/transform-image.js +145 -0
- package/lib/src/transform-image.js.map +1 -0
- package/lib/src/types.d.ts +137 -0
- package/lib/src/types.js +3 -0
- package/lib/src/types.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
var AssetServerPlugin_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AssetServerPlugin = void 0;
|
|
17
|
+
const core_1 = require("@deenruv/core");
|
|
18
|
+
const crypto_1 = require("crypto");
|
|
19
|
+
const express_1 = __importDefault(require("express"));
|
|
20
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const common_1 = require("./common");
|
|
23
|
+
const constants_1 = require("./constants");
|
|
24
|
+
const default_asset_storage_strategy_factory_1 = require("./default-asset-storage-strategy-factory");
|
|
25
|
+
const hashed_asset_naming_strategy_1 = require("./hashed-asset-naming-strategy");
|
|
26
|
+
const sharp_asset_preview_strategy_1 = require("./sharp-asset-preview-strategy");
|
|
27
|
+
const transform_image_1 = require("./transform-image");
|
|
28
|
+
async function getFileType(buffer) {
|
|
29
|
+
const { fileTypeFromBuffer } = await import("file-type");
|
|
30
|
+
return fileTypeFromBuffer(buffer);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @description
|
|
34
|
+
* The `AssetServerPlugin` serves assets (images and other files) from the local file system, and can also be configured to use
|
|
35
|
+
* other storage strategies (e.g. {@link S3AssetStorageStrategy}. It can also perform on-the-fly image transformations
|
|
36
|
+
* and caches the results for subsequent calls.
|
|
37
|
+
*
|
|
38
|
+
* ## Installation
|
|
39
|
+
*
|
|
40
|
+
* `yarn add \@deenruv/asset-server-plugin`
|
|
41
|
+
*
|
|
42
|
+
* or
|
|
43
|
+
*
|
|
44
|
+
* `npm install \@deenruv/asset-server-plugin`
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { AssetServerPlugin } from '\@deenruv/asset-server-plugin';
|
|
49
|
+
*
|
|
50
|
+
* const config: DeenruvConfig = {
|
|
51
|
+
* // Add an instance of the plugin to the plugins array
|
|
52
|
+
* plugins: [
|
|
53
|
+
* AssetServerPlugin.init({
|
|
54
|
+
* route: 'assets',
|
|
55
|
+
* assetUploadDir: path.join(__dirname, 'assets'),
|
|
56
|
+
* }),
|
|
57
|
+
* ],
|
|
58
|
+
* };
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* The full configuration is documented at [AssetServerOptions](/reference/core-plugins/asset-server-plugin/asset-server-options)
|
|
62
|
+
*
|
|
63
|
+
* ## Image transformation
|
|
64
|
+
*
|
|
65
|
+
* Asset preview images can be transformed (resized & cropped) on the fly by appending query parameters to the url:
|
|
66
|
+
*
|
|
67
|
+
* `http://localhost:3000/assets/some-asset.jpg?w=500&h=300&mode=resize`
|
|
68
|
+
*
|
|
69
|
+
* The above URL will return `some-asset.jpg`, resized to fit in the bounds of a 500px x 300px rectangle.
|
|
70
|
+
*
|
|
71
|
+
* ### Preview mode
|
|
72
|
+
*
|
|
73
|
+
* The `mode` parameter can be either `crop` or `resize`. See the [ImageTransformMode](/reference/core-plugins/asset-server-plugin/image-transform-mode) docs for details.
|
|
74
|
+
*
|
|
75
|
+
* ### Focal point
|
|
76
|
+
*
|
|
77
|
+
* When cropping an image (`mode=crop`), Deenruv will attempt to keep the most "interesting" area of the image in the cropped frame. It does this
|
|
78
|
+
* by finding the area of the image with highest entropy (the busiest area of the image). However, sometimes this does not yield a satisfactory
|
|
79
|
+
* result - part or all of the main subject may still be cropped out.
|
|
80
|
+
*
|
|
81
|
+
* This is where specifying the focal point can help. The focal point of the image may be specified by passing the `fpx` and `fpy` query parameters.
|
|
82
|
+
* These are normalized coordinates (i.e. a number between 0 and 1), so the `fpx=0&fpy=0` corresponds to the top left of the image.
|
|
83
|
+
*
|
|
84
|
+
* For example, let's say there is a very wide landscape image which we want to crop to be square. The main subject is a house to the far left of the
|
|
85
|
+
* image. The following query would crop it to a square with the house centered:
|
|
86
|
+
*
|
|
87
|
+
* `http://localhost:3000/assets/landscape.jpg?w=150&h=150&mode=crop&fpx=0.2&fpy=0.7`
|
|
88
|
+
*
|
|
89
|
+
* ### Format
|
|
90
|
+
*
|
|
91
|
+
* Since v1.7.0, the image format can be specified by adding the `format` query parameter:
|
|
92
|
+
*
|
|
93
|
+
* `http://localhost:3000/assets/some-asset.jpg?format=webp`
|
|
94
|
+
*
|
|
95
|
+
* This means that, no matter the format of your original asset files, you can use more modern formats in your storefront if the browser
|
|
96
|
+
* supports them. Supported values for `format` are:
|
|
97
|
+
*
|
|
98
|
+
* * `jpeg` or `jpg`
|
|
99
|
+
* * `png`
|
|
100
|
+
* * `webp`
|
|
101
|
+
* * `avif`
|
|
102
|
+
*
|
|
103
|
+
* The `format` parameter can also be combined with presets (see below).
|
|
104
|
+
*
|
|
105
|
+
* ### Quality
|
|
106
|
+
*
|
|
107
|
+
* Since v2.2.0, the image quality can be specified by adding the `q` query parameter:
|
|
108
|
+
*
|
|
109
|
+
* `http://localhost:3000/assets/some-asset.jpg?q=75`
|
|
110
|
+
*
|
|
111
|
+
* This applies to the `jpg`, `webp` and `avif` formats. The default quality value for `jpg` and `webp` is 80, and for `avif` is 50.
|
|
112
|
+
*
|
|
113
|
+
* The `q` parameter can also be combined with presets (see below).
|
|
114
|
+
*
|
|
115
|
+
* ### Transform presets
|
|
116
|
+
*
|
|
117
|
+
* Presets can be defined which allow a single preset name to be used instead of specifying the width, height and mode. Presets are
|
|
118
|
+
* configured via the AssetServerOptions [presets property](/reference/core-plugins/asset-server-plugin/asset-server-options/#presets).
|
|
119
|
+
*
|
|
120
|
+
* For example, defining the following preset:
|
|
121
|
+
*
|
|
122
|
+
* ```ts
|
|
123
|
+
* AssetServerPlugin.init({
|
|
124
|
+
* // ...
|
|
125
|
+
* presets: [
|
|
126
|
+
* { name: 'my-preset', width: 85, height: 85, mode: 'crop' },
|
|
127
|
+
* ],
|
|
128
|
+
* }),
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* means that a request to:
|
|
132
|
+
*
|
|
133
|
+
* `http://localhost:3000/assets/some-asset.jpg?preset=my-preset`
|
|
134
|
+
*
|
|
135
|
+
* is equivalent to:
|
|
136
|
+
*
|
|
137
|
+
* `http://localhost:3000/assets/some-asset.jpg?w=85&h=85&mode=crop`
|
|
138
|
+
*
|
|
139
|
+
* The AssetServerPlugin comes pre-configured with the following presets:
|
|
140
|
+
*
|
|
141
|
+
* name | width | height | mode
|
|
142
|
+
* -----|-------|--------|-----
|
|
143
|
+
* tiny | 50px | 50px | crop
|
|
144
|
+
* thumb | 150px | 150px | crop
|
|
145
|
+
* small | 300px | 300px | resize
|
|
146
|
+
* medium | 500px | 500px | resize
|
|
147
|
+
* large | 800px | 800px | resize
|
|
148
|
+
*
|
|
149
|
+
* ### Caching
|
|
150
|
+
* By default, the AssetServerPlugin will cache every transformed image, so that the transformation only needs to be performed a single time for
|
|
151
|
+
* a given configuration. Caching can be disabled per-request by setting the `?cache=false` query parameter.
|
|
152
|
+
*
|
|
153
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
154
|
+
*/
|
|
155
|
+
let AssetServerPlugin = AssetServerPlugin_1 = class AssetServerPlugin {
|
|
156
|
+
/**
|
|
157
|
+
* @description
|
|
158
|
+
* Set the plugin options.
|
|
159
|
+
*/
|
|
160
|
+
static init(options) {
|
|
161
|
+
AssetServerPlugin_1.options = options;
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
/** @internal */
|
|
165
|
+
static async configure(config) {
|
|
166
|
+
var _a;
|
|
167
|
+
const storageStrategyFactory = this.options.storageStrategyFactory || default_asset_storage_strategy_factory_1.defaultAssetStorageStrategyFactory;
|
|
168
|
+
this.assetStorage = await storageStrategyFactory(this.options);
|
|
169
|
+
config.assetOptions.assetPreviewStrategy =
|
|
170
|
+
(_a = this.options.previewStrategy) !== null && _a !== void 0 ? _a : new sharp_asset_preview_strategy_1.SharpAssetPreviewStrategy({
|
|
171
|
+
maxWidth: this.options.previewMaxWidth,
|
|
172
|
+
maxHeight: this.options.previewMaxHeight,
|
|
173
|
+
});
|
|
174
|
+
config.assetOptions.assetStorageStrategy = this.assetStorage;
|
|
175
|
+
config.assetOptions.assetNamingStrategy =
|
|
176
|
+
this.options.namingStrategy || new hashed_asset_naming_strategy_1.HashedAssetNamingStrategy();
|
|
177
|
+
return config;
|
|
178
|
+
}
|
|
179
|
+
constructor(processContext) {
|
|
180
|
+
this.processContext = processContext;
|
|
181
|
+
this.cacheDir = "cache";
|
|
182
|
+
this.presets = [
|
|
183
|
+
{ name: "tiny", width: 50, height: 50, mode: "crop" },
|
|
184
|
+
{ name: "thumb", width: 150, height: 150, mode: "crop" },
|
|
185
|
+
{ name: "small", width: 300, height: 300, mode: "resize" },
|
|
186
|
+
{ name: "medium", width: 500, height: 500, mode: "resize" },
|
|
187
|
+
{ name: "large", width: 800, height: 800, mode: "resize" },
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
/** @internal */
|
|
191
|
+
onApplicationBootstrap() {
|
|
192
|
+
if (this.processContext.isWorker) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (AssetServerPlugin_1.options.presets) {
|
|
196
|
+
for (const preset of AssetServerPlugin_1.options.presets) {
|
|
197
|
+
const existingIndex = this.presets.findIndex((p) => p.name === preset.name);
|
|
198
|
+
if (-1 < existingIndex) {
|
|
199
|
+
this.presets.splice(existingIndex, 1, preset);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
this.presets.push(preset);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Configure Cache-Control header
|
|
207
|
+
const { cacheHeader } = AssetServerPlugin_1.options;
|
|
208
|
+
if (!cacheHeader) {
|
|
209
|
+
this.cacheHeader = constants_1.DEFAULT_CACHE_HEADER;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
if (typeof cacheHeader === "string") {
|
|
213
|
+
this.cacheHeader = cacheHeader;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.cacheHeader = [
|
|
217
|
+
cacheHeader.restriction,
|
|
218
|
+
`max-age: ${cacheHeader.maxAge}`,
|
|
219
|
+
]
|
|
220
|
+
.filter((value) => !!value)
|
|
221
|
+
.join(", ");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const cachePath = path_1.default.join(AssetServerPlugin_1.options.assetUploadDir, this.cacheDir);
|
|
225
|
+
fs_extra_1.default.ensureDirSync(cachePath);
|
|
226
|
+
}
|
|
227
|
+
configure(consumer) {
|
|
228
|
+
if (this.processContext.isWorker) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
core_1.Logger.info("Creating asset server middleware", constants_1.loggerCtx);
|
|
232
|
+
consumer
|
|
233
|
+
.apply(this.createAssetServer())
|
|
234
|
+
.forRoutes(AssetServerPlugin_1.options.route);
|
|
235
|
+
(0, core_1.registerPluginStartupMessage)("Asset server", AssetServerPlugin_1.options.route);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Creates the image server instance
|
|
239
|
+
*/
|
|
240
|
+
createAssetServer() {
|
|
241
|
+
const assetServer = express_1.default.Router();
|
|
242
|
+
assetServer.use(this.sendAsset(), this.generateTransformedImage());
|
|
243
|
+
return assetServer;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Reads the file requested and send the response to the browser.
|
|
247
|
+
*/
|
|
248
|
+
sendAsset() {
|
|
249
|
+
return async (req, res, next) => {
|
|
250
|
+
var _a;
|
|
251
|
+
const key = this.getFileNameFromRequest(req);
|
|
252
|
+
try {
|
|
253
|
+
const file = await AssetServerPlugin_1.assetStorage.readFileToBuffer(key);
|
|
254
|
+
let mimeType = this.getMimeType(key);
|
|
255
|
+
if (!mimeType) {
|
|
256
|
+
mimeType =
|
|
257
|
+
((_a = (await getFileType(file))) === null || _a === void 0 ? void 0 : _a.mime) || "application/octet-stream";
|
|
258
|
+
}
|
|
259
|
+
res.contentType(mimeType);
|
|
260
|
+
res.setHeader("content-security-policy", "default-src 'self'");
|
|
261
|
+
res.setHeader("Cache-Control", this.cacheHeader);
|
|
262
|
+
res.send(file);
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
const err = new Error("File not found");
|
|
266
|
+
err.status = 404;
|
|
267
|
+
return next(err);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* If an exception was thrown by the first handler, then it may be because a transformed image
|
|
273
|
+
* is being requested which does not yet exist. In this case, this handler will generate the
|
|
274
|
+
* transformed image, save it to cache, and serve the result as a response.
|
|
275
|
+
*/
|
|
276
|
+
generateTransformedImage() {
|
|
277
|
+
return async (err, req, res, next) => {
|
|
278
|
+
var _a;
|
|
279
|
+
if (err && (err.status === 404 || err.statusCode === 404)) {
|
|
280
|
+
if (req.query) {
|
|
281
|
+
const decodedReqPath = decodeURIComponent(req.path);
|
|
282
|
+
core_1.Logger.debug(`Pre-cached Asset not found: ${decodedReqPath}`, constants_1.loggerCtx);
|
|
283
|
+
let file;
|
|
284
|
+
try {
|
|
285
|
+
file =
|
|
286
|
+
await AssetServerPlugin_1.assetStorage.readFileToBuffer(decodedReqPath);
|
|
287
|
+
}
|
|
288
|
+
catch (_err) {
|
|
289
|
+
res.status(404).send("Resource not found");
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const image = await (0, transform_image_1.transformImage)(file, req.query, this.presets || []);
|
|
293
|
+
try {
|
|
294
|
+
const imageBuffer = await image.toBuffer();
|
|
295
|
+
const cachedFileName = this.getFileNameFromRequest(req);
|
|
296
|
+
if (!req.query.cache || req.query.cache === "true") {
|
|
297
|
+
await AssetServerPlugin_1.assetStorage.writeFileFromBuffer(cachedFileName, imageBuffer);
|
|
298
|
+
core_1.Logger.debug(`Saved cached asset: ${cachedFileName}`, constants_1.loggerCtx);
|
|
299
|
+
}
|
|
300
|
+
let mimeType = this.getMimeType(cachedFileName);
|
|
301
|
+
if (!mimeType) {
|
|
302
|
+
mimeType = ((_a = (await getFileType(imageBuffer))) === null || _a === void 0 ? void 0 : _a.mime) || "image/jpeg";
|
|
303
|
+
}
|
|
304
|
+
res.set("Content-Type", mimeType);
|
|
305
|
+
res.setHeader("content-security-policy", "default-src 'self'");
|
|
306
|
+
res.send(imageBuffer);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
catch (e) {
|
|
310
|
+
core_1.Logger.error(e, constants_1.loggerCtx, e.stack);
|
|
311
|
+
res.status(500).send(e.message);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
next();
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
getFileNameFromRequest(req) {
|
|
320
|
+
const { w, h, mode, preset, fpx, fpy, format, q } = req.query;
|
|
321
|
+
const focalPoint = fpx && fpy ? `_fpx${fpx}_fpy${fpy}` : "";
|
|
322
|
+
const quality = q ? `_q${q}` : "";
|
|
323
|
+
const imageFormat = (0, common_1.getValidFormat)(format);
|
|
324
|
+
let imageParamsString = "";
|
|
325
|
+
if (w || h) {
|
|
326
|
+
const width = w || "";
|
|
327
|
+
const height = h || "";
|
|
328
|
+
imageParamsString = `_transform_w${width}_h${height}_m${mode}`;
|
|
329
|
+
}
|
|
330
|
+
else if (preset) {
|
|
331
|
+
if (this.presets && !!this.presets.find((p) => p.name === preset)) {
|
|
332
|
+
imageParamsString = `_transform_pre_${preset}`;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (focalPoint) {
|
|
336
|
+
imageParamsString += focalPoint;
|
|
337
|
+
}
|
|
338
|
+
if (imageFormat) {
|
|
339
|
+
imageParamsString += imageFormat;
|
|
340
|
+
}
|
|
341
|
+
if (quality) {
|
|
342
|
+
imageParamsString += quality;
|
|
343
|
+
}
|
|
344
|
+
const decodedReqPath = decodeURIComponent(req.path);
|
|
345
|
+
if (imageParamsString !== "") {
|
|
346
|
+
const imageParamHash = this.md5(imageParamsString);
|
|
347
|
+
return path_1.default.join(this.cacheDir, this.addSuffix(decodedReqPath, imageParamHash, imageFormat));
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
return decodedReqPath;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
md5(input) {
|
|
354
|
+
return (0, crypto_1.createHash)("md5").update(input).digest("hex");
|
|
355
|
+
}
|
|
356
|
+
addSuffix(fileName, suffix, ext) {
|
|
357
|
+
const originalExt = path_1.default.extname(fileName);
|
|
358
|
+
const effectiveExt = ext ? `.${ext}` : originalExt;
|
|
359
|
+
const baseName = path_1.default.basename(fileName, originalExt);
|
|
360
|
+
const dirName = path_1.default.dirname(fileName);
|
|
361
|
+
return path_1.default.join(dirName, `${baseName}${suffix}${effectiveExt}`);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Attempt to get the mime type from the file name.
|
|
365
|
+
*/
|
|
366
|
+
getMimeType(fileName) {
|
|
367
|
+
const ext = path_1.default.extname(fileName);
|
|
368
|
+
switch (ext) {
|
|
369
|
+
case ".jpg":
|
|
370
|
+
case ".jpeg":
|
|
371
|
+
return "image/jpeg";
|
|
372
|
+
case ".png":
|
|
373
|
+
return "image/png";
|
|
374
|
+
case ".gif":
|
|
375
|
+
return "image/gif";
|
|
376
|
+
case ".svg":
|
|
377
|
+
return "image/svg+xml";
|
|
378
|
+
case ".tiff":
|
|
379
|
+
return "image/tiff";
|
|
380
|
+
case ".webp":
|
|
381
|
+
return "image/webp";
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
exports.AssetServerPlugin = AssetServerPlugin;
|
|
386
|
+
exports.AssetServerPlugin = AssetServerPlugin = AssetServerPlugin_1 = __decorate([
|
|
387
|
+
(0, core_1.DeenruvPlugin)({
|
|
388
|
+
imports: [core_1.PluginCommonModule],
|
|
389
|
+
configuration: (config) => AssetServerPlugin.configure(config),
|
|
390
|
+
compatibility: "^0.0.0",
|
|
391
|
+
}),
|
|
392
|
+
__metadata("design:paramtypes", [core_1.ProcessContext])
|
|
393
|
+
], AssetServerPlugin);
|
|
394
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import { AwsCredentialIdentity, AwsCredentialIdentityProvider } from "@aws-sdk/types";
|
|
5
|
+
import { AssetStorageStrategy } from "@deenruv/core";
|
|
6
|
+
import { Request } from "express";
|
|
7
|
+
import { Readable } from "node:stream";
|
|
8
|
+
import { AssetServerOptions } from "./types";
|
|
9
|
+
/**
|
|
10
|
+
* @description
|
|
11
|
+
* Configuration for connecting to AWS S3.
|
|
12
|
+
*
|
|
13
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
14
|
+
* @docsPage S3AssetStorageStrategy
|
|
15
|
+
*/
|
|
16
|
+
export interface S3Config {
|
|
17
|
+
/**
|
|
18
|
+
* @description
|
|
19
|
+
* The credentials used to access your s3 account. You can supply either the access key ID & secret, or you can make use of a
|
|
20
|
+
* [shared credentials file](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html)
|
|
21
|
+
* To use a shared credentials file, import the `fromIni()` function from the "@aws-sdk/credential-provider-ini" or "@aws-sdk/credential-providers" package and supply
|
|
22
|
+
* the profile name (e.g. `{ profile: 'default' }`) as its argument.
|
|
23
|
+
*/
|
|
24
|
+
credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider;
|
|
25
|
+
/**
|
|
26
|
+
* @description
|
|
27
|
+
* The S3 bucket in which to store the assets. If it does not exist, it will be created on startup.
|
|
28
|
+
*/
|
|
29
|
+
bucket: string;
|
|
30
|
+
/**
|
|
31
|
+
* @description
|
|
32
|
+
* Configuration object passed directly to the AWS SDK.
|
|
33
|
+
* S3.Types.ClientConfiguration can be used after importing aws-sdk.
|
|
34
|
+
* Using type `any` in order to avoid the need to include `aws-sdk` dependency in general.
|
|
35
|
+
*/
|
|
36
|
+
nativeS3Configuration?: any;
|
|
37
|
+
/**
|
|
38
|
+
* @description
|
|
39
|
+
* Configuration object passed directly to the AWS SDK.
|
|
40
|
+
* ManagedUpload.ManagedUploadOptions can be used after importing aws-sdk.
|
|
41
|
+
* Using type `any` in order to avoid the need to include `aws-sdk` dependency in general.
|
|
42
|
+
*/
|
|
43
|
+
nativeS3UploadConfiguration?: any;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @description
|
|
47
|
+
* Returns a configured instance of the {@link S3AssetStorageStrategy} which can then be passed to the {@link AssetServerOptions}
|
|
48
|
+
* `storageStrategyFactory` property.
|
|
49
|
+
*
|
|
50
|
+
* Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
|
|
51
|
+
*
|
|
52
|
+
* ```sh
|
|
53
|
+
* npm install \@aws-sdk/client-s3 \@aws-sdk/lib-storage
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { AssetServerPlugin, configureS3AssetStorage } from '\@deenruv/asset-server-plugin';
|
|
59
|
+
* import { DefaultAssetNamingStrategy } from '\@deenruv/core';
|
|
60
|
+
* import { fromEnv } from '\@aws-sdk/credential-providers';
|
|
61
|
+
*
|
|
62
|
+
* // ...
|
|
63
|
+
*
|
|
64
|
+
* plugins: [
|
|
65
|
+
* AssetServerPlugin.init({
|
|
66
|
+
* route: 'assets',
|
|
67
|
+
* assetUploadDir: path.join(__dirname, 'assets'),
|
|
68
|
+
* namingStrategy: new DefaultAssetNamingStrategy(),
|
|
69
|
+
* storageStrategyFactory: configureS3AssetStorage({
|
|
70
|
+
* bucket: 'my-s3-bucket',
|
|
71
|
+
* credentials: fromEnv(), // or any other credential provider
|
|
72
|
+
* nativeS3Configuration: {
|
|
73
|
+
* region: process.env.AWS_REGION,
|
|
74
|
+
* },
|
|
75
|
+
* }),
|
|
76
|
+
* }),
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* ## Usage with MinIO
|
|
80
|
+
*
|
|
81
|
+
* Reference: [How to use AWS SDK for Javascript with MinIO Server](https://docs.min.io/docs/how-to-use-aws-sdk-for-javascript-with-minio-server.html)
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { AssetServerPlugin, configureS3AssetStorage } from '\@deenruv/asset-server-plugin';
|
|
86
|
+
* import { DefaultAssetNamingStrategy } from '\@deenruv/core';
|
|
87
|
+
*
|
|
88
|
+
* // ...
|
|
89
|
+
*
|
|
90
|
+
* plugins: [
|
|
91
|
+
* AssetServerPlugin.init({
|
|
92
|
+
* route: 'assets',
|
|
93
|
+
* assetUploadDir: path.join(__dirname, 'assets'),
|
|
94
|
+
* namingStrategy: new DefaultAssetNamingStrategy(),
|
|
95
|
+
* storageStrategyFactory: configureS3AssetStorage({
|
|
96
|
+
* bucket: 'my-minio-bucket',
|
|
97
|
+
* credentials: {
|
|
98
|
+
* accessKeyId: process.env.MINIO_ACCESS_KEY_ID,
|
|
99
|
+
* secretAccessKey: process.env.MINIO_SECRET_ACCESS_KEY,
|
|
100
|
+
* },
|
|
101
|
+
* nativeS3Configuration: {
|
|
102
|
+
* endpoint: process.env.MINIO_ENDPOINT ?? 'http://localhost:9000',
|
|
103
|
+
* forcePathStyle: true,
|
|
104
|
+
* signatureVersion: 'v4',
|
|
105
|
+
* // The `region` is required by the AWS SDK even when using MinIO,
|
|
106
|
+
* // so we just use a dummy value here.
|
|
107
|
+
* region: 'eu-west-1',
|
|
108
|
+
* },
|
|
109
|
+
* }),
|
|
110
|
+
* }),
|
|
111
|
+
* ```
|
|
112
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
113
|
+
* @docsPage S3AssetStorageStrategy
|
|
114
|
+
*/
|
|
115
|
+
export declare function configureS3AssetStorage(s3Config: S3Config): (options: AssetServerOptions) => S3AssetStorageStrategy;
|
|
116
|
+
/**
|
|
117
|
+
* @description
|
|
118
|
+
* An {@link AssetStorageStrategy} which uses [Amazon S3](https://aws.amazon.com/s3/) object storage service.
|
|
119
|
+
* To us this strategy you must first have access to an AWS account.
|
|
120
|
+
* See their [getting started guide](https://aws.amazon.com/s3/getting-started/) for how to get set up.
|
|
121
|
+
*
|
|
122
|
+
* Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
|
|
123
|
+
*
|
|
124
|
+
* ```sh
|
|
125
|
+
* npm install \@aws-sdk/client-s3 \@aws-sdk/lib-storage
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* **Note:** Rather than instantiating this manually, use the {@link configureS3AssetStorage} function.
|
|
129
|
+
*
|
|
130
|
+
* ## Use with S3-compatible services (MinIO)
|
|
131
|
+
* This strategy will also work with any S3-compatible object storage solutions, such as [MinIO](https://min.io/).
|
|
132
|
+
* See the {@link configureS3AssetStorage} for an example with MinIO.
|
|
133
|
+
*
|
|
134
|
+
* @docsCategory asset-server-plugin
|
|
135
|
+
* @docsPage S3AssetStorageStrategy
|
|
136
|
+
* @docsWeight 0
|
|
137
|
+
*/
|
|
138
|
+
export declare class S3AssetStorageStrategy implements AssetStorageStrategy {
|
|
139
|
+
private s3Config;
|
|
140
|
+
readonly toAbsoluteUrl: (request: Request, identifier: string) => string;
|
|
141
|
+
private AWS;
|
|
142
|
+
private libStorage;
|
|
143
|
+
private s3Client;
|
|
144
|
+
constructor(s3Config: S3Config, toAbsoluteUrl: (request: Request, identifier: string) => string);
|
|
145
|
+
init(): Promise<void>;
|
|
146
|
+
destroy?: (() => void | Promise<void>) | undefined;
|
|
147
|
+
writeFileFromBuffer(fileName: string, data: Buffer): Promise<string>;
|
|
148
|
+
writeFileFromStream(fileName: string, data: Readable): Promise<string>;
|
|
149
|
+
readFileToBuffer(identifier: string): Promise<Buffer>;
|
|
150
|
+
readFileToStream(identifier: string): Promise<Readable>;
|
|
151
|
+
private readFile;
|
|
152
|
+
private writeFile;
|
|
153
|
+
deleteFile(identifier: string): Promise<void>;
|
|
154
|
+
fileExists(fileName: string): Promise<boolean>;
|
|
155
|
+
private getObjectParams;
|
|
156
|
+
private ensureBucket;
|
|
157
|
+
private getCredentials;
|
|
158
|
+
private isCredentialsProfile;
|
|
159
|
+
}
|