@webiny/api-file-manager-s3 0.0.0-unstable.99666aeb00 → 0.0.0-unstable.a9593f74dd

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 (115) hide show
  1. package/assetDelivery/assetDeliveryConfig.d.ts +6 -0
  2. package/assetDelivery/assetDeliveryConfig.js +46 -0
  3. package/assetDelivery/assetDeliveryConfig.js.map +1 -0
  4. package/assetDelivery/createAssetDelivery.d.ts +3 -0
  5. package/assetDelivery/createAssetDelivery.js +20 -0
  6. package/assetDelivery/createAssetDelivery.js.map +1 -0
  7. package/assetDelivery/s3/S3AssetMetadataReader.d.ts +15 -0
  8. package/assetDelivery/s3/S3AssetMetadataReader.js +36 -0
  9. package/assetDelivery/s3/S3AssetMetadataReader.js.map +1 -0
  10. package/assetDelivery/s3/S3AssetResolver.d.ts +8 -0
  11. package/assetDelivery/s3/S3AssetResolver.js +37 -0
  12. package/assetDelivery/s3/S3AssetResolver.js.map +1 -0
  13. package/assetDelivery/s3/S3ContentsReader.d.ts +9 -0
  14. package/assetDelivery/s3/S3ContentsReader.js +27 -0
  15. package/assetDelivery/s3/S3ContentsReader.js.map +1 -0
  16. package/assetDelivery/s3/S3ErrorAssetReply.d.ts +4 -0
  17. package/assetDelivery/s3/S3ErrorAssetReply.js +20 -0
  18. package/assetDelivery/s3/S3ErrorAssetReply.js.map +1 -0
  19. package/assetDelivery/s3/S3OutputStrategy.d.ts +14 -0
  20. package/assetDelivery/s3/S3OutputStrategy.js +39 -0
  21. package/assetDelivery/s3/S3OutputStrategy.js.map +1 -0
  22. package/assetDelivery/s3/S3RedirectAssetReply.d.ts +4 -0
  23. package/assetDelivery/s3/S3RedirectAssetReply.js +23 -0
  24. package/assetDelivery/s3/S3RedirectAssetReply.js.map +1 -0
  25. package/assetDelivery/s3/S3StreamAssetReply.d.ts +4 -0
  26. package/assetDelivery/s3/S3StreamAssetReply.js +22 -0
  27. package/assetDelivery/s3/S3StreamAssetReply.js.map +1 -0
  28. package/assetDelivery/s3/SharpTransform.d.ts +18 -0
  29. package/assetDelivery/s3/SharpTransform.js +156 -0
  30. package/assetDelivery/s3/SharpTransform.js.map +1 -0
  31. package/assetDelivery/s3/transformation/AssetKeyGenerator.d.ts +8 -0
  32. package/assetDelivery/s3/transformation/AssetKeyGenerator.js +29 -0
  33. package/assetDelivery/s3/transformation/AssetKeyGenerator.js.map +1 -0
  34. package/assetDelivery/s3/transformation/CallableContentsReader.d.ts +11 -0
  35. package/assetDelivery/s3/transformation/CallableContentsReader.js +17 -0
  36. package/assetDelivery/s3/transformation/CallableContentsReader.js.map +1 -0
  37. package/assetDelivery/s3/transformation/WidthCollection.d.ts +7 -0
  38. package/assetDelivery/s3/transformation/WidthCollection.js +27 -0
  39. package/assetDelivery/s3/transformation/WidthCollection.js.map +1 -0
  40. package/assetDelivery/s3/transformation/legacyUtils.d.ts +12 -0
  41. package/assetDelivery/s3/transformation/legacyUtils.js +38 -0
  42. package/assetDelivery/s3/transformation/legacyUtils.js.map +1 -0
  43. package/assetDelivery/s3/transformation/utils.d.ts +11 -0
  44. package/assetDelivery/s3/transformation/utils.js +36 -0
  45. package/assetDelivery/s3/transformation/utils.js.map +1 -0
  46. package/flushCdnCache/CdnPathsGenerator.d.ts +4 -0
  47. package/flushCdnCache/CdnPathsGenerator.js +14 -0
  48. package/flushCdnCache/CdnPathsGenerator.js.map +1 -0
  49. package/flushCdnCache/InvalidateCacheTask.d.ts +18 -0
  50. package/flushCdnCache/InvalidateCacheTask.js +78 -0
  51. package/flushCdnCache/InvalidateCacheTask.js.map +1 -0
  52. package/flushCdnCache/flushCacheOnFileDelete.d.ts +3 -0
  53. package/flushCdnCache/flushCacheOnFileDelete.js +34 -0
  54. package/flushCdnCache/flushCacheOnFileDelete.js.map +1 -0
  55. package/flushCdnCache/flushCacheOnFileUpdate.d.ts +3 -0
  56. package/flushCdnCache/flushCacheOnFileUpdate.js +40 -0
  57. package/flushCdnCache/flushCacheOnFileUpdate.js.map +1 -0
  58. package/flushCdnCache/index.d.ts +1 -0
  59. package/flushCdnCache/index.js +15 -0
  60. package/flushCdnCache/index.js.map +1 -0
  61. package/flushCdnCache/invalidateCacheTaskDefinition.d.ts +2 -0
  62. package/flushCdnCache/invalidateCacheTaskDefinition.js +22 -0
  63. package/flushCdnCache/invalidateCacheTaskDefinition.js.map +1 -0
  64. package/index.d.ts +3 -1
  65. package/index.js +20 -2
  66. package/index.js.map +1 -1
  67. package/multiPartUpload/CompleteMultiPartUploadUseCase.d.ts +1 -1
  68. package/multiPartUpload/CompleteMultiPartUploadUseCase.js +10 -10
  69. package/multiPartUpload/CompleteMultiPartUploadUseCase.js.map +1 -1
  70. package/multiPartUpload/CreateMultiPartUploadUseCase.d.ts +5 -8
  71. package/multiPartUpload/CreateMultiPartUploadUseCase.js +16 -15
  72. package/multiPartUpload/CreateMultiPartUploadUseCase.js.map +1 -1
  73. package/package.json +22 -13
  74. package/plugins/addFileMetadata.d.ts +10 -0
  75. package/plugins/addFileMetadata.js +67 -0
  76. package/plugins/addFileMetadata.js.map +1 -0
  77. package/plugins/checkPermissions.js +3 -1
  78. package/plugins/checkPermissions.js.map +1 -1
  79. package/plugins/fileStorageS3.d.ts +2 -2
  80. package/plugins/fileStorageS3.js +41 -36
  81. package/plugins/fileStorageS3.js.map +1 -1
  82. package/plugins/graphqlFileStorageS3.js +22 -14
  83. package/plugins/graphqlFileStorageS3.js.map +1 -1
  84. package/types.d.ts +4 -4
  85. package/types.js +3 -1
  86. package/types.js.map +1 -1
  87. package/utils/FileExtension.d.ts +6 -0
  88. package/utils/FileExtension.js +24 -0
  89. package/utils/FileExtension.js.map +1 -0
  90. package/utils/FileKey.d.ts +11 -0
  91. package/utils/FileKey.js +33 -0
  92. package/utils/FileKey.js.map +1 -0
  93. package/utils/FileKey.test.d.ts +1 -0
  94. package/utils/FileKey.test.js +60 -0
  95. package/utils/FileKey.test.js.map +1 -0
  96. package/utils/FileNormalizer.d.ts +18 -0
  97. package/utils/FileNormalizer.js +49 -0
  98. package/utils/FileNormalizer.js.map +1 -0
  99. package/utils/FileUploadModifier.d.ts +30 -0
  100. package/utils/FileUploadModifier.js +49 -0
  101. package/utils/FileUploadModifier.js.map +1 -0
  102. package/utils/createFileNormalizerFromContext.d.ts +3 -0
  103. package/utils/createFileNormalizerFromContext.js +15 -0
  104. package/utils/createFileNormalizerFromContext.js.map +1 -0
  105. package/utils/getPresignedPostPayload.d.ts +2 -2
  106. package/utils/getPresignedPostPayload.js +11 -12
  107. package/utils/getPresignedPostPayload.js.map +1 -1
  108. package/utils/mimeTypes.js +9 -5
  109. package/utils/mimeTypes.js.map +1 -1
  110. package/utils/uploadFileToS3.d.ts +2 -2
  111. package/utils/uploadFileToS3.js +3 -1
  112. package/utils/uploadFileToS3.js.map +1 -1
  113. package/utils/prepareFileData.d.ts +0 -2
  114. package/utils/prepareFileData.js +0 -62
  115. package/utils/prepareFileData.js.map +0 -1
@@ -0,0 +1,6 @@
1
+ import { createAssetDelivery as createBaseAssetDelivery } from "@webiny/api-file-manager";
2
+ export declare type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {
3
+ imageResizeWidths?: number[];
4
+ presignedUrlTtl?: number;
5
+ };
6
+ export declare const assetDeliveryConfig: (params: AssetDeliveryParams) => (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | import("@webiny/handler").ModifyFastifyPlugin)[])[];
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.assetDeliveryConfig = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ var _clientS = require("@webiny/aws-sdk/client-s3");
9
+ var _S3AssetResolver = require("./s3/S3AssetResolver");
10
+ var _S3OutputStrategy = require("./s3/S3OutputStrategy");
11
+ var _SharpTransform = require("./s3/SharpTransform");
12
+ const assetDeliveryConfig = params => {
13
+ const bucket = process.env.S3_BUCKET;
14
+ const region = process.env.AWS_REGION;
15
+ const {
16
+ presignedUrlTtl = 900,
17
+ imageResizeWidths = [100, 300, 500, 750, 1000, 1500, 2500],
18
+ ...baseParams
19
+ } = params;
20
+ return [
21
+ // Base asset delivery
22
+ (0, _apiFileManager.createAssetDelivery)(baseParams),
23
+ // S3 plugins
24
+ (0, _apiFileManager.createAssetDeliveryConfig)(config => {
25
+ const s3 = new _clientS.S3({
26
+ region
27
+ });
28
+ config.decorateAssetResolver(() => {
29
+ // This resolver loads file information from the `.metadata` file.
30
+ return new _S3AssetResolver.S3AssetResolver(s3, bucket);
31
+ });
32
+ config.decorateAssetOutputStrategy(() => {
33
+ return new _S3OutputStrategy.S3OutputStrategy(s3, bucket, presignedUrlTtl);
34
+ });
35
+ config.decorateAssetTransformationStrategy(() => {
36
+ return new _SharpTransform.SharpTransform({
37
+ s3,
38
+ bucket,
39
+ imageResizeWidths
40
+ });
41
+ });
42
+ })];
43
+ };
44
+ exports.assetDeliveryConfig = assetDeliveryConfig;
45
+
46
+ //# sourceMappingURL=assetDeliveryConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","_clientS","_S3AssetResolver","_S3OutputStrategy","_SharpTransform","assetDeliveryConfig","params","bucket","process","env","S3_BUCKET","region","AWS_REGION","presignedUrlTtl","imageResizeWidths","baseParams","createBaseAssetDelivery","createAssetDeliveryConfig","config","s3","S3","decorateAssetResolver","S3AssetResolver","decorateAssetOutputStrategy","S3OutputStrategy","decorateAssetTransformationStrategy","SharpTransform","exports"],"sources":["assetDeliveryConfig.ts"],"sourcesContent":["import {\n createAssetDelivery as createBaseAssetDelivery,\n createAssetDeliveryConfig\n} from \"@webiny/api-file-manager\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { S3AssetResolver } from \"~/assetDelivery/s3/S3AssetResolver\";\nimport { S3OutputStrategy } from \"~/assetDelivery/s3/S3OutputStrategy\";\nimport { SharpTransform } from \"~/assetDelivery/s3/SharpTransform\";\n\nexport type AssetDeliveryParams = Parameters<typeof createBaseAssetDelivery>[0] & {\n imageResizeWidths?: number[];\n presignedUrlTtl?: number;\n};\n\nexport const assetDeliveryConfig = (params: AssetDeliveryParams) => {\n const bucket = process.env.S3_BUCKET as string;\n const region = process.env.AWS_REGION as string;\n\n const {\n presignedUrlTtl = 900,\n imageResizeWidths = [100, 300, 500, 750, 1000, 1500, 2500],\n ...baseParams\n } = params;\n\n return [\n // Base asset delivery\n createBaseAssetDelivery(baseParams),\n // S3 plugins\n createAssetDeliveryConfig(config => {\n const s3 = new S3({ region });\n\n config.decorateAssetResolver(() => {\n // This resolver loads file information from the `.metadata` file.\n return new S3AssetResolver(s3, bucket);\n });\n\n config.decorateAssetOutputStrategy(() => {\n return new S3OutputStrategy(s3, bucket, presignedUrlTtl);\n });\n\n config.decorateAssetTransformationStrategy(() => {\n return new SharpTransform({ s3, bucket, imageResizeWidths });\n });\n })\n ];\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAIA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AAOO,MAAMK,mBAAmB,GAAIC,MAA2B,IAAK;EAChE,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,SAAmB;EAC9C,MAAMC,MAAM,GAAGH,OAAO,CAACC,GAAG,CAACG,UAAoB;EAE/C,MAAM;IACFC,eAAe,GAAG,GAAG;IACrBC,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC1D,GAAGC;EACP,CAAC,GAAGT,MAAM;EAEV,OAAO;EACH;EACA,IAAAU,mCAAuB,EAACD,UAAU,CAAC;EACnC;EACA,IAAAE,yCAAyB,EAACC,MAAM,IAAI;IAChC,MAAMC,EAAE,GAAG,IAAIC,WAAE,CAAC;MAAET;IAAO,CAAC,CAAC;IAE7BO,MAAM,CAACG,qBAAqB,CAAC,MAAM;MAC/B;MACA,OAAO,IAAIC,gCAAe,CAACH,EAAE,EAAEZ,MAAM,CAAC;IAC1C,CAAC,CAAC;IAEFW,MAAM,CAACK,2BAA2B,CAAC,MAAM;MACrC,OAAO,IAAIC,kCAAgB,CAACL,EAAE,EAAEZ,MAAM,EAAEM,eAAe,CAAC;IAC5D,CAAC,CAAC;IAEFK,MAAM,CAACO,mCAAmC,CAAC,MAAM;MAC7C,OAAO,IAAIC,8BAAc,CAAC;QAAEP,EAAE;QAAEZ,MAAM;QAAEO;MAAkB,CAAC,CAAC;IAChE,CAAC,CAAC;EACN,CAAC,CAAC,CACL;AACL,CAAC;AAACa,OAAA,CAAAtB,mBAAA,GAAAA,mBAAA"}
@@ -0,0 +1,3 @@
1
+ import { PluginFactory } from "@webiny/plugins/types";
2
+ import type { AssetDeliveryParams } from "./assetDeliveryConfig";
3
+ export declare const createAssetDelivery: (params: AssetDeliveryParams) => PluginFactory;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createAssetDelivery = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ const createAssetDelivery = params => {
9
+ /**
10
+ * We only want to load this plugin in the context of the Asset Delivery Lambda function.
11
+ */
12
+ return (0, _apiFileManager.createAssetDeliveryPluginLoader)(() => {
13
+ return import( /* webpackChunkName: "s3AssetDelivery" */"./assetDeliveryConfig").then(({
14
+ assetDeliveryConfig
15
+ }) => assetDeliveryConfig(params));
16
+ });
17
+ };
18
+ exports.createAssetDelivery = createAssetDelivery;
19
+
20
+ //# sourceMappingURL=createAssetDelivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","createAssetDelivery","params","createAssetDeliveryPluginLoader","then","assetDeliveryConfig","exports"],"sources":["createAssetDelivery.ts"],"sourcesContent":["import { createAssetDeliveryPluginLoader } from \"@webiny/api-file-manager\";\nimport { PluginFactory } from \"@webiny/plugins/types\";\nimport type { AssetDeliveryParams } from \"./assetDeliveryConfig\";\n\nexport const createAssetDelivery = (params: AssetDeliveryParams): PluginFactory => {\n /**\n * We only want to load this plugin in the context of the Asset Delivery Lambda function.\n */\n return createAssetDeliveryPluginLoader(() => {\n return import(/* webpackChunkName: \"s3AssetDelivery\" */ \"./assetDeliveryConfig\").then(\n ({ assetDeliveryConfig }) => assetDeliveryConfig(params)\n );\n });\n};\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAIO,MAAMC,mBAAmB,GAAIC,MAA2B,IAAoB;EAC/E;AACJ;AACA;EACI,OAAO,IAAAC,+CAA+B,EAAC,MAAM;IACzC,OAAO,MAAM,EAAC,gEAAiE,CAAC,CAACC,IAAI,CACjF,CAAC;MAAEC;IAAoB,CAAC,KAAKA,mBAAmB,CAACH,MAAM,CAC3D,CAAC;EACL,CAAC,CAAC;AACN,CAAC;AAACI,OAAA,CAAAL,mBAAA,GAAAA,mBAAA"}
@@ -0,0 +1,15 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3";
2
+ interface AssetMetadata {
3
+ id: string;
4
+ tenant: string;
5
+ locale: string;
6
+ size: number;
7
+ contentType: string;
8
+ }
9
+ export declare class S3AssetMetadataReader {
10
+ private readonly s3;
11
+ private readonly bucket;
12
+ constructor(s3: S3, bucket: string);
13
+ getMetadata(key: string): Promise<AssetMetadata>;
14
+ }
15
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3AssetMetadataReader = void 0;
7
+ class S3AssetMetadataReader {
8
+ constructor(s3, bucket) {
9
+ this.bucket = bucket;
10
+ this.s3 = s3;
11
+ }
12
+ async getMetadata(key) {
13
+ const metadataKey = `${key}.metadata`;
14
+ console.log("Reading metadata", metadataKey);
15
+ const {
16
+ Body
17
+ } = await this.s3.getObject({
18
+ Bucket: this.bucket,
19
+ Key: metadataKey
20
+ });
21
+ if (!Body) {
22
+ throw Error(`Missing or corrupted ${metadataKey} file!`);
23
+ }
24
+ const metadata = JSON.parse(await Body.transformToString());
25
+ return {
26
+ id: metadata.id,
27
+ tenant: metadata.tenant,
28
+ locale: metadata.locale,
29
+ size: metadata.size,
30
+ contentType: metadata.contentType
31
+ };
32
+ }
33
+ }
34
+ exports.S3AssetMetadataReader = S3AssetMetadataReader;
35
+
36
+ //# sourceMappingURL=S3AssetMetadataReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["S3AssetMetadataReader","constructor","s3","bucket","getMetadata","key","metadataKey","console","log","Body","getObject","Bucket","Key","Error","metadata","JSON","parse","transformToString","id","tenant","locale","size","contentType","exports"],"sources":["S3AssetMetadataReader.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3\";\n\ninterface AssetMetadata {\n id: string;\n tenant: string;\n locale: string;\n size: number;\n contentType: string;\n}\n\nexport class S3AssetMetadataReader {\n private readonly s3: S3;\n private readonly bucket: string;\n\n constructor(s3: S3, bucket: string) {\n this.bucket = bucket;\n this.s3 = s3;\n }\n\n async getMetadata(key: string): Promise<AssetMetadata> {\n const metadataKey = `${key}.metadata`;\n\n console.log(\"Reading metadata\", metadataKey);\n\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: metadataKey\n });\n\n if (!Body) {\n throw Error(`Missing or corrupted ${metadataKey} file!`);\n }\n\n const metadata = JSON.parse(await Body.transformToString());\n\n return {\n id: metadata.id,\n tenant: metadata.tenant,\n locale: metadata.locale,\n size: metadata.size,\n contentType: metadata.contentType\n };\n }\n}\n"],"mappings":";;;;;;AAUO,MAAMA,qBAAqB,CAAC;EAI/BC,WAAWA,CAACC,EAAM,EAAEC,MAAc,EAAE;IAChC,IAAI,CAACA,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACD,EAAE,GAAGA,EAAE;EAChB;EAEA,MAAME,WAAWA,CAACC,GAAW,EAA0B;IACnD,MAAMC,WAAW,GAAI,GAAED,GAAI,WAAU;IAErCE,OAAO,CAACC,GAAG,CAAC,kBAAkB,EAAEF,WAAW,CAAC;IAE5C,MAAM;MAAEG;IAAK,CAAC,GAAG,MAAM,IAAI,CAACP,EAAE,CAACQ,SAAS,CAAC;MACrCC,MAAM,EAAE,IAAI,CAACR,MAAM;MACnBS,GAAG,EAAEN;IACT,CAAC,CAAC;IAEF,IAAI,CAACG,IAAI,EAAE;MACP,MAAMI,KAAK,CAAE,wBAAuBP,WAAY,QAAO,CAAC;IAC5D;IAEA,MAAMQ,QAAQ,GAAGC,IAAI,CAACC,KAAK,CAAC,MAAMP,IAAI,CAACQ,iBAAiB,CAAC,CAAC,CAAC;IAE3D,OAAO;MACHC,EAAE,EAAEJ,QAAQ,CAACI,EAAE;MACfC,MAAM,EAAEL,QAAQ,CAACK,MAAM;MACvBC,MAAM,EAAEN,QAAQ,CAACM,MAAM;MACvBC,IAAI,EAAEP,QAAQ,CAACO,IAAI;MACnBC,WAAW,EAAER,QAAQ,CAACQ;IAC1B,CAAC;EACL;AACJ;AAACC,OAAA,CAAAvB,qBAAA,GAAAA,qBAAA"}
@@ -0,0 +1,8 @@
1
+ import { S3 } from "@webiny/aws-sdk/client-s3";
2
+ import { Asset, AssetRequest, AssetResolver } from "@webiny/api-file-manager";
3
+ export declare class S3AssetResolver implements AssetResolver {
4
+ private readonly s3;
5
+ private readonly bucket;
6
+ constructor(s3: S3, bucket: string);
7
+ resolve(request: AssetRequest): Promise<Asset | undefined>;
8
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3AssetResolver = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ var _S3AssetMetadataReader = require("./S3AssetMetadataReader");
9
+ var _S3ContentsReader = require("./S3ContentsReader");
10
+ class S3AssetResolver {
11
+ constructor(s3, bucket) {
12
+ this.s3 = s3;
13
+ this.bucket = bucket;
14
+ }
15
+ async resolve(request) {
16
+ try {
17
+ const metadataReader = new _S3AssetMetadataReader.S3AssetMetadataReader(this.s3, this.bucket);
18
+ const metadata = await metadataReader.getMetadata(request.getKey());
19
+ const asset = new _apiFileManager.Asset({
20
+ id: metadata.id,
21
+ tenant: metadata.tenant,
22
+ locale: metadata.locale,
23
+ size: metadata.size,
24
+ contentType: metadata.contentType,
25
+ key: request.getKey()
26
+ });
27
+ asset.setContentsReader(new _S3ContentsReader.S3ContentsReader(this.s3, this.bucket));
28
+ return asset;
29
+ } catch (error) {
30
+ console.error(error);
31
+ return undefined;
32
+ }
33
+ }
34
+ }
35
+ exports.S3AssetResolver = S3AssetResolver;
36
+
37
+ //# sourceMappingURL=S3AssetResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","_S3AssetMetadataReader","_S3ContentsReader","S3AssetResolver","constructor","s3","bucket","resolve","request","metadataReader","S3AssetMetadataReader","metadata","getMetadata","getKey","asset","Asset","id","tenant","locale","size","contentType","key","setContentsReader","S3ContentsReader","error","console","undefined","exports"],"sources":["S3AssetResolver.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { Asset, AssetRequest, AssetResolver } from \"@webiny/api-file-manager\";\nimport { S3AssetMetadataReader } from \"./S3AssetMetadataReader\";\nimport { S3ContentsReader } from \"./S3ContentsReader\";\n\nexport class S3AssetResolver implements AssetResolver {\n private readonly s3: S3;\n private readonly bucket: string;\n\n constructor(s3: S3, bucket: string) {\n this.s3 = s3;\n this.bucket = bucket;\n }\n\n async resolve(request: AssetRequest): Promise<Asset | undefined> {\n try {\n const metadataReader = new S3AssetMetadataReader(this.s3, this.bucket);\n const metadata = await metadataReader.getMetadata(request.getKey());\n\n const asset = new Asset({\n id: metadata.id,\n tenant: metadata.tenant,\n locale: metadata.locale,\n size: metadata.size,\n contentType: metadata.contentType,\n key: request.getKey()\n });\n\n asset.setContentsReader(new S3ContentsReader(this.s3, this.bucket));\n\n return asset;\n } catch (error) {\n console.error(error);\n return undefined;\n }\n }\n}\n"],"mappings":";;;;;;AACA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AACA,IAAAE,iBAAA,GAAAF,OAAA;AAEO,MAAMG,eAAe,CAA0B;EAIlDC,WAAWA,CAACC,EAAM,EAAEC,MAAc,EAAE;IAChC,IAAI,CAACD,EAAE,GAAGA,EAAE;IACZ,IAAI,CAACC,MAAM,GAAGA,MAAM;EACxB;EAEA,MAAMC,OAAOA,CAACC,OAAqB,EAA8B;IAC7D,IAAI;MACA,MAAMC,cAAc,GAAG,IAAIC,4CAAqB,CAAC,IAAI,CAACL,EAAE,EAAE,IAAI,CAACC,MAAM,CAAC;MACtE,MAAMK,QAAQ,GAAG,MAAMF,cAAc,CAACG,WAAW,CAACJ,OAAO,CAACK,MAAM,CAAC,CAAC,CAAC;MAEnE,MAAMC,KAAK,GAAG,IAAIC,qBAAK,CAAC;QACpBC,EAAE,EAAEL,QAAQ,CAACK,EAAE;QACfC,MAAM,EAAEN,QAAQ,CAACM,MAAM;QACvBC,MAAM,EAAEP,QAAQ,CAACO,MAAM;QACvBC,IAAI,EAAER,QAAQ,CAACQ,IAAI;QACnBC,WAAW,EAAET,QAAQ,CAACS,WAAW;QACjCC,GAAG,EAAEb,OAAO,CAACK,MAAM,CAAC;MACxB,CAAC,CAAC;MAEFC,KAAK,CAACQ,iBAAiB,CAAC,IAAIC,kCAAgB,CAAC,IAAI,CAAClB,EAAE,EAAE,IAAI,CAACC,MAAM,CAAC,CAAC;MAEnE,OAAOQ,KAAK;IAChB,CAAC,CAAC,OAAOU,KAAK,EAAE;MACZC,OAAO,CAACD,KAAK,CAACA,KAAK,CAAC;MACpB,OAAOE,SAAS;IACpB;EACJ;AACJ;AAACC,OAAA,CAAAxB,eAAA,GAAAA,eAAA"}
@@ -0,0 +1,9 @@
1
+ /// <reference types="node" />
2
+ import { S3 } from "@webiny/aws-sdk/client-s3";
3
+ import { Asset, AssetContentsReader } from "@webiny/api-file-manager";
4
+ export declare class S3ContentsReader implements AssetContentsReader {
5
+ private s3;
6
+ private readonly bucket;
7
+ constructor(s3: S3, bucket: string);
8
+ read(asset: Asset): Promise<Buffer>;
9
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3ContentsReader = void 0;
7
+ class S3ContentsReader {
8
+ constructor(s3, bucket) {
9
+ this.s3 = s3;
10
+ this.bucket = bucket;
11
+ }
12
+ async read(asset) {
13
+ const {
14
+ Body
15
+ } = await this.s3.getObject({
16
+ Bucket: this.bucket,
17
+ Key: asset.getKey()
18
+ });
19
+ if (!Body) {
20
+ throw Error(`Unable to read ${asset.getKey()}!`);
21
+ }
22
+ return Buffer.from(await Body.transformToByteArray());
23
+ }
24
+ }
25
+ exports.S3ContentsReader = S3ContentsReader;
26
+
27
+ //# sourceMappingURL=S3ContentsReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["S3ContentsReader","constructor","s3","bucket","read","asset","Body","getObject","Bucket","Key","getKey","Error","Buffer","from","transformToByteArray","exports"],"sources":["S3ContentsReader.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { Asset, AssetContentsReader } from \"@webiny/api-file-manager\";\n\nexport class S3ContentsReader implements AssetContentsReader {\n private s3: S3;\n private readonly bucket: string;\n\n constructor(s3: S3, bucket: string) {\n this.s3 = s3;\n this.bucket = bucket;\n }\n\n async read(asset: Asset): Promise<Buffer> {\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: asset.getKey()\n });\n\n if (!Body) {\n throw Error(`Unable to read ${asset.getKey()}!`);\n }\n\n return Buffer.from(await Body.transformToByteArray());\n }\n}\n"],"mappings":";;;;;;AAGO,MAAMA,gBAAgB,CAAgC;EAIzDC,WAAWA,CAACC,EAAM,EAAEC,MAAc,EAAE;IAChC,IAAI,CAACD,EAAE,GAAGA,EAAE;IACZ,IAAI,CAACC,MAAM,GAAGA,MAAM;EACxB;EAEA,MAAMC,IAAIA,CAACC,KAAY,EAAmB;IACtC,MAAM;MAAEC;IAAK,CAAC,GAAG,MAAM,IAAI,CAACJ,EAAE,CAACK,SAAS,CAAC;MACrCC,MAAM,EAAE,IAAI,CAACL,MAAM;MACnBM,GAAG,EAAEJ,KAAK,CAACK,MAAM,CAAC;IACtB,CAAC,CAAC;IAEF,IAAI,CAACJ,IAAI,EAAE;MACP,MAAMK,KAAK,CAAE,kBAAiBN,KAAK,CAACK,MAAM,CAAC,CAAE,GAAE,CAAC;IACpD;IAEA,OAAOE,MAAM,CAACC,IAAI,CAAC,MAAMP,IAAI,CAACQ,oBAAoB,CAAC,CAAC,CAAC;EACzD;AACJ;AAACC,OAAA,CAAAf,gBAAA,GAAAA,gBAAA"}
@@ -0,0 +1,4 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ export declare class S3ErrorAssetReply extends AssetReply {
3
+ constructor(message: string);
4
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3ErrorAssetReply = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ class S3ErrorAssetReply extends _apiFileManager.AssetReply {
9
+ constructor(message) {
10
+ super({
11
+ code: 400,
12
+ body: () => ({
13
+ error: message
14
+ })
15
+ });
16
+ }
17
+ }
18
+ exports.S3ErrorAssetReply = S3ErrorAssetReply;
19
+
20
+ //# sourceMappingURL=S3ErrorAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","S3ErrorAssetReply","AssetReply","constructor","message","code","body","error","exports"],"sources":["S3ErrorAssetReply.ts"],"sourcesContent":["import { AssetReply } from \"@webiny/api-file-manager\";\n\nexport class S3ErrorAssetReply extends AssetReply {\n constructor(message: string) {\n super({\n code: 400,\n body: () => ({ error: message })\n });\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AAEO,MAAMC,iBAAiB,SAASC,0BAAU,CAAC;EAC9CC,WAAWA,CAACC,OAAe,EAAE;IACzB,KAAK,CAAC;MACFC,IAAI,EAAE,GAAG;MACTC,IAAI,EAAEA,CAAA,MAAO;QAAEC,KAAK,EAAEH;MAAQ,CAAC;IACnC,CAAC,CAAC;EACN;AACJ;AAACI,OAAA,CAAAP,iBAAA,GAAAA,iBAAA"}
@@ -0,0 +1,14 @@
1
+ import { Asset, AssetOutputStrategy, AssetReply } from "@webiny/api-file-manager";
2
+ import { S3 } from "@webiny/aws-sdk/client-s3";
3
+ /**
4
+ * This strategy outputs an asset taking into account the size of the asset contents.
5
+ * If the asset is larger than 5MB, a presigned URL will be generated, and a redirect will happen.
6
+ */
7
+ export declare class S3OutputStrategy implements AssetOutputStrategy {
8
+ private readonly s3;
9
+ private readonly bucket;
10
+ private readonly presignedUrlTtl;
11
+ constructor(s3: S3, bucket: string, presignedUrlTtl: number);
12
+ output(asset: Asset): Promise<AssetReply>;
13
+ protected getPresignedUrl(asset: Asset): Promise<string>;
14
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3OutputStrategy = void 0;
7
+ var _clientS = require("@webiny/aws-sdk/client-s3");
8
+ var _S3RedirectAssetReply = require("./S3RedirectAssetReply");
9
+ var _S3StreamAssetReply = require("./S3StreamAssetReply");
10
+ const MAX_RETURN_CONTENT_LENGTH = 4915200; // ~4.8 MB
11
+
12
+ /**
13
+ * This strategy outputs an asset taking into account the size of the asset contents.
14
+ * If the asset is larger than 5MB, a presigned URL will be generated, and a redirect will happen.
15
+ */
16
+ class S3OutputStrategy {
17
+ constructor(s3, bucket, presignedUrlTtl) {
18
+ this.presignedUrlTtl = presignedUrlTtl;
19
+ this.s3 = s3;
20
+ this.bucket = bucket;
21
+ }
22
+ async output(asset) {
23
+ if ((await asset.getSize()) > MAX_RETURN_CONTENT_LENGTH) {
24
+ return new _S3RedirectAssetReply.S3RedirectAssetReply(await this.getPresignedUrl(asset), this.presignedUrlTtl);
25
+ }
26
+ return new _S3StreamAssetReply.S3StreamAssetReply(asset);
27
+ }
28
+ getPresignedUrl(asset) {
29
+ return (0, _clientS.getSignedUrl)(this.s3, new _clientS.GetObjectCommand({
30
+ Bucket: this.bucket,
31
+ Key: asset.getKey()
32
+ }), {
33
+ expiresIn: this.presignedUrlTtl
34
+ });
35
+ }
36
+ }
37
+ exports.S3OutputStrategy = S3OutputStrategy;
38
+
39
+ //# sourceMappingURL=S3OutputStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_clientS","require","_S3RedirectAssetReply","_S3StreamAssetReply","MAX_RETURN_CONTENT_LENGTH","S3OutputStrategy","constructor","s3","bucket","presignedUrlTtl","output","asset","getSize","S3RedirectAssetReply","getPresignedUrl","S3StreamAssetReply","getSignedUrl","GetObjectCommand","Bucket","Key","getKey","expiresIn","exports"],"sources":["S3OutputStrategy.ts"],"sourcesContent":["import { Asset, AssetOutputStrategy, AssetReply } from \"@webiny/api-file-manager\";\nimport { GetObjectCommand, getSignedUrl, S3 } from \"@webiny/aws-sdk/client-s3\";\nimport { S3RedirectAssetReply } from \"~/assetDelivery/s3/S3RedirectAssetReply\";\nimport { S3StreamAssetReply } from \"~/assetDelivery/s3/S3StreamAssetReply\";\n\nconst MAX_RETURN_CONTENT_LENGTH = 4915200; // ~4.8 MB\n\n/**\n * This strategy outputs an asset taking into account the size of the asset contents.\n * If the asset is larger than 5MB, a presigned URL will be generated, and a redirect will happen.\n */\nexport class S3OutputStrategy implements AssetOutputStrategy {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly presignedUrlTtl: number;\n\n constructor(s3: S3, bucket: string, presignedUrlTtl: number) {\n this.presignedUrlTtl = presignedUrlTtl;\n this.s3 = s3;\n this.bucket = bucket;\n }\n\n async output(asset: Asset): Promise<AssetReply> {\n if ((await asset.getSize()) > MAX_RETURN_CONTENT_LENGTH) {\n return new S3RedirectAssetReply(\n await this.getPresignedUrl(asset),\n this.presignedUrlTtl\n );\n }\n\n return new S3StreamAssetReply(asset);\n }\n\n protected getPresignedUrl(asset: Asset) {\n return getSignedUrl(\n this.s3,\n new GetObjectCommand({\n Bucket: this.bucket,\n Key: asset.getKey()\n }),\n { expiresIn: this.presignedUrlTtl }\n );\n }\n}\n"],"mappings":";;;;;;AACA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,qBAAA,GAAAD,OAAA;AACA,IAAAE,mBAAA,GAAAF,OAAA;AAEA,MAAMG,yBAAyB,GAAG,OAAO,CAAC,CAAC;;AAE3C;AACA;AACA;AACA;AACO,MAAMC,gBAAgB,CAAgC;EAKzDC,WAAWA,CAACC,EAAM,EAAEC,MAAc,EAAEC,eAAuB,EAAE;IACzD,IAAI,CAACA,eAAe,GAAGA,eAAe;IACtC,IAAI,CAACF,EAAE,GAAGA,EAAE;IACZ,IAAI,CAACC,MAAM,GAAGA,MAAM;EACxB;EAEA,MAAME,MAAMA,CAACC,KAAY,EAAuB;IAC5C,IAAI,CAAC,MAAMA,KAAK,CAACC,OAAO,CAAC,CAAC,IAAIR,yBAAyB,EAAE;MACrD,OAAO,IAAIS,0CAAoB,CAC3B,MAAM,IAAI,CAACC,eAAe,CAACH,KAAK,CAAC,EACjC,IAAI,CAACF,eACT,CAAC;IACL;IAEA,OAAO,IAAIM,sCAAkB,CAACJ,KAAK,CAAC;EACxC;EAEUG,eAAeA,CAACH,KAAY,EAAE;IACpC,OAAO,IAAAK,qBAAY,EACf,IAAI,CAACT,EAAE,EACP,IAAIU,yBAAgB,CAAC;MACjBC,MAAM,EAAE,IAAI,CAACV,MAAM;MACnBW,GAAG,EAAER,KAAK,CAACS,MAAM,CAAC;IACtB,CAAC,CAAC,EACF;MAAEC,SAAS,EAAE,IAAI,CAACZ;IAAgB,CACtC,CAAC;EACL;AACJ;AAACa,OAAA,CAAAjB,gBAAA,GAAAA,gBAAA"}
@@ -0,0 +1,4 @@
1
+ import { AssetReply } from "@webiny/api-file-manager";
2
+ export declare class S3RedirectAssetReply extends AssetReply {
3
+ constructor(url: string, cacheDuration: number);
4
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3RedirectAssetReply = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ var _handler = require("@webiny/handler");
9
+ class S3RedirectAssetReply extends _apiFileManager.AssetReply {
10
+ constructor(url, cacheDuration) {
11
+ super({
12
+ code: 301,
13
+ headers: _handler.ResponseHeaders.create({
14
+ location: url,
15
+ "cache-control": "public, max-age=" + cacheDuration
16
+ }),
17
+ body: () => ""
18
+ });
19
+ }
20
+ }
21
+ exports.S3RedirectAssetReply = S3RedirectAssetReply;
22
+
23
+ //# sourceMappingURL=S3RedirectAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","_handler","S3RedirectAssetReply","AssetReply","constructor","url","cacheDuration","code","headers","ResponseHeaders","create","location","body","exports"],"sources":["S3RedirectAssetReply.ts"],"sourcesContent":["import { AssetReply } from \"@webiny/api-file-manager\";\nimport { ResponseHeaders } from \"@webiny/handler\";\n\nexport class S3RedirectAssetReply extends AssetReply {\n constructor(url: string, cacheDuration: number) {\n super({\n code: 301,\n headers: ResponseHeaders.create({\n location: url,\n \"cache-control\": \"public, max-age=\" + cacheDuration\n }),\n body: () => \"\"\n });\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEO,MAAME,oBAAoB,SAASC,0BAAU,CAAC;EACjDC,WAAWA,CAACC,GAAW,EAAEC,aAAqB,EAAE;IAC5C,KAAK,CAAC;MACFC,IAAI,EAAE,GAAG;MACTC,OAAO,EAAEC,wBAAe,CAACC,MAAM,CAAC;QAC5BC,QAAQ,EAAEN,GAAG;QACb,eAAe,EAAE,kBAAkB,GAAGC;MAC1C,CAAC,CAAC;MACFM,IAAI,EAAEA,CAAA,KAAM;IAChB,CAAC,CAAC;EACN;AACJ;AAACC,OAAA,CAAAX,oBAAA,GAAAA,oBAAA"}
@@ -0,0 +1,4 @@
1
+ import { Asset, AssetReply } from "@webiny/api-file-manager";
2
+ export declare class S3StreamAssetReply extends AssetReply {
3
+ constructor(asset: Asset);
4
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.S3StreamAssetReply = void 0;
7
+ var _apiFileManager = require("@webiny/api-file-manager");
8
+ var _handler = require("@webiny/handler");
9
+ class S3StreamAssetReply extends _apiFileManager.AssetReply {
10
+ constructor(asset) {
11
+ super({
12
+ code: 200,
13
+ headers: _handler.ResponseHeaders.create({
14
+ "content-type": asset.getContentType()
15
+ }),
16
+ body: () => asset.getContents()
17
+ });
18
+ }
19
+ }
20
+ exports.S3StreamAssetReply = S3StreamAssetReply;
21
+
22
+ //# sourceMappingURL=S3StreamAssetReply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_apiFileManager","require","_handler","S3StreamAssetReply","AssetReply","constructor","asset","code","headers","ResponseHeaders","create","getContentType","body","getContents","exports"],"sources":["S3StreamAssetReply.ts"],"sourcesContent":["import { Asset, AssetReply } from \"@webiny/api-file-manager\";\nimport { ResponseHeaders } from \"@webiny/handler\";\n\nexport class S3StreamAssetReply extends AssetReply {\n constructor(asset: Asset) {\n super({\n code: 200,\n headers: ResponseHeaders.create({\n \"content-type\": asset.getContentType()\n }),\n body: () => asset.getContents()\n });\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEO,MAAME,kBAAkB,SAASC,0BAAU,CAAC;EAC/CC,WAAWA,CAACC,KAAY,EAAE;IACtB,KAAK,CAAC;MACFC,IAAI,EAAE,GAAG;MACTC,OAAO,EAAEC,wBAAe,CAACC,MAAM,CAAC;QAC5B,cAAc,EAAEJ,KAAK,CAACK,cAAc,CAAC;MACzC,CAAC,CAAC;MACFC,IAAI,EAAEA,CAAA,KAAMN,KAAK,CAACO,WAAW,CAAC;IAClC,CAAC,CAAC;EACN;AACJ;AAACC,OAAA,CAAAX,kBAAA,GAAAA,kBAAA"}
@@ -0,0 +1,18 @@
1
+ import { S3 } from "@webiny/aws-sdk/client-s3";
2
+ import { Asset, AssetRequest, AssetTransformationStrategy } from "@webiny/api-file-manager";
3
+ interface SharpTransformationParams {
4
+ s3: S3;
5
+ bucket: string;
6
+ imageResizeWidths: number[];
7
+ }
8
+ export declare class SharpTransform implements AssetTransformationStrategy {
9
+ private readonly params;
10
+ constructor(params: SharpTransformationParams);
11
+ transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset>;
12
+ private transformAsset;
13
+ private optimizeAsset;
14
+ private isAssetAnimated;
15
+ private optimizePng;
16
+ private optimizeJpeg;
17
+ }
18
+ export {};
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.SharpTransform = void 0;
9
+ var _sharp = _interopRequireDefault(require("sharp"));
10
+ var _WidthCollection = require("./transformation/WidthCollection");
11
+ var utils = _interopRequireWildcard(require("./transformation/utils"));
12
+ var _CallableContentsReader = require("./transformation/CallableContentsReader");
13
+ var _AssetKeyGenerator = require("./transformation/AssetKeyGenerator");
14
+ class SharpTransform {
15
+ constructor(params) {
16
+ this.params = params;
17
+ }
18
+ async transform(assetRequest, asset) {
19
+ if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {
20
+ return asset;
21
+ }
22
+
23
+ // `original` is part of the request, but it won't even get to this point in the execution.
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ const {
26
+ original,
27
+ ...options
28
+ } = assetRequest.getOptions();
29
+ const transformedAsset = asset.clone();
30
+ if (Object.keys(options).length > 0) {
31
+ // Transformations were requested.
32
+ return this.transformAsset(transformedAsset, options);
33
+ }
34
+
35
+ // Return an optimized asset.
36
+ return this.optimizeAsset(transformedAsset);
37
+ }
38
+ async transformAsset(asset, options) {
39
+ if (options.width) {
40
+ const {
41
+ s3,
42
+ bucket
43
+ } = this.params;
44
+ const assetKey = new _AssetKeyGenerator.AssetKeyGenerator(asset);
45
+ const transformedAssetKey = assetKey.getTransformedImageKey(options);
46
+ try {
47
+ const {
48
+ Body
49
+ } = await s3.getObject({
50
+ Bucket: bucket,
51
+ Key: transformedAssetKey
52
+ });
53
+ if (!Body) {
54
+ throw new Error(`Missing image body!`);
55
+ }
56
+ const buffer = Buffer.from(await Body.transformToByteArray());
57
+ asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => buffer));
58
+ } catch (e) {
59
+ const optimizedImage = await this.optimizeAsset(asset);
60
+ const widths = new _WidthCollection.WidthCollection(this.params.imageResizeWidths);
61
+ const width = widths.getClosestOrMax(options.width);
62
+
63
+ /**
64
+ * `width` is the only transformation we currently support.
65
+ */
66
+ const buffer = await optimizedImage.getContents();
67
+ const transformedBuffer = (0, _sharp.default)(buffer, {
68
+ animated: this.isAssetAnimated(asset)
69
+ }).resize({
70
+ width
71
+ }).toBuffer();
72
+
73
+ /**
74
+ * Transformations are applied to the optimized image.
75
+ */
76
+ asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => transformedBuffer));
77
+ await s3.putObject({
78
+ Bucket: bucket,
79
+ Key: transformedAssetKey,
80
+ ContentType: asset.getContentType(),
81
+ Body: await asset.getContents()
82
+ });
83
+ }
84
+ }
85
+ return asset;
86
+ }
87
+ async optimizeAsset(asset) {
88
+ const {
89
+ s3,
90
+ bucket
91
+ } = this.params;
92
+ const assetKey = new _AssetKeyGenerator.AssetKeyGenerator(asset);
93
+ const optimizedAssetKey = assetKey.getOptimizedImageKey();
94
+ try {
95
+ const {
96
+ Body
97
+ } = await s3.getObject({
98
+ Bucket: bucket,
99
+ Key: optimizedAssetKey
100
+ });
101
+ if (!Body) {
102
+ throw new Error(`Missing image body!`);
103
+ }
104
+ const buffer = Buffer.from(await Body.transformToByteArray());
105
+ asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => buffer));
106
+ } catch (e) {
107
+ // If not found, create an optimized version of the original asset.
108
+ const buffer = await asset.getContents();
109
+ const optimizationMap = {
110
+ "image/png": buffer => this.optimizePng(buffer),
111
+ "image/jpeg": buffer => this.optimizeJpeg(buffer),
112
+ "image/jpg": buffer => this.optimizeJpeg(buffer)
113
+ };
114
+ const optimization = optimizationMap[asset.getContentType()];
115
+ if (!optimization) {
116
+ console.log(`no optimizations defined for ${asset.getContentType()}`);
117
+ return asset;
118
+ }
119
+ const optimizedBuffer = optimization(buffer).toBuffer();
120
+ asset.setContentsReader(new _CallableContentsReader.CallableContentsReader(() => optimizedBuffer));
121
+ await s3.putObject({
122
+ Bucket: bucket,
123
+ Key: optimizedAssetKey,
124
+ ContentType: asset.getContentType(),
125
+ Body: await asset.getContents()
126
+ });
127
+ }
128
+ return asset;
129
+ }
130
+ isAssetAnimated(asset) {
131
+ return ["gif", "webp"].includes(asset.getExtension());
132
+ }
133
+ optimizePng(buffer) {
134
+ return (0, _sharp.default)(buffer).resize({
135
+ width: 2560,
136
+ withoutEnlargement: true,
137
+ fit: "inside"
138
+ }).png({
139
+ compressionLevel: 9,
140
+ adaptiveFiltering: true,
141
+ force: true
142
+ }).withMetadata();
143
+ }
144
+ optimizeJpeg(buffer) {
145
+ return (0, _sharp.default)(buffer).resize({
146
+ width: 2560,
147
+ withoutEnlargement: true,
148
+ fit: "inside"
149
+ }).toFormat("jpeg", {
150
+ quality: 90
151
+ });
152
+ }
153
+ }
154
+ exports.SharpTransform = SharpTransform;
155
+
156
+ //# sourceMappingURL=SharpTransform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_sharp","_interopRequireDefault","require","_WidthCollection","utils","_interopRequireWildcard","_CallableContentsReader","_AssetKeyGenerator","SharpTransform","constructor","params","transform","assetRequest","asset","SUPPORTED_TRANSFORMABLE_IMAGES","includes","getExtension","original","options","getOptions","transformedAsset","clone","Object","keys","length","transformAsset","optimizeAsset","width","s3","bucket","assetKey","AssetKeyGenerator","transformedAssetKey","getTransformedImageKey","Body","getObject","Bucket","Key","Error","buffer","Buffer","from","transformToByteArray","setContentsReader","CallableContentsReader","e","optimizedImage","widths","WidthCollection","imageResizeWidths","getClosestOrMax","getContents","transformedBuffer","sharp","animated","isAssetAnimated","resize","toBuffer","putObject","ContentType","getContentType","optimizedAssetKey","getOptimizedImageKey","optimizationMap","optimizePng","optimizeJpeg","optimization","console","log","optimizedBuffer","withoutEnlargement","fit","png","compressionLevel","adaptiveFiltering","force","withMetadata","toFormat","quality","exports"],"sources":["SharpTransform.ts"],"sourcesContent":["import sharp from \"sharp\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3\";\nimport {\n Asset,\n AssetRequest,\n AssetRequestOptions,\n AssetTransformationStrategy\n} from \"@webiny/api-file-manager\";\nimport { WidthCollection } from \"./transformation/WidthCollection\";\nimport * as utils from \"./transformation/utils\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator\";\n\ninterface SharpTransformationParams {\n s3: S3;\n bucket: string;\n imageResizeWidths: number[];\n}\n\nexport class SharpTransform implements AssetTransformationStrategy {\n private readonly params: SharpTransformationParams;\n\n constructor(params: SharpTransformationParams) {\n this.params = params;\n }\n\n async transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset> {\n if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {\n return asset;\n }\n\n // `original` is part of the request, but it won't even get to this point in the execution.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { original, ...options } = assetRequest.getOptions();\n\n const transformedAsset = asset.clone();\n\n if (Object.keys(options).length > 0) {\n // Transformations were requested.\n return this.transformAsset(transformedAsset, options);\n }\n\n // Return an optimized asset.\n return this.optimizeAsset(transformedAsset);\n }\n\n private async transformAsset(asset: Asset, options: Omit<AssetRequestOptions, \"original\">) {\n if (options.width) {\n const { s3, bucket } = this.params;\n\n const assetKey = new AssetKeyGenerator(asset);\n const transformedAssetKey = assetKey.getTransformedImageKey(options);\n\n try {\n const { Body } = await s3.getObject({\n Bucket: bucket,\n Key: transformedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n asset.setContentsReader(new CallableContentsReader(() => buffer));\n } catch (e) {\n const optimizedImage = await this.optimizeAsset(asset);\n\n const widths = new WidthCollection(this.params.imageResizeWidths);\n const width = widths.getClosestOrMax(options.width);\n\n /**\n * `width` is the only transformation we currently support.\n */\n const buffer = await optimizedImage.getContents();\n const transformedBuffer = sharp(buffer, { animated: this.isAssetAnimated(asset) })\n .resize({ width })\n .toBuffer();\n\n /**\n * Transformations are applied to the optimized image.\n */\n asset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: transformedAssetKey,\n ContentType: asset.getContentType(),\n Body: await asset.getContents()\n });\n }\n }\n\n return asset;\n }\n\n private async optimizeAsset(asset: Asset) {\n const { s3, bucket } = this.params;\n\n const assetKey = new AssetKeyGenerator(asset);\n const optimizedAssetKey = assetKey.getOptimizedImageKey();\n\n try {\n const { Body } = await s3.getObject({\n Bucket: bucket,\n Key: optimizedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n asset.setContentsReader(new CallableContentsReader(() => buffer));\n } catch (e) {\n // If not found, create an optimized version of the original asset.\n const buffer = await asset.getContents();\n\n const optimizationMap: Record<string, ((buffer: Buffer) => sharp.Sharp) | undefined> = {\n \"image/png\": (buffer: Buffer) => this.optimizePng(buffer),\n \"image/jpeg\": (buffer: Buffer) => this.optimizeJpeg(buffer),\n \"image/jpg\": (buffer: Buffer) => this.optimizeJpeg(buffer)\n };\n\n const optimization = optimizationMap[asset.getContentType()];\n\n if (!optimization) {\n console.log(`no optimizations defined for ${asset.getContentType()}`);\n return asset;\n }\n\n const optimizedBuffer = optimization(buffer).toBuffer();\n\n asset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: optimizedAssetKey,\n ContentType: asset.getContentType(),\n Body: await asset.getContents()\n });\n }\n\n return asset;\n }\n\n private isAssetAnimated(asset: Asset) {\n return [\"gif\", \"webp\"].includes(asset.getExtension());\n }\n\n private optimizePng(buffer: Buffer) {\n return sharp(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .png({ compressionLevel: 9, adaptiveFiltering: true, force: true })\n .withMetadata();\n }\n\n private optimizeJpeg(buffer: Buffer) {\n return sharp(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Asset } from "@webiny/api-file-manager";
2
+ export declare class AssetKeyGenerator {
3
+ private utils;
4
+ private asset;
5
+ constructor(asset: Asset);
6
+ getOptimizedImageKey(): string;
7
+ getTransformedImageKey(transformations: Record<string, any>): string;
8
+ }