@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,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
26
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
27
|
+
var m = o[Symbol.asyncIterator], i;
|
|
28
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
29
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
30
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
31
|
+
};
|
|
32
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.S3AssetStorageStrategy = exports.configureS3AssetStorage = void 0;
|
|
34
|
+
const core_1 = require("@deenruv/core");
|
|
35
|
+
const path = __importStar(require("node:path"));
|
|
36
|
+
const node_stream_1 = require("node:stream");
|
|
37
|
+
const common_1 = require("./common");
|
|
38
|
+
const constants_1 = require("./constants");
|
|
39
|
+
/**
|
|
40
|
+
* @description
|
|
41
|
+
* Returns a configured instance of the {@link S3AssetStorageStrategy} which can then be passed to the {@link AssetServerOptions}
|
|
42
|
+
* `storageStrategyFactory` property.
|
|
43
|
+
*
|
|
44
|
+
* Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
|
|
45
|
+
*
|
|
46
|
+
* ```sh
|
|
47
|
+
* npm install \@aws-sdk/client-s3 \@aws-sdk/lib-storage
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { AssetServerPlugin, configureS3AssetStorage } from '\@deenruv/asset-server-plugin';
|
|
53
|
+
* import { DefaultAssetNamingStrategy } from '\@deenruv/core';
|
|
54
|
+
* import { fromEnv } from '\@aws-sdk/credential-providers';
|
|
55
|
+
*
|
|
56
|
+
* // ...
|
|
57
|
+
*
|
|
58
|
+
* plugins: [
|
|
59
|
+
* AssetServerPlugin.init({
|
|
60
|
+
* route: 'assets',
|
|
61
|
+
* assetUploadDir: path.join(__dirname, 'assets'),
|
|
62
|
+
* namingStrategy: new DefaultAssetNamingStrategy(),
|
|
63
|
+
* storageStrategyFactory: configureS3AssetStorage({
|
|
64
|
+
* bucket: 'my-s3-bucket',
|
|
65
|
+
* credentials: fromEnv(), // or any other credential provider
|
|
66
|
+
* nativeS3Configuration: {
|
|
67
|
+
* region: process.env.AWS_REGION,
|
|
68
|
+
* },
|
|
69
|
+
* }),
|
|
70
|
+
* }),
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ## Usage with MinIO
|
|
74
|
+
*
|
|
75
|
+
* 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)
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { AssetServerPlugin, configureS3AssetStorage } from '\@deenruv/asset-server-plugin';
|
|
80
|
+
* import { DefaultAssetNamingStrategy } from '\@deenruv/core';
|
|
81
|
+
*
|
|
82
|
+
* // ...
|
|
83
|
+
*
|
|
84
|
+
* plugins: [
|
|
85
|
+
* AssetServerPlugin.init({
|
|
86
|
+
* route: 'assets',
|
|
87
|
+
* assetUploadDir: path.join(__dirname, 'assets'),
|
|
88
|
+
* namingStrategy: new DefaultAssetNamingStrategy(),
|
|
89
|
+
* storageStrategyFactory: configureS3AssetStorage({
|
|
90
|
+
* bucket: 'my-minio-bucket',
|
|
91
|
+
* credentials: {
|
|
92
|
+
* accessKeyId: process.env.MINIO_ACCESS_KEY_ID,
|
|
93
|
+
* secretAccessKey: process.env.MINIO_SECRET_ACCESS_KEY,
|
|
94
|
+
* },
|
|
95
|
+
* nativeS3Configuration: {
|
|
96
|
+
* endpoint: process.env.MINIO_ENDPOINT ?? 'http://localhost:9000',
|
|
97
|
+
* forcePathStyle: true,
|
|
98
|
+
* signatureVersion: 'v4',
|
|
99
|
+
* // The `region` is required by the AWS SDK even when using MinIO,
|
|
100
|
+
* // so we just use a dummy value here.
|
|
101
|
+
* region: 'eu-west-1',
|
|
102
|
+
* },
|
|
103
|
+
* }),
|
|
104
|
+
* }),
|
|
105
|
+
* ```
|
|
106
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
107
|
+
* @docsPage S3AssetStorageStrategy
|
|
108
|
+
*/
|
|
109
|
+
function configureS3AssetStorage(s3Config) {
|
|
110
|
+
return (options) => {
|
|
111
|
+
const prefixFn = (0, common_1.getAssetUrlPrefixFn)(options);
|
|
112
|
+
const toAbsoluteUrlFn = (request, identifier) => {
|
|
113
|
+
if (!identifier) {
|
|
114
|
+
return "";
|
|
115
|
+
}
|
|
116
|
+
const prefix = prefixFn(request, identifier);
|
|
117
|
+
return identifier.startsWith(prefix)
|
|
118
|
+
? identifier
|
|
119
|
+
: `${prefix}${identifier}`;
|
|
120
|
+
};
|
|
121
|
+
return new S3AssetStorageStrategy(s3Config, toAbsoluteUrlFn);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
exports.configureS3AssetStorage = configureS3AssetStorage;
|
|
125
|
+
/**
|
|
126
|
+
* @description
|
|
127
|
+
* An {@link AssetStorageStrategy} which uses [Amazon S3](https://aws.amazon.com/s3/) object storage service.
|
|
128
|
+
* To us this strategy you must first have access to an AWS account.
|
|
129
|
+
* See their [getting started guide](https://aws.amazon.com/s3/getting-started/) for how to get set up.
|
|
130
|
+
*
|
|
131
|
+
* Before using this strategy, make sure you have the `@aws-sdk/client-s3` and `@aws-sdk/lib-storage` package installed:
|
|
132
|
+
*
|
|
133
|
+
* ```sh
|
|
134
|
+
* npm install \@aws-sdk/client-s3 \@aws-sdk/lib-storage
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* **Note:** Rather than instantiating this manually, use the {@link configureS3AssetStorage} function.
|
|
138
|
+
*
|
|
139
|
+
* ## Use with S3-compatible services (MinIO)
|
|
140
|
+
* This strategy will also work with any S3-compatible object storage solutions, such as [MinIO](https://min.io/).
|
|
141
|
+
* See the {@link configureS3AssetStorage} for an example with MinIO.
|
|
142
|
+
*
|
|
143
|
+
* @docsCategory asset-server-plugin
|
|
144
|
+
* @docsPage S3AssetStorageStrategy
|
|
145
|
+
* @docsWeight 0
|
|
146
|
+
*/
|
|
147
|
+
class S3AssetStorageStrategy {
|
|
148
|
+
constructor(s3Config, toAbsoluteUrl) {
|
|
149
|
+
this.s3Config = s3Config;
|
|
150
|
+
this.toAbsoluteUrl = toAbsoluteUrl;
|
|
151
|
+
}
|
|
152
|
+
async init() {
|
|
153
|
+
try {
|
|
154
|
+
this.AWS = await import("@aws-sdk/client-s3");
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
core_1.Logger.error('Could not find the "@aws-sdk/client-s3" package. Make sure it is installed', constants_1.loggerCtx, err.stack);
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
this.libStorage = await import("@aws-sdk/lib-storage");
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
core_1.Logger.error('Could not find the "@aws-sdk/lib-storage" package. Make sure it is installed', constants_1.loggerCtx, err.stack);
|
|
164
|
+
}
|
|
165
|
+
const config = Object.assign(Object.assign({}, this.s3Config.nativeS3Configuration), { credentials: await this.getCredentials() });
|
|
166
|
+
this.s3Client = new this.AWS.S3Client(config);
|
|
167
|
+
await this.ensureBucket();
|
|
168
|
+
}
|
|
169
|
+
async writeFileFromBuffer(fileName, data) {
|
|
170
|
+
return this.writeFile(fileName, data);
|
|
171
|
+
}
|
|
172
|
+
async writeFileFromStream(fileName, data) {
|
|
173
|
+
return this.writeFile(fileName, data);
|
|
174
|
+
}
|
|
175
|
+
async readFileToBuffer(identifier) {
|
|
176
|
+
var _a, e_1, _b, _c;
|
|
177
|
+
const body = await this.readFile(identifier);
|
|
178
|
+
if (!body) {
|
|
179
|
+
core_1.Logger.error(`Got undefined Body for ${identifier}`, constants_1.loggerCtx);
|
|
180
|
+
return Buffer.from("");
|
|
181
|
+
}
|
|
182
|
+
const chunks = [];
|
|
183
|
+
try {
|
|
184
|
+
for (var _d = true, body_1 = __asyncValues(body), body_1_1; body_1_1 = await body_1.next(), _a = body_1_1.done, !_a; _d = true) {
|
|
185
|
+
_c = body_1_1.value;
|
|
186
|
+
_d = false;
|
|
187
|
+
const chunk = _c;
|
|
188
|
+
chunks.push(chunk);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
192
|
+
finally {
|
|
193
|
+
try {
|
|
194
|
+
if (!_d && !_a && (_b = body_1.return)) await _b.call(body_1);
|
|
195
|
+
}
|
|
196
|
+
finally { if (e_1) throw e_1.error; }
|
|
197
|
+
}
|
|
198
|
+
return Buffer.concat(chunks);
|
|
199
|
+
}
|
|
200
|
+
async readFileToStream(identifier) {
|
|
201
|
+
const body = await this.readFile(identifier);
|
|
202
|
+
if (!body) {
|
|
203
|
+
return new node_stream_1.Readable({
|
|
204
|
+
read() {
|
|
205
|
+
this.push(null);
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return body;
|
|
210
|
+
}
|
|
211
|
+
async readFile(identifier) {
|
|
212
|
+
const { GetObjectCommand } = this.AWS;
|
|
213
|
+
const result = await this.s3Client.send(new GetObjectCommand(this.getObjectParams(identifier)));
|
|
214
|
+
return result.Body;
|
|
215
|
+
}
|
|
216
|
+
async writeFile(fileName, data) {
|
|
217
|
+
const { Upload } = this.libStorage;
|
|
218
|
+
const upload = new Upload({
|
|
219
|
+
client: this.s3Client,
|
|
220
|
+
params: Object.assign(Object.assign({}, this.s3Config.nativeS3UploadConfiguration), { Bucket: this.s3Config.bucket, Key: fileName, Body: data }),
|
|
221
|
+
});
|
|
222
|
+
return upload.done().then((result) => {
|
|
223
|
+
if (!("Key" in result) || !result.Key) {
|
|
224
|
+
core_1.Logger.error(`Got undefined Key for ${fileName}`, constants_1.loggerCtx);
|
|
225
|
+
throw new Error(`Got undefined Key for ${fileName}`);
|
|
226
|
+
}
|
|
227
|
+
return result.Key;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
async deleteFile(identifier) {
|
|
231
|
+
const { DeleteObjectCommand } = this.AWS;
|
|
232
|
+
await this.s3Client.send(new DeleteObjectCommand(this.getObjectParams(identifier)));
|
|
233
|
+
}
|
|
234
|
+
async fileExists(fileName) {
|
|
235
|
+
const { HeadObjectCommand } = this.AWS;
|
|
236
|
+
try {
|
|
237
|
+
await this.s3Client.send(new HeadObjectCommand(this.getObjectParams(fileName)));
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
getObjectParams(identifier) {
|
|
245
|
+
return {
|
|
246
|
+
Bucket: this.s3Config.bucket,
|
|
247
|
+
Key: path.join(identifier.replace(/^\//, "")),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
async ensureBucket(bucket = this.s3Config.bucket) {
|
|
251
|
+
const { HeadBucketCommand, CreateBucketCommand } = this.AWS;
|
|
252
|
+
try {
|
|
253
|
+
await this.s3Client.send(new HeadBucketCommand({ Bucket: bucket }));
|
|
254
|
+
core_1.Logger.verbose(`Found S3 bucket "${bucket}"`, constants_1.loggerCtx);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
core_1.Logger.verbose(`Could not find bucket "${bucket}: ${JSON.stringify(err.message)}". Attempting to create...`);
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
await this.s3Client.send(new CreateBucketCommand({ Bucket: bucket, ACL: "private" }));
|
|
262
|
+
core_1.Logger.verbose(`Created S3 bucket "${bucket}"`, constants_1.loggerCtx);
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
core_1.Logger.error(`Could not find nor create the S3 bucket "${bucket}: ${JSON.stringify(err.message)}"`, constants_1.loggerCtx, err.stack);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async getCredentials() {
|
|
269
|
+
if (this.s3Config.credentials == null) {
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
if (this.isCredentialsProfile(this.s3Config.credentials)) {
|
|
273
|
+
core_1.Logger.warn('The "profile" property of the "s3Config.credentials" is deprecated. ' +
|
|
274
|
+
'Please use the "fromIni()" function from the "@aws-sdk/credential-provider-ini" or "@aws-sdk/credential-providers" package instead.', constants_1.loggerCtx);
|
|
275
|
+
return (await import("@aws-sdk/credential-provider-ini")).fromIni({
|
|
276
|
+
profile: this.s3Config.credentials.profile,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return this.s3Config.credentials;
|
|
280
|
+
}
|
|
281
|
+
isCredentialsProfile(credentials) {
|
|
282
|
+
return (credentials !== null &&
|
|
283
|
+
typeof credentials === "object" &&
|
|
284
|
+
"profile" in credentials &&
|
|
285
|
+
Object.keys(credentials).length === 1);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
exports.S3AssetStorageStrategy = S3AssetStorageStrategy;
|
|
289
|
+
//# sourceMappingURL=s3-asset-storage-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-asset-storage-strategy.js","sourceRoot":"","sources":["../../src/s3-asset-storage-strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { AssetPreviewStrategy, RequestContext } from "@deenruv/core";
|
|
4
|
+
import sharp from "sharp";
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* This {@link AssetPreviewStrategy} uses the [Sharp library](https://sharp.pixelplumbing.com/) to generate
|
|
8
|
+
* preview images of uploaded binary files. For non-image binaries, a generic "file" icon with the mime type
|
|
9
|
+
* overlay will be generated.
|
|
10
|
+
*
|
|
11
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
12
|
+
* @docsPage SharpAssetPreviewStrategy
|
|
13
|
+
*/
|
|
14
|
+
interface SharpAssetPreviewConfig {
|
|
15
|
+
/**
|
|
16
|
+
* @description
|
|
17
|
+
* The max height in pixels of a generated preview image.
|
|
18
|
+
*
|
|
19
|
+
* @default 1600
|
|
20
|
+
*/
|
|
21
|
+
maxHeight?: number;
|
|
22
|
+
/**
|
|
23
|
+
* @description
|
|
24
|
+
* The max width in pixels of a generated preview image.
|
|
25
|
+
*
|
|
26
|
+
* @default 1600
|
|
27
|
+
*/
|
|
28
|
+
maxWidth?: number;
|
|
29
|
+
/**
|
|
30
|
+
* @description
|
|
31
|
+
* Set Sharp's options for encoding jpeg files: https://sharp.pixelplumbing.com/api-output#jpeg
|
|
32
|
+
*
|
|
33
|
+
* @since 1.7.0
|
|
34
|
+
*/
|
|
35
|
+
jpegOptions?: sharp.JpegOptions;
|
|
36
|
+
/**
|
|
37
|
+
* @description
|
|
38
|
+
* Set Sharp's options for encoding png files: https://sharp.pixelplumbing.com/api-output#png
|
|
39
|
+
*
|
|
40
|
+
* @since 1.7.0
|
|
41
|
+
*/
|
|
42
|
+
pngOptions?: sharp.PngOptions;
|
|
43
|
+
/**
|
|
44
|
+
* @description
|
|
45
|
+
* Set Sharp's options for encoding webp files: https://sharp.pixelplumbing.com/api-output#webp
|
|
46
|
+
*
|
|
47
|
+
* @since 1.7.0
|
|
48
|
+
*/
|
|
49
|
+
webpOptions?: sharp.WebpOptions;
|
|
50
|
+
/**
|
|
51
|
+
* @description
|
|
52
|
+
* Set Sharp's options for encoding gif files: https://sharp.pixelplumbing.com/api-output#gif
|
|
53
|
+
*
|
|
54
|
+
* @since 1.7.0
|
|
55
|
+
*/
|
|
56
|
+
gifOptions?: sharp.GifOptions;
|
|
57
|
+
/**
|
|
58
|
+
* @description
|
|
59
|
+
* Set Sharp's options for encoding avif files: https://sharp.pixelplumbing.com/api-output#avif
|
|
60
|
+
*
|
|
61
|
+
* @since 1.7.0
|
|
62
|
+
*/
|
|
63
|
+
avifOptions?: sharp.AvifOptions;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @description
|
|
67
|
+
* This {@link AssetPreviewStrategy} uses the [Sharp library](https://sharp.pixelplumbing.com/) to generate
|
|
68
|
+
* preview images of uploaded binary files. For non-image binaries, a generic "file" icon with the mime type
|
|
69
|
+
* overlay will be generated.
|
|
70
|
+
*
|
|
71
|
+
* By default, this strategy will produce previews up to maximum dimensions of 1600 x 1600 pixels. The created
|
|
72
|
+
* preview images will match the input format - so a source file in jpeg format will output a jpeg preview,
|
|
73
|
+
* a webp source file will output a webp preview, and so on.
|
|
74
|
+
*
|
|
75
|
+
* The settings for the outputs will default to Sharp's defaults (https://sharp.pixelplumbing.com/api-output).
|
|
76
|
+
* However, it is possible to pass your own configurations to control the output of each format:
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* AssetServerPlugin.init({
|
|
80
|
+
* previewStrategy: new SharpAssetPreviewStrategy({
|
|
81
|
+
* jpegOptions: { quality: 95 },
|
|
82
|
+
* webpOptions: { quality: 95 },
|
|
83
|
+
* }),
|
|
84
|
+
* }),
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
88
|
+
* @docsPage SharpAssetPreviewStrategy
|
|
89
|
+
* @docsWeight 0
|
|
90
|
+
*/
|
|
91
|
+
export declare class SharpAssetPreviewStrategy implements AssetPreviewStrategy {
|
|
92
|
+
private readonly defaultConfig;
|
|
93
|
+
private readonly config;
|
|
94
|
+
constructor(config?: SharpAssetPreviewConfig);
|
|
95
|
+
generatePreviewImage(ctx: RequestContext, mimeType: string, data: Buffer): Promise<Buffer>;
|
|
96
|
+
private generateMimeTypeOverlay;
|
|
97
|
+
private generateBinaryFilePreview;
|
|
98
|
+
}
|
|
99
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SharpAssetPreviewStrategy = void 0;
|
|
7
|
+
const generated_types_1 = require("@deenruv/common/lib/generated-types");
|
|
8
|
+
const core_1 = require("@deenruv/core");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
11
|
+
const constants_1 = require("./constants");
|
|
12
|
+
/**
|
|
13
|
+
* @description
|
|
14
|
+
* This {@link AssetPreviewStrategy} uses the [Sharp library](https://sharp.pixelplumbing.com/) to generate
|
|
15
|
+
* preview images of uploaded binary files. For non-image binaries, a generic "file" icon with the mime type
|
|
16
|
+
* overlay will be generated.
|
|
17
|
+
*
|
|
18
|
+
* By default, this strategy will produce previews up to maximum dimensions of 1600 x 1600 pixels. The created
|
|
19
|
+
* preview images will match the input format - so a source file in jpeg format will output a jpeg preview,
|
|
20
|
+
* a webp source file will output a webp preview, and so on.
|
|
21
|
+
*
|
|
22
|
+
* The settings for the outputs will default to Sharp's defaults (https://sharp.pixelplumbing.com/api-output).
|
|
23
|
+
* However, it is possible to pass your own configurations to control the output of each format:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* AssetServerPlugin.init({
|
|
27
|
+
* previewStrategy: new SharpAssetPreviewStrategy({
|
|
28
|
+
* jpegOptions: { quality: 95 },
|
|
29
|
+
* webpOptions: { quality: 95 },
|
|
30
|
+
* }),
|
|
31
|
+
* }),
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @docsCategory core plugins/AssetServerPlugin
|
|
35
|
+
* @docsPage SharpAssetPreviewStrategy
|
|
36
|
+
* @docsWeight 0
|
|
37
|
+
*/
|
|
38
|
+
class SharpAssetPreviewStrategy {
|
|
39
|
+
constructor(config) {
|
|
40
|
+
this.defaultConfig = {
|
|
41
|
+
maxHeight: 1600,
|
|
42
|
+
maxWidth: 1600,
|
|
43
|
+
jpegOptions: {},
|
|
44
|
+
pngOptions: {},
|
|
45
|
+
webpOptions: {},
|
|
46
|
+
gifOptions: {},
|
|
47
|
+
avifOptions: {},
|
|
48
|
+
};
|
|
49
|
+
this.config = Object.assign(Object.assign({}, this.defaultConfig), (config !== null && config !== void 0 ? config : {}));
|
|
50
|
+
}
|
|
51
|
+
async generatePreviewImage(ctx, mimeType, data) {
|
|
52
|
+
const assetType = (0, core_1.getAssetType)(mimeType);
|
|
53
|
+
const { maxWidth, maxHeight } = this.config;
|
|
54
|
+
if (assetType === generated_types_1.AssetType.IMAGE) {
|
|
55
|
+
try {
|
|
56
|
+
const image = (0, sharp_1.default)(data, { failOn: "truncated" }).rotate();
|
|
57
|
+
const metadata = await image.metadata();
|
|
58
|
+
const width = metadata.width || 0;
|
|
59
|
+
const height = metadata.height || 0;
|
|
60
|
+
if (maxWidth < width || maxHeight < height) {
|
|
61
|
+
image.resize(maxWidth, maxHeight, { fit: "inside" });
|
|
62
|
+
}
|
|
63
|
+
if (mimeType === "image/svg+xml") {
|
|
64
|
+
// Convert the SVG to a raster for the preview
|
|
65
|
+
return image.toBuffer();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
switch (metadata.format) {
|
|
69
|
+
case "jpeg":
|
|
70
|
+
case "jpg":
|
|
71
|
+
return image.jpeg(this.config.jpegOptions).toBuffer();
|
|
72
|
+
case "png":
|
|
73
|
+
return image.png(this.config.pngOptions).toBuffer();
|
|
74
|
+
case "webp":
|
|
75
|
+
return image.webp(this.config.webpOptions).toBuffer();
|
|
76
|
+
case "gif":
|
|
77
|
+
return image.gif(this.config.jpegOptions).toBuffer();
|
|
78
|
+
case "avif":
|
|
79
|
+
return image.avif(this.config.avifOptions).toBuffer();
|
|
80
|
+
default:
|
|
81
|
+
return image.toBuffer();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
core_1.Logger.error(`An error occurred when generating preview for image with mimeType ${mimeType}: ${JSON.stringify(err.message)}`, constants_1.loggerCtx);
|
|
87
|
+
return this.generateBinaryFilePreview(mimeType);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return this.generateBinaryFilePreview(mimeType);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
generateMimeTypeOverlay(mimeType) {
|
|
95
|
+
return Buffer.from(`
|
|
96
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="150" width="800">
|
|
97
|
+
<style>
|
|
98
|
+
text {
|
|
99
|
+
font-size: 64px;
|
|
100
|
+
font-family: Arial, sans-serif;
|
|
101
|
+
fill: #666;
|
|
102
|
+
}
|
|
103
|
+
</style>
|
|
104
|
+
|
|
105
|
+
<text x="400" y="110" text-anchor="middle" width="800">${mimeType}</text>
|
|
106
|
+
</svg>`);
|
|
107
|
+
}
|
|
108
|
+
generateBinaryFilePreview(mimeType) {
|
|
109
|
+
return (0, sharp_1.default)(path_1.default.join(__dirname, "file-icon.png"))
|
|
110
|
+
.resize(800, 800, { fit: "outside" })
|
|
111
|
+
.composite([
|
|
112
|
+
{
|
|
113
|
+
input: this.generateMimeTypeOverlay(mimeType),
|
|
114
|
+
gravity: sharp_1.default.gravity.center,
|
|
115
|
+
},
|
|
116
|
+
])
|
|
117
|
+
.toBuffer();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.SharpAssetPreviewStrategy = SharpAssetPreviewStrategy;
|
|
121
|
+
//# sourceMappingURL=sharp-asset-preview-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharp-asset-preview-strategy.js","sourceRoot":"","sources":["../../src/sharp-asset-preview-strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import sharp, { Region } from "sharp";
|
|
4
|
+
import { ImageTransformPreset } from "./types";
|
|
5
|
+
export type Dimensions = {
|
|
6
|
+
w: number;
|
|
7
|
+
h: number;
|
|
8
|
+
};
|
|
9
|
+
export type Point = {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Applies transforms to the given image according to the query params passed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function transformImage(originalImage: Buffer, queryParams: Record<string, string>, presets: ImageTransformPreset[]): Promise<sharp.Sharp>;
|
|
17
|
+
/**
|
|
18
|
+
* Resize an image but keep it centered on the focal point.
|
|
19
|
+
* Based on the method outlined in https://github.com/lovell/sharp/issues/1198#issuecomment-384591756
|
|
20
|
+
*/
|
|
21
|
+
export declare function resizeToFocalPoint(original: Dimensions, target: Dimensions, focalPoint: Point): {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
region: Region;
|
|
25
|
+
};
|