@webiny/api-file-manager-s3 6.4.0-beta.1 → 6.4.0-beta.3

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.
@@ -0,0 +1,9 @@
1
+ import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
+ export interface IS3AssetDeliveryConfig {
3
+ presignedUrlTtl: number;
4
+ imageResizeWidths: number[];
5
+ assetStreamingMaxSize: number;
6
+ }
7
+ export declare const S3AssetDeliveryConfig: import("@webiny/di").Abstraction<IS3AssetDeliveryConfig>;
8
+ export declare const S3Client: import("@webiny/di").Abstraction<S3>;
9
+ export declare const S3Bucket: import("@webiny/di").Abstraction<string>;
@@ -0,0 +1,7 @@
1
+ import { createAbstraction } from "@webiny/feature/api";
2
+ const S3AssetDeliveryConfig = createAbstraction("AssetDelivery/S3Config");
3
+ const S3Client = createAbstraction("AssetDelivery/S3Client");
4
+ const S3Bucket = createAbstraction("AssetDelivery/S3Bucket");
5
+ export { S3AssetDeliveryConfig, S3Bucket, S3Client };
6
+
7
+ //# sourceMappingURL=abstractions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/abstractions.js","sources":["../../src/assetDelivery/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\n\nexport interface IS3AssetDeliveryConfig {\n presignedUrlTtl: number;\n imageResizeWidths: number[];\n assetStreamingMaxSize: number;\n}\n\nexport const S3AssetDeliveryConfig =\n createAbstraction<IS3AssetDeliveryConfig>(\"AssetDelivery/S3Config\");\n\nexport const S3Client = createAbstraction<S3>(\"AssetDelivery/S3Client\");\n\nexport const S3Bucket = createAbstraction<string>(\"AssetDelivery/S3Bucket\");\n"],"names":["S3AssetDeliveryConfig","createAbstraction","S3Client","S3Bucket"],"mappings":";AASO,MAAMA,wBACTC,kBAA0C;AAEvC,MAAMC,WAAWD,kBAAsB;AAEvC,MAAME,WAAWF,kBAA0B"}
@@ -1,2 +1,2 @@
1
1
  import type { AssetDeliveryParams } from "../assetDelivery/types.js";
2
- export declare const assetDeliveryConfig: (params: AssetDeliveryParams) => (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | (import("@webiny/api-file-manager").AssetDeliveryConfigModifierPlugin | import("@webiny/handler/index").ModifyFastifyPlugin)[])[];
2
+ export declare const assetDeliveryConfig: (params: AssetDeliveryParams) => (import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types").Context> | (import("@webiny/handler").ModifyFastifyPlugin | import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types").Context>)[])[];
@@ -1,37 +1,12 @@
1
- import { createAssetDelivery, createAssetDeliveryConfig } from "@webiny/api-file-manager";
2
- import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
3
- import { S3AssetResolver } from "./s3/S3AssetResolver.js";
4
- import { S3OutputStrategy } from "./s3/S3OutputStrategy.js";
5
- import { SharpTransform } from "./s3/SharpTransform.js";
6
- import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
1
+ import { createAssetDelivery } from "@webiny/api-file-manager";
2
+ import { createRegisterExtensionPlugin } from "@webiny/handler";
3
+ import { createS3AssetDeliveryFeature } from "./feature.js";
7
4
  const assetDeliveryConfig = (params)=>{
8
- const bucket = process.env.S3_BUCKET;
9
- const region = process.env.AWS_REGION;
10
- const { presignedUrlTtl = 3600, imageResizeWidths = [
11
- 128,
12
- 384,
13
- 640,
14
- 750,
15
- 828,
16
- 1080,
17
- 1200,
18
- 1920,
19
- 2048,
20
- 3840
21
- ], assetStreamingMaxSize = 4718592 } = params;
5
+ const feature = createS3AssetDeliveryFeature(params);
22
6
  return [
23
7
  createAssetDelivery(),
24
- createAssetDeliveryConfig((config)=>{
25
- const s3 = new S3({
26
- region
27
- });
28
- config.decorateAssetResolver(({ container })=>new S3AssetResolver(container.resolve(GlobalKeyValueStore), s3, bucket));
29
- config.decorateAssetOutputStrategy(()=>new S3OutputStrategy(s3, bucket, presignedUrlTtl, assetStreamingMaxSize));
30
- config.decorateAssetTransformationStrategy(()=>new SharpTransform({
31
- s3,
32
- bucket,
33
- imageResizeWidths
34
- }));
8
+ createRegisterExtensionPlugin((context)=>{
9
+ feature.register(context.container);
35
10
  })
36
11
  ];
37
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"assetDelivery/assetDeliveryConfig.js","sources":["../../src/assetDelivery/assetDeliveryConfig.ts"],"sourcesContent":["import {\n createAssetDelivery as createBaseAssetDelivery,\n createAssetDeliveryConfig\n} from \"@webiny/api-file-manager\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3AssetResolver } from \"~/assetDelivery/s3/S3AssetResolver.js\";\nimport { S3OutputStrategy } from \"~/assetDelivery/s3/S3OutputStrategy.js\";\nimport { SharpTransform } from \"~/assetDelivery/s3/SharpTransform.js\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\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 // Presigned URLs last 1 hour\n presignedUrlTtl = 3600,\n imageResizeWidths = [128, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840],\n /**\n * Even though Lambda's response payload limit is 6,291,556 bytes, we leave some room for the response envelope.\n * We had situations where a 4.7MB file would cause the payload to go over the limit, so let's be on the safe side.\n */\n assetStreamingMaxSize = 4718592\n } = params;\n\n return [\n // Base asset delivery\n createBaseAssetDelivery(),\n // S3 plugins\n createAssetDeliveryConfig(config => {\n const s3 = new S3({ region });\n\n config.decorateAssetResolver(({ container }) => {\n // This resolver loads file information from the `.metadata` file.\n return new S3AssetResolver(container.resolve(GlobalKeyValueStore), s3, bucket);\n });\n\n config.decorateAssetOutputStrategy(() => {\n return new S3OutputStrategy(s3, bucket, presignedUrlTtl, assetStreamingMaxSize);\n });\n\n config.decorateAssetTransformationStrategy(() => {\n return new SharpTransform({ s3, bucket, imageResizeWidths });\n });\n })\n ];\n};\n"],"names":["assetDeliveryConfig","params","bucket","process","region","presignedUrlTtl","imageResizeWidths","assetStreamingMaxSize","createBaseAssetDelivery","createAssetDeliveryConfig","config","s3","S3","container","S3AssetResolver","GlobalKeyValueStore","S3OutputStrategy","SharpTransform"],"mappings":";;;;;;AAWO,MAAMA,sBAAsB,CAACC;IAChC,MAAMC,SAASC,QAAQ,GAAG,CAAC,SAAS;IACpC,MAAMC,SAASD,QAAQ,GAAG,CAAC,UAAU;IAErC,MAAM,EAEFE,kBAAkB,IAAI,EACtBC,oBAAoB;QAAC;QAAK;QAAK;QAAK;QAAK;QAAK;QAAM;QAAM;QAAM;QAAM;KAAK,EAK3EC,wBAAwB,OAAO,EAClC,GAAGN;IAEJ,OAAO;QAEHO;QAEAC,0BAA0BC,CAAAA;YACtB,MAAMC,KAAK,IAAIC,GAAG;gBAAER;YAAO;YAE3BM,OAAO,qBAAqB,CAAC,CAAC,EAAEG,SAAS,EAAE,GAEhC,IAAIC,gBAAgBD,UAAU,OAAO,CAACE,sBAAsBJ,IAAIT;YAG3EQ,OAAO,2BAA2B,CAAC,IACxB,IAAIM,iBAAiBL,IAAIT,QAAQG,iBAAiBE;YAG7DG,OAAO,mCAAmC,CAAC,IAChC,IAAIO,eAAe;oBAAEN;oBAAIT;oBAAQI;gBAAkB;QAElE;KACH;AACL"}
1
+ {"version":3,"file":"assetDelivery/assetDeliveryConfig.js","sources":["../../src/assetDelivery/assetDeliveryConfig.ts"],"sourcesContent":["import { createAssetDelivery as createBaseAssetDelivery } from \"@webiny/api-file-manager\";\nimport { createRegisterExtensionPlugin } from \"@webiny/handler\";\nimport type { AssetDeliveryParams } from \"~/assetDelivery/types.js\";\nimport { createS3AssetDeliveryFeature } from \"~/assetDelivery/feature.js\";\n\nexport const assetDeliveryConfig = (params: AssetDeliveryParams) => {\n const feature = createS3AssetDeliveryFeature(params);\n\n return [\n createBaseAssetDelivery(),\n createRegisterExtensionPlugin(context => {\n feature.register(context.container);\n })\n ];\n};\n"],"names":["assetDeliveryConfig","params","feature","createS3AssetDeliveryFeature","createBaseAssetDelivery","createRegisterExtensionPlugin","context"],"mappings":";;;AAKO,MAAMA,sBAAsB,CAACC;IAChC,MAAMC,UAAUC,6BAA6BF;IAE7C,OAAO;QACHG;QACAC,8BAA8BC,CAAAA;YAC1BJ,QAAQ,QAAQ,CAACI,QAAQ,SAAS;QACtC;KACH;AACL"}
@@ -0,0 +1,5 @@
1
+ import type { AssetDeliveryParams } from "./types.js";
2
+ export declare const createS3AssetDeliveryFeature: (params?: AssetDeliveryParams) => {
3
+ name: string;
4
+ register(container: import("@webiny/di").Container): void;
5
+ };
@@ -0,0 +1,37 @@
1
+ import { createFeature } from "@webiny/feature/api";
2
+ import { S3 } from "@webiny/aws-sdk/client-s3/index.js";
3
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "./abstractions.js";
4
+ import { S3AssetResolverImpl } from "./s3/S3AssetResolver.js";
5
+ import { S3OutputStrategyImpl } from "./s3/S3OutputStrategy.js";
6
+ import { SharpTransformImpl } from "./s3/SharpTransform.js";
7
+ const createS3AssetDeliveryFeature = (params = {})=>createFeature({
8
+ name: "AssetDelivery/S3",
9
+ register (container) {
10
+ container.registerInstance(S3Client, new S3({
11
+ region: process.env.AWS_REGION
12
+ }));
13
+ container.registerInstance(S3Bucket, process.env.S3_BUCKET);
14
+ container.registerInstance(S3AssetDeliveryConfig, {
15
+ presignedUrlTtl: params.presignedUrlTtl ?? 3600,
16
+ imageResizeWidths: params.imageResizeWidths ?? [
17
+ 128,
18
+ 384,
19
+ 640,
20
+ 750,
21
+ 828,
22
+ 1080,
23
+ 1200,
24
+ 1920,
25
+ 2048,
26
+ 3840
27
+ ],
28
+ assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592
29
+ });
30
+ container.register(S3AssetResolverImpl);
31
+ container.register(S3OutputStrategyImpl);
32
+ container.register(SharpTransformImpl);
33
+ }
34
+ });
35
+ export { createS3AssetDeliveryFeature };
36
+
37
+ //# sourceMappingURL=feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetDelivery/feature.js","sources":["../../src/assetDelivery/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"./abstractions.js\";\nimport type { AssetDeliveryParams } from \"./types.js\";\nimport { S3AssetResolverImpl } from \"./s3/S3AssetResolver.js\";\nimport { S3OutputStrategyImpl } from \"./s3/S3OutputStrategy.js\";\nimport { SharpTransformImpl } from \"./s3/SharpTransform.js\";\n\nexport const createS3AssetDeliveryFeature = (params: AssetDeliveryParams = {}) => {\n return createFeature({\n name: \"AssetDelivery/S3\",\n register(container) {\n container.registerInstance(\n S3Client,\n new S3({ region: process.env.AWS_REGION as string })\n );\n container.registerInstance(S3Bucket, process.env.S3_BUCKET as string);\n container.registerInstance(S3AssetDeliveryConfig, {\n presignedUrlTtl: params.presignedUrlTtl ?? 3600,\n imageResizeWidths: params.imageResizeWidths ?? [\n 128, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840\n ],\n assetStreamingMaxSize: params.assetStreamingMaxSize ?? 4718592\n });\n\n container.register(S3AssetResolverImpl);\n container.register(S3OutputStrategyImpl);\n container.register(SharpTransformImpl);\n }\n });\n};\n"],"names":["createS3AssetDeliveryFeature","params","createFeature","container","S3Client","S3","process","S3Bucket","S3AssetDeliveryConfig","S3AssetResolverImpl","S3OutputStrategyImpl","SharpTransformImpl"],"mappings":";;;;;;AAQO,MAAMA,+BAA+B,CAACC,SAA8B,CAAC,CAAC,GAClEC,cAAc;QACjB,MAAM;QACN,UAASC,SAAS;YACdA,UAAU,gBAAgB,CACtBC,UACA,IAAIC,GAAG;gBAAE,QAAQC,QAAQ,GAAG,CAAC,UAAU;YAAW;YAEtDH,UAAU,gBAAgB,CAACI,UAAUD,QAAQ,GAAG,CAAC,SAAS;YAC1DH,UAAU,gBAAgB,CAACK,uBAAuB;gBAC9C,iBAAiBP,OAAO,eAAe,IAAI;gBAC3C,mBAAmBA,OAAO,iBAAiB,IAAI;oBAC3C;oBAAK;oBAAK;oBAAK;oBAAK;oBAAK;oBAAM;oBAAM;oBAAM;oBAAM;iBACpD;gBACD,uBAAuBA,OAAO,qBAAqB,IAAI;YAC3D;YAEAE,UAAU,QAAQ,CAACM;YACnBN,UAAU,QAAQ,CAACO;YACnBP,UAAU,QAAQ,CAACQ;QACvB;IACJ"}
@@ -9,3 +9,6 @@ export declare class S3AssetResolver implements AssetResolver {
9
9
  constructor(keyValueStore: GlobalKeyValueStore.Interface, s3: S3, bucket: string);
10
10
  resolve(request: AssetRequest): Promise<Asset | undefined>;
11
11
  }
12
+ export declare const S3AssetResolverImpl: typeof S3AssetResolver & {
13
+ __abstraction: import("@webiny/di").Abstraction<AssetResolver>;
14
+ };
@@ -1,6 +1,9 @@
1
1
  import { Asset } from "@webiny/api-file-manager";
2
+ import { AssetResolver } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
3
+ import { GlobalKeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
2
4
  import { S3ContentsReader } from "../index.js";
3
5
  import { ObjectKey } from "../threatDetection/ObjectKey.js";
6
+ import { S3Bucket, S3Client } from "../abstractions.js";
4
7
  class S3AssetResolver {
5
8
  constructor(keyValueStore, s3, bucket){
6
9
  this.keyValueStore = keyValueStore;
@@ -23,6 +26,14 @@ class S3AssetResolver {
23
26
  return asset;
24
27
  }
25
28
  }
26
- export { S3AssetResolver };
29
+ const S3AssetResolverImpl = AssetResolver.createImplementation({
30
+ implementation: S3AssetResolver,
31
+ dependencies: [
32
+ GlobalKeyValueStore,
33
+ S3Client,
34
+ S3Bucket
35
+ ]
36
+ });
37
+ export { S3AssetResolver, S3AssetResolverImpl };
27
38
 
28
39
  //# sourceMappingURL=S3AssetResolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assetDelivery/s3/S3AssetResolver.js","sources":["../../../src/assetDelivery/s3/S3AssetResolver.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type { AssetRequest, AssetResolver } from \"@webiny/api-file-manager\";\nimport { Asset } from \"@webiny/api-file-manager\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { S3ContentsReader } from \"~/assetDelivery/index.js\";\nimport { ObjectKey } from \"~/assetDelivery/threatDetection/ObjectKey.js\";\n\ninterface AssetMetadata {\n id: string;\n tenant: string;\n size: number;\n contentType: string;\n bucketKey: string;\n}\n\nexport class S3AssetResolver implements AssetResolver {\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private s3: S3,\n private bucket: string\n ) {}\n\n async resolve(request: AssetRequest): Promise<Asset | undefined> {\n const fileId = ObjectKey.from(request.getKey()).id();\n const result = await this.keyValueStore.get<AssetMetadata>(\n `FileManager/File/${fileId}/Metadata`\n );\n\n if (result.isFail()) {\n return undefined;\n }\n\n const metadata = result.value;\n\n const asset = new Asset({\n id: metadata.id,\n tenant: metadata.tenant,\n size: metadata.size,\n contentType: metadata.contentType,\n key: metadata.bucketKey\n });\n\n asset.setContentsReader(new S3ContentsReader(this.s3, this.bucket));\n\n return asset;\n }\n}\n"],"names":["S3AssetResolver","keyValueStore","s3","bucket","request","fileId","ObjectKey","result","metadata","asset","Asset","S3ContentsReader"],"mappings":";;;AAeO,MAAMA;IACT,YACYC,aAA4C,EAC5CC,EAAM,EACNC,MAAc,CACxB;aAHUF,aAAa,GAAbA;aACAC,EAAE,GAAFA;aACAC,MAAM,GAANA;IACT;IAEH,MAAM,QAAQC,OAAqB,EAA8B;QAC7D,MAAMC,SAASC,UAAU,IAAI,CAACF,QAAQ,MAAM,IAAI,EAAE;QAClD,MAAMG,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CACvC,CAAC,iBAAiB,EAAEF,OAAO,SAAS,CAAC;QAGzC,IAAIE,OAAO,MAAM,IACb;QAGJ,MAAMC,WAAWD,OAAO,KAAK;QAE7B,MAAME,QAAQ,IAAIC,MAAM;YACpB,IAAIF,SAAS,EAAE;YACf,QAAQA,SAAS,MAAM;YACvB,MAAMA,SAAS,IAAI;YACnB,aAAaA,SAAS,WAAW;YACjC,KAAKA,SAAS,SAAS;QAC3B;QAEAC,MAAM,iBAAiB,CAAC,IAAIE,iBAAiB,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM;QAEjE,OAAOF;IACX;AACJ"}
1
+ {"version":3,"file":"assetDelivery/s3/S3AssetResolver.js","sources":["../../../src/assetDelivery/s3/S3AssetResolver.ts"],"sourcesContent":["import type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type { AssetRequest, AssetResolver } from \"@webiny/api-file-manager\";\nimport { Asset } from \"@webiny/api-file-manager\";\nimport { AssetResolver as AssetResolverAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { S3ContentsReader } from \"~/assetDelivery/index.js\";\nimport { ObjectKey } from \"~/assetDelivery/threatDetection/ObjectKey.js\";\nimport { S3Client, S3Bucket } from \"~/assetDelivery/abstractions.js\";\n\ninterface AssetMetadata {\n id: string;\n tenant: string;\n size: number;\n contentType: string;\n bucketKey: string;\n}\n\nexport class S3AssetResolver implements AssetResolver {\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private s3: S3,\n private bucket: string\n ) {}\n\n async resolve(request: AssetRequest): Promise<Asset | undefined> {\n const fileId = ObjectKey.from(request.getKey()).id();\n const result = await this.keyValueStore.get<AssetMetadata>(\n `FileManager/File/${fileId}/Metadata`\n );\n\n if (result.isFail()) {\n return undefined;\n }\n\n const metadata = result.value;\n\n const asset = new Asset({\n id: metadata.id,\n tenant: metadata.tenant,\n size: metadata.size,\n contentType: metadata.contentType,\n key: metadata.bucketKey\n });\n\n asset.setContentsReader(new S3ContentsReader(this.s3, this.bucket));\n\n return asset;\n }\n}\n\nexport const S3AssetResolverImpl = AssetResolverAbstraction.createImplementation({\n implementation: S3AssetResolver,\n dependencies: [GlobalKeyValueStore, S3Client, S3Bucket]\n});\n"],"names":["S3AssetResolver","keyValueStore","s3","bucket","request","fileId","ObjectKey","result","metadata","asset","Asset","S3ContentsReader","S3AssetResolverImpl","AssetResolverAbstraction","GlobalKeyValueStore","S3Client","S3Bucket"],"mappings":";;;;;;AAiBO,MAAMA;IACT,YACYC,aAA4C,EAC5CC,EAAM,EACNC,MAAc,CACxB;aAHUF,aAAa,GAAbA;aACAC,EAAE,GAAFA;aACAC,MAAM,GAANA;IACT;IAEH,MAAM,QAAQC,OAAqB,EAA8B;QAC7D,MAAMC,SAASC,UAAU,IAAI,CAACF,QAAQ,MAAM,IAAI,EAAE;QAClD,MAAMG,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CACvC,CAAC,iBAAiB,EAAEF,OAAO,SAAS,CAAC;QAGzC,IAAIE,OAAO,MAAM,IACb;QAGJ,MAAMC,WAAWD,OAAO,KAAK;QAE7B,MAAME,QAAQ,IAAIC,MAAM;YACpB,IAAIF,SAAS,EAAE;YACf,QAAQA,SAAS,MAAM;YACvB,MAAMA,SAAS,IAAI;YACnB,aAAaA,SAAS,WAAW;YACjC,KAAKA,SAAS,SAAS;QAC3B;QAEAC,MAAM,iBAAiB,CAAC,IAAIE,iBAAiB,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM;QAEjE,OAAOF;IACX;AACJ;AAEO,MAAMG,sBAAsBC,cAAAA,oBAA6C,CAAC;IAC7E,gBAAgBb;IAChB,cAAc;QAACc;QAAqBC;QAAUC;KAAS;AAC3D"}
@@ -1,15 +1,15 @@
1
1
  import type { Asset, AssetOutputStrategy, AssetReply } from "@webiny/api-file-manager";
2
2
  import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
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
- */
3
+ import type { IS3AssetDeliveryConfig } from "../../assetDelivery/abstractions.js";
7
4
  export declare class S3OutputStrategy implements AssetOutputStrategy {
8
5
  private readonly s3;
9
6
  private readonly bucket;
10
7
  private readonly presignedUrlTtl;
11
8
  private readonly assetStreamingMaxSize;
12
- constructor(s3: S3, bucket: string, presignedUrlTtl: number, assetStreamingMaxSize: number);
9
+ constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig);
13
10
  output(asset: Asset): Promise<AssetReply>;
14
11
  protected getPresignedUrl(asset: Asset): Promise<string>;
15
12
  }
13
+ export declare const S3OutputStrategyImpl: typeof S3OutputStrategy & {
14
+ __abstraction: import("@webiny/di").Abstraction<AssetOutputStrategy>;
15
+ };
@@ -1,12 +1,14 @@
1
+ import { AssetOutputStrategy } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
1
2
  import { GetObjectCommand, getSignedUrl } from "@webiny/aws-sdk/client-s3/index.js";
2
3
  import { S3RedirectAssetReply } from "./S3RedirectAssetReply.js";
3
4
  import { S3StreamAssetReply } from "./S3StreamAssetReply.js";
5
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "../abstractions.js";
4
6
  class S3OutputStrategy {
5
- constructor(s3, bucket, presignedUrlTtl, assetStreamingMaxSize){
6
- this.assetStreamingMaxSize = assetStreamingMaxSize;
7
- this.presignedUrlTtl = presignedUrlTtl;
7
+ constructor(s3, bucket, config){
8
8
  this.s3 = s3;
9
9
  this.bucket = bucket;
10
+ this.presignedUrlTtl = config.presignedUrlTtl;
11
+ this.assetStreamingMaxSize = config.assetStreamingMaxSize;
10
12
  }
11
13
  async output(asset) {
12
14
  if (asset.getSize() > this.assetStreamingMaxSize) {
@@ -25,6 +27,14 @@ class S3OutputStrategy {
25
27
  });
26
28
  }
27
29
  }
28
- export { S3OutputStrategy };
30
+ const S3OutputStrategyImpl = AssetOutputStrategy.createImplementation({
31
+ implementation: S3OutputStrategy,
32
+ dependencies: [
33
+ S3Client,
34
+ S3Bucket,
35
+ S3AssetDeliveryConfig
36
+ ]
37
+ });
38
+ export { S3OutputStrategy, S3OutputStrategyImpl };
29
39
 
30
40
  //# sourceMappingURL=S3OutputStrategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assetDelivery/s3/S3OutputStrategy.js","sources":["../../../src/assetDelivery/s3/S3OutputStrategy.ts"],"sourcesContent":["import type { Asset, AssetOutputStrategy, AssetReply } from \"@webiny/api-file-manager\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { GetObjectCommand, getSignedUrl } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3RedirectAssetReply } from \"~/assetDelivery/s3/S3RedirectAssetReply.js\";\nimport { S3StreamAssetReply } from \"~/assetDelivery/s3/S3StreamAssetReply.js\";\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 private readonly assetStreamingMaxSize: number;\n\n constructor(s3: S3, bucket: string, presignedUrlTtl: number, assetStreamingMaxSize: number) {\n this.assetStreamingMaxSize = assetStreamingMaxSize;\n this.presignedUrlTtl = presignedUrlTtl;\n this.s3 = s3;\n this.bucket = bucket;\n }\n\n async output(asset: Asset): Promise<AssetReply> {\n if (asset.getSize() > this.assetStreamingMaxSize) {\n console.log(\n `Asset size is greater than ${this.assetStreamingMaxSize}; redirecting to a presigned S3 URL.`\n );\n\n return new S3RedirectAssetReply(\n await this.getPresignedUrl(asset),\n this.presignedUrlTtl\n );\n }\n\n console.log(\n `Asset size is smaller than ${this.assetStreamingMaxSize}; streaming directly from Lambda function.`\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"],"names":["S3OutputStrategy","s3","bucket","presignedUrlTtl","assetStreamingMaxSize","asset","console","S3RedirectAssetReply","S3StreamAssetReply","getSignedUrl","GetObjectCommand"],"mappings":";;;AAUO,MAAMA;IAMT,YAAYC,EAAM,EAAEC,MAAc,EAAEC,eAAuB,EAAEC,qBAA6B,CAAE;QACxF,IAAI,CAAC,qBAAqB,GAAGA;QAC7B,IAAI,CAAC,eAAe,GAAGD;QACvB,IAAI,CAAC,EAAE,GAAGF;QACV,IAAI,CAAC,MAAM,GAAGC;IAClB;IAEA,MAAM,OAAOG,KAAY,EAAuB;QAC5C,IAAIA,MAAM,OAAO,KAAK,IAAI,CAAC,qBAAqB,EAAE;YAC9CC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,oCAAoC,CAAC;YAGlG,OAAO,IAAIC,qBACP,MAAM,IAAI,CAAC,eAAe,CAACF,QAC3B,IAAI,CAAC,eAAe;QAE5B;QAEAC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,0CAA0C,CAAC;QAExG,OAAO,IAAIE,mBAAmBH;IAClC;IAEU,gBAAgBA,KAAY,EAAE;QACpC,OAAOI,aACH,IAAI,CAAC,EAAE,EACP,IAAIC,iBAAiB;YACjB,QAAQ,IAAI,CAAC,MAAM;YACnB,KAAKL,MAAM,MAAM;QACrB,IACA;YAAE,WAAW,IAAI,CAAC,eAAe;QAAC;IAE1C;AACJ"}
1
+ {"version":3,"file":"assetDelivery/s3/S3OutputStrategy.js","sources":["../../../src/assetDelivery/s3/S3OutputStrategy.ts"],"sourcesContent":["import type { Asset, AssetOutputStrategy, AssetReply } from \"@webiny/api-file-manager\";\nimport { AssetOutputStrategy as AssetOutputStrategyAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { GetObjectCommand, getSignedUrl } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { S3RedirectAssetReply } from \"~/assetDelivery/s3/S3RedirectAssetReply.js\";\nimport { S3StreamAssetReply } from \"~/assetDelivery/s3/S3StreamAssetReply.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\nimport type { IS3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\n\nexport class S3OutputStrategy implements AssetOutputStrategy {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly presignedUrlTtl: number;\n private readonly assetStreamingMaxSize: number;\n\n constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig) {\n this.s3 = s3;\n this.bucket = bucket;\n this.presignedUrlTtl = config.presignedUrlTtl;\n this.assetStreamingMaxSize = config.assetStreamingMaxSize;\n }\n\n async output(asset: Asset): Promise<AssetReply> {\n if (asset.getSize() > this.assetStreamingMaxSize) {\n console.log(\n `Asset size is greater than ${this.assetStreamingMaxSize}; redirecting to a presigned S3 URL.`\n );\n\n return new S3RedirectAssetReply(\n await this.getPresignedUrl(asset),\n this.presignedUrlTtl\n );\n }\n\n console.log(\n `Asset size is smaller than ${this.assetStreamingMaxSize}; streaming directly from Lambda function.`\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\nexport const S3OutputStrategyImpl = AssetOutputStrategyAbstraction.createImplementation({\n implementation: S3OutputStrategy,\n dependencies: [S3Client, S3Bucket, S3AssetDeliveryConfig]\n});\n"],"names":["S3OutputStrategy","s3","bucket","config","asset","console","S3RedirectAssetReply","S3StreamAssetReply","getSignedUrl","GetObjectCommand","S3OutputStrategyImpl","AssetOutputStrategyAbstraction","S3Client","S3Bucket","S3AssetDeliveryConfig"],"mappings":";;;;;AASO,MAAMA;IAMT,YAAYC,EAAM,EAAEC,MAAc,EAAEC,MAA8B,CAAE;QAChE,IAAI,CAAC,EAAE,GAAGF;QACV,IAAI,CAAC,MAAM,GAAGC;QACd,IAAI,CAAC,eAAe,GAAGC,OAAO,eAAe;QAC7C,IAAI,CAAC,qBAAqB,GAAGA,OAAO,qBAAqB;IAC7D;IAEA,MAAM,OAAOC,KAAY,EAAuB;QAC5C,IAAIA,MAAM,OAAO,KAAK,IAAI,CAAC,qBAAqB,EAAE;YAC9CC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,oCAAoC,CAAC;YAGlG,OAAO,IAAIC,qBACP,MAAM,IAAI,CAAC,eAAe,CAACF,QAC3B,IAAI,CAAC,eAAe;QAE5B;QAEAC,QAAQ,GAAG,CACP,CAAC,2BAA2B,EAAE,IAAI,CAAC,qBAAqB,CAAC,0CAA0C,CAAC;QAExG,OAAO,IAAIE,mBAAmBH;IAClC;IAEU,gBAAgBA,KAAY,EAAE;QACpC,OAAOI,aACH,IAAI,CAAC,EAAE,EACP,IAAIC,iBAAiB;YACjB,QAAQ,IAAI,CAAC,MAAM;YACnB,KAAKL,MAAM,MAAM;QACrB,IACA;YAAE,WAAW,IAAI,CAAC,eAAe;QAAC;IAE1C;AACJ;AAEO,MAAMM,uBAAuBC,oBAAAA,oBAAmD,CAAC;IACpF,gBAAgBX;IAChB,cAAc;QAACY;QAAUC;QAAUC;KAAsB;AAC7D"}
@@ -1,13 +1,11 @@
1
1
  import type { S3 } from "@webiny/aws-sdk/client-s3/index.js";
2
2
  import type { Asset, AssetRequest, AssetTransformationStrategy } from "@webiny/api-file-manager";
3
- interface SharpTransformationParams {
4
- s3: S3;
5
- bucket: string;
6
- imageResizeWidths: number[];
7
- }
3
+ import type { IS3AssetDeliveryConfig } from "../../assetDelivery/abstractions.js";
8
4
  export declare class SharpTransform implements AssetTransformationStrategy {
9
- private readonly params;
10
- constructor(params: SharpTransformationParams);
5
+ private readonly s3;
6
+ private readonly bucket;
7
+ private readonly imageResizeWidths;
8
+ constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig);
11
9
  transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset>;
12
10
  private transformAsset;
13
11
  private optimizeAsset;
@@ -15,4 +13,6 @@ export declare class SharpTransform implements AssetTransformationStrategy {
15
13
  private optimizePng;
16
14
  private optimizeJpeg;
17
15
  }
18
- export {};
16
+ export declare const SharpTransformImpl: typeof SharpTransform & {
17
+ __abstraction: import("@webiny/di").Abstraction<AssetTransformationStrategy>;
18
+ };
@@ -1,11 +1,15 @@
1
1
  import sharp from "sharp";
2
+ import { AssetTransformationStrategy } from "@webiny/api-file-manager/features/assetDelivery/abstractions.js";
2
3
  import { WidthCollection } from "./transformation/WidthCollection.js";
3
4
  import { CallableContentsReader } from "./transformation/CallableContentsReader.js";
4
5
  import { AssetKeyGenerator } from "./transformation/AssetKeyGenerator.js";
6
+ import { S3AssetDeliveryConfig, S3Bucket, S3Client } from "../abstractions.js";
5
7
  import * as __rspack_external__transformation_utils_js_d3dc8821 from "./transformation/utils.js";
6
8
  class SharpTransform {
7
- constructor(params){
8
- this.params = params;
9
+ constructor(s3, bucket, config){
10
+ this.s3 = s3;
11
+ this.bucket = bucket;
12
+ this.imageResizeWidths = config.imageResizeWidths;
9
13
  }
10
14
  async transform(assetRequest, asset) {
11
15
  if (!__rspack_external__transformation_utils_js_d3dc8821.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {
@@ -19,12 +23,11 @@ class SharpTransform {
19
23
  }
20
24
  async transformAsset(asset, options) {
21
25
  if (options.width) {
22
- const { s3, bucket } = this.params;
23
26
  const assetKey = new AssetKeyGenerator(asset);
24
27
  const transformedAssetKey = assetKey.getTransformedImageKey(options);
25
28
  try {
26
- const { Body } = await s3.getObject({
27
- Bucket: bucket,
29
+ const { Body } = await this.s3.getObject({
30
+ Bucket: this.bucket,
28
31
  Key: transformedAssetKey
29
32
  });
30
33
  if (!Body) throw new Error("Missing image body!");
@@ -40,7 +43,7 @@ class SharpTransform {
40
43
  return newAsset;
41
44
  } catch {
42
45
  const optimizedImage = await this.optimizeAsset(asset);
43
- const widths = new WidthCollection(this.params.imageResizeWidths);
46
+ const widths = new WidthCollection(this.imageResizeWidths);
44
47
  const width = widths.getClosestOrMax(options.width);
45
48
  console.log(`Resize the asset (width: ${width})`);
46
49
  const buffer = await optimizedImage.getContents();
@@ -54,8 +57,8 @@ class SharpTransform {
54
57
  size: transformedBuffer.length
55
58
  });
56
59
  newAsset.setContentsReader(new CallableContentsReader(()=>transformedBuffer));
57
- await s3.putObject({
58
- Bucket: bucket,
60
+ await this.s3.putObject({
61
+ Bucket: this.bucket,
59
62
  Key: transformedAssetKey,
60
63
  ContentType: newAsset.getContentType(),
61
64
  Body: await newAsset.getContents()
@@ -70,7 +73,6 @@ class SharpTransform {
70
73
  return asset;
71
74
  }
72
75
  async optimizeAsset(asset) {
73
- const { s3, bucket } = this.params;
74
76
  console.log("Optimize asset", {
75
77
  id: asset.getId(),
76
78
  key: asset.getKey(),
@@ -80,8 +82,8 @@ class SharpTransform {
80
82
  const assetKey = new AssetKeyGenerator(asset);
81
83
  const optimizedAssetKey = assetKey.getOptimizedImageKey();
82
84
  try {
83
- const { Body } = await s3.getObject({
84
- Bucket: bucket,
85
+ const { Body } = await this.s3.getObject({
86
+ Bucket: this.bucket,
85
87
  Key: optimizedAssetKey
86
88
  });
87
89
  if (!Body) throw new Error("Missing image body!");
@@ -111,8 +113,8 @@ class SharpTransform {
111
113
  size: optimizedBuffer.length
112
114
  });
113
115
  newAsset.setContentsReader(new CallableContentsReader(()=>optimizedBuffer));
114
- await s3.putObject({
115
- Bucket: bucket,
116
+ await this.s3.putObject({
117
+ Bucket: this.bucket,
116
118
  Key: optimizedAssetKey,
117
119
  ContentType: newAsset.getContentType(),
118
120
  Body: await newAsset.getContents()
@@ -147,6 +149,14 @@ class SharpTransform {
147
149
  });
148
150
  }
149
151
  }
150
- export { SharpTransform };
152
+ const SharpTransformImpl = AssetTransformationStrategy.createImplementation({
153
+ implementation: SharpTransform,
154
+ dependencies: [
155
+ S3Client,
156
+ S3Bucket,
157
+ S3AssetDeliveryConfig
158
+ ]
159
+ });
160
+ export { SharpTransform, SharpTransformImpl };
151
161
 
152
162
  //# sourceMappingURL=SharpTransform.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assetDelivery/s3/SharpTransform.js","sources":["../../../src/assetDelivery/s3/SharpTransform.ts"],"sourcesContent":["import sharp from \"sharp\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type {\n Asset,\n AssetRequest,\n AssetRequestOptions,\n AssetTransformationStrategy\n} from \"@webiny/api-file-manager\";\nimport { WidthCollection } from \"./transformation/WidthCollection.js\";\nimport * as utils from \"./transformation/utils.js\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader.js\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator.js\";\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 console.log(\n `Transformations/optimizations of ${asset.getContentType()} assets are not supported. Skipping.`\n );\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 // oxlint-disable-next-line typescript/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 const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n console.log(`Return a previously transformed asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n } catch {\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 console.log(`Resize the asset (width: ${width})`);\n const buffer = await optimizedImage.getContents();\n const transformedBuffer = await sharp(buffer, {\n animated: this.isAssetAnimated(asset)\n })\n .withMetadata()\n .resize({ width, withoutEnlargement: true })\n .toBuffer();\n\n /**\n * Transformations are applied to the optimized image.\n */\n const newAsset = asset.withProps({ size: transformedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: transformedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n console.log(`Return the resized asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n }\n }\n\n return asset;\n }\n\n private async optimizeAsset(asset: Asset) {\n const { s3, bucket } = this.params;\n\n console.log(\"Optimize asset\", {\n id: asset.getId(),\n key: asset.getKey(),\n size: asset.getSize(),\n type: asset.getContentType()\n });\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 console.log(\"Return a previously optimized asset\", optimizedAssetKey);\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n return newAsset;\n } catch {\n console.log(\"Create an optimized version of the original asset\", asset.getKey());\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 = await optimization(buffer).toBuffer();\n\n console.log(\"Optimized asset size\", optimizedBuffer.length);\n\n const newAsset = asset.withProps({ size: optimizedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));\n\n await s3.putObject({\n Bucket: bucket,\n Key: optimizedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n return newAsset;\n }\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 .withMetadata()\n .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n"],"names":["SharpTransform","params","assetRequest","asset","utils","console","original","options","transformedAsset","Object","s3","bucket","assetKey","AssetKeyGenerator","transformedAssetKey","Body","Error","buffer","Buffer","newAsset","CallableContentsReader","optimizedImage","widths","WidthCollection","width","transformedBuffer","sharp","optimizedAssetKey","optimizationMap","optimization","optimizedBuffer"],"mappings":"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"}
1
+ {"version":3,"file":"assetDelivery/s3/SharpTransform.js","sources":["../../../src/assetDelivery/s3/SharpTransform.ts"],"sourcesContent":["import sharp from \"sharp\";\nimport type { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport type {\n Asset,\n AssetRequest,\n AssetRequestOptions,\n AssetTransformationStrategy\n} from \"@webiny/api-file-manager\";\nimport { AssetTransformationStrategy as AssetTransformationStrategyAbstraction } from \"@webiny/api-file-manager/features/assetDelivery/abstractions.js\";\nimport { WidthCollection } from \"./transformation/WidthCollection.js\";\nimport * as utils from \"./transformation/utils.js\";\nimport { CallableContentsReader } from \"./transformation/CallableContentsReader.js\";\nimport { AssetKeyGenerator } from \"./transformation/AssetKeyGenerator.js\";\nimport { S3Client, S3Bucket, S3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\nimport type { IS3AssetDeliveryConfig } from \"~/assetDelivery/abstractions.js\";\n\nexport class SharpTransform implements AssetTransformationStrategy {\n private readonly s3: S3;\n private readonly bucket: string;\n private readonly imageResizeWidths: number[];\n\n constructor(s3: S3, bucket: string, config: IS3AssetDeliveryConfig) {\n this.s3 = s3;\n this.bucket = bucket;\n this.imageResizeWidths = config.imageResizeWidths;\n }\n\n async transform(assetRequest: AssetRequest, asset: Asset): Promise<Asset> {\n if (!utils.SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension())) {\n console.log(\n `Transformations/optimizations of ${asset.getContentType()} assets are not supported. Skipping.`\n );\n return asset;\n }\n\n // oxlint-disable-next-line typescript/no-unused-vars\n const { original, ...options } = assetRequest.getOptions();\n\n const transformedAsset = asset.clone();\n\n if (Object.keys(options).length > 0) {\n return this.transformAsset(transformedAsset, options);\n }\n\n return this.optimizeAsset(transformedAsset);\n }\n\n private async transformAsset(asset: Asset, options: Omit<AssetRequestOptions, \"original\">) {\n if (options.width) {\n const assetKey = new AssetKeyGenerator(asset);\n const transformedAssetKey = assetKey.getTransformedImageKey(options);\n\n try {\n const { Body } = await this.s3.getObject({\n Bucket: this.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 const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n console.log(`Return a previously transformed asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n } catch {\n const optimizedImage = await this.optimizeAsset(asset);\n\n const widths = new WidthCollection(this.imageResizeWidths);\n const width = widths.getClosestOrMax(options.width);\n\n console.log(`Resize the asset (width: ${width})`);\n const buffer = await optimizedImage.getContents();\n const transformedBuffer = await sharp(buffer, {\n animated: this.isAssetAnimated(asset)\n })\n .withMetadata()\n .resize({ width, withoutEnlargement: true })\n .toBuffer();\n\n const newAsset = asset.withProps({ size: transformedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => transformedBuffer));\n\n await this.s3.putObject({\n Bucket: this.bucket,\n Key: transformedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n console.log(`Return the resized asset`, {\n key: transformedAssetKey,\n size: newAsset.getSize()\n });\n\n return newAsset;\n }\n }\n\n return asset;\n }\n\n private async optimizeAsset(asset: Asset) {\n console.log(\"Optimize asset\", {\n id: asset.getId(),\n key: asset.getKey(),\n size: asset.getSize(),\n type: asset.getContentType()\n });\n\n const assetKey = new AssetKeyGenerator(asset);\n const optimizedAssetKey = assetKey.getOptimizedImageKey();\n\n try {\n const { Body } = await this.s3.getObject({\n Bucket: this.bucket,\n Key: optimizedAssetKey\n });\n\n if (!Body) {\n throw new Error(`Missing image body!`);\n }\n\n console.log(\"Return a previously optimized asset\", optimizedAssetKey);\n\n const buffer = Buffer.from(await Body.transformToByteArray());\n\n const newAsset = asset.withProps({ size: buffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => buffer));\n\n return newAsset;\n } catch {\n console.log(\"Create an optimized version of the original asset\", asset.getKey());\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 = await optimization(buffer).toBuffer();\n\n console.log(\"Optimized asset size\", optimizedBuffer.length);\n\n const newAsset = asset.withProps({ size: optimizedBuffer.length });\n newAsset.setContentsReader(new CallableContentsReader(() => optimizedBuffer));\n\n await this.s3.putObject({\n Bucket: this.bucket,\n Key: optimizedAssetKey,\n ContentType: newAsset.getContentType(),\n Body: await newAsset.getContents()\n });\n\n return newAsset;\n }\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 .withMetadata()\n .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n\nexport const SharpTransformImpl = AssetTransformationStrategyAbstraction.createImplementation({\n implementation: SharpTransform,\n dependencies: [S3Client, S3Bucket, S3AssetDeliveryConfig]\n});\n"],"names":["SharpTransform","s3","bucket","config","assetRequest","asset","utils","console","original","options","transformedAsset","Object","assetKey","AssetKeyGenerator","transformedAssetKey","Body","Error","buffer","Buffer","newAsset","CallableContentsReader","optimizedImage","widths","WidthCollection","width","transformedBuffer","sharp","optimizedAssetKey","optimizationMap","optimization","optimizedBuffer","SharpTransformImpl","AssetTransformationStrategyAbstraction","S3Client","S3Bucket","S3AssetDeliveryConfig"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-file-manager-s3",
3
- "version": "6.4.0-beta.1",
3
+ "version": "6.4.0-beta.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -14,20 +14,20 @@
14
14
  "author": "Webiny Ltd",
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
- "@webiny/api": "6.4.0-beta.1",
18
- "@webiny/api-core": "6.4.0-beta.1",
19
- "@webiny/api-file-manager": "6.4.0-beta.1",
20
- "@webiny/api-websockets": "6.4.0-beta.1",
21
- "@webiny/aws-sdk": "6.4.0-beta.1",
22
- "@webiny/feature": "6.4.0-beta.1",
23
- "@webiny/handler": "6.4.0-beta.1",
24
- "@webiny/handler-aws": "6.4.0-beta.1",
25
- "@webiny/handler-graphql": "6.4.0-beta.1",
26
- "@webiny/plugins": "6.4.0-beta.1",
27
- "@webiny/tasks": "6.4.0-beta.1",
28
- "@webiny/utils": "6.4.0-beta.1",
29
- "@webiny/validation": "6.4.0-beta.1",
30
- "exifreader": "4.39.0",
17
+ "@webiny/api": "6.4.0-beta.3",
18
+ "@webiny/api-core": "6.4.0-beta.3",
19
+ "@webiny/api-file-manager": "6.4.0-beta.3",
20
+ "@webiny/api-websockets": "6.4.0-beta.3",
21
+ "@webiny/aws-sdk": "6.4.0-beta.3",
22
+ "@webiny/feature": "6.4.0-beta.3",
23
+ "@webiny/handler": "6.4.0-beta.3",
24
+ "@webiny/handler-aws": "6.4.0-beta.3",
25
+ "@webiny/handler-graphql": "6.4.0-beta.3",
26
+ "@webiny/plugins": "6.4.0-beta.3",
27
+ "@webiny/tasks": "6.4.0-beta.3",
28
+ "@webiny/utils": "6.4.0-beta.3",
29
+ "@webiny/validation": "6.4.0-beta.3",
30
+ "exifreader": "4.39.1",
31
31
  "mime": "4.1.0",
32
32
  "object-hash": "3.0.0",
33
33
  "p-map": "7.0.4",
@@ -36,7 +36,7 @@
36
36
  "sharp": "0.34.5"
37
37
  },
38
38
  "devDependencies": {
39
- "@webiny/build-tools": "6.4.0-beta.1",
39
+ "@webiny/build-tools": "6.4.0-beta.3",
40
40
  "rimraf": "6.1.3",
41
41
  "typescript": "6.0.3",
42
42
  "vitest": "4.1.6"
@@ -45,5 +45,5 @@
45
45
  "access": "public",
46
46
  "directory": "dist"
47
47
  },
48
- "gitHead": "73237b8243693038c072bae1c0b783387448cbbe"
48
+ "gitHead": "2e58681d4344024bfb60e6180338e2f154ec87f0"
49
49
  }