@webiny/api-file-manager-s3 6.3.0-beta.1 → 6.3.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.
@@ -14,7 +14,7 @@ export class SharpTransform {
14
14
  }
15
15
 
16
16
  // `original` is part of the request, but it won't even get to this point in the execution.
17
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
+ // oxlint-disable-next-line typescript/no-unused-vars
18
18
  const {
19
19
  original,
20
20
  ...options
@@ -1 +1 @@
1
- {"version":3,"names":["sharp","WidthCollection","utils","CallableContentsReader","AssetKeyGenerator","SharpTransform","constructor","params","transform","assetRequest","asset","SUPPORTED_TRANSFORMABLE_IMAGES","includes","getExtension","console","log","getContentType","original","options","getOptions","transformedAsset","clone","Object","keys","length","transformAsset","optimizeAsset","width","s3","bucket","assetKey","transformedAssetKey","getTransformedImageKey","Body","getObject","Bucket","Key","Error","buffer","Buffer","from","transformToByteArray","newAsset","withProps","size","setContentsReader","key","getSize","optimizedImage","widths","imageResizeWidths","getClosestOrMax","getContents","transformedBuffer","animated","isAssetAnimated","withMetadata","resize","withoutEnlargement","toBuffer","putObject","ContentType","id","getId","getKey","type","optimizedAssetKey","getOptimizedImageKey","optimizationMap","optimizePng","optimizeJpeg","optimization","optimizedBuffer","fit","png","compressionLevel","adaptiveFiltering","force","toFormat","quality"],"sources":["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 // 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 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"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["sharp","WidthCollection","utils","CallableContentsReader","AssetKeyGenerator","SharpTransform","constructor","params","transform","assetRequest","asset","SUPPORTED_TRANSFORMABLE_IMAGES","includes","getExtension","console","log","getContentType","original","options","getOptions","transformedAsset","clone","Object","keys","length","transformAsset","optimizeAsset","width","s3","bucket","assetKey","transformedAssetKey","getTransformedImageKey","Body","getObject","Bucket","Key","Error","buffer","Buffer","from","transformToByteArray","newAsset","withProps","size","setContentsReader","key","getSize","optimizedImage","widths","imageResizeWidths","getClosestOrMax","getContents","transformedBuffer","animated","isAssetAnimated","withMetadata","resize","withoutEnlargement","toBuffer","putObject","ContentType","id","getId","getKey","type","optimizedAssetKey","getOptimizedImageKey","optimizationMap","optimizePng","optimizeJpeg","optimization","optimizedBuffer","fit","png","compressionLevel","adaptiveFiltering","force","toFormat","quality"],"sources":["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"],"mappings":"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","ignoreList":[]}
@@ -23,6 +23,7 @@ declare class DeleteS3FolderTask implements TaskDefinition.Interface<DeleteS3Fol
23
23
  description: string;
24
24
  maxIterations: number;
25
25
  isPrivate: boolean;
26
+ readonly selfCleanup: ("onSuccess" | "onAbort")[];
26
27
  run({ input, controller }: TaskDefinition.RunParams<DeleteS3FolderInput>): Promise<TaskDefinition.Result<DeleteS3FolderInput>>;
27
28
  }
28
29
  export declare const DeleteS3FolderTaskDefinition: typeof DeleteS3FolderTask & {
@@ -6,6 +6,7 @@ class DeleteS3FolderTask {
6
6
  description = "A task to delete all files from a given folder.";
7
7
  maxIterations = 5;
8
8
  isPrivate = true;
9
+ selfCleanup = ["onSuccess", "onAbort"];
9
10
  async run({
10
11
  input,
11
12
  controller
@@ -1 +1 @@
1
- {"version":3,"names":["S3","TaskDefinition","DeleteS3FolderTask","id","title","description","maxIterations","isPrivate","run","input","controller","runtime","isAborted","response","aborted","bucket","error","message","s3","filesList","listObjectsV2","Bucket","Prefix","folderKey","ContinuationToken","continuationToken","Contents","length","objectsToDelete","filter","file","Key","map","deleteObjects","Delete","Objects","IsTruncated","NextContinuationToken","continue","done","DeleteS3FolderTaskDefinition","createImplementation","implementation","dependencies"],"sources":["DeleteS3FolderTask.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface DeleteS3FolderInput {\n /**\n * Caller of the task (e.g., `fm-after-delete`).\n */\n caller: string;\n /**\n * Cache paths to invalidate.\n */\n bucket: string;\n /**\n * FM file directory key to delete.\n */\n folderKey: string;\n /**\n * Continuation token for pagination.\n */\n continuationToken?: string;\n}\n\nclass DeleteS3FolderTask implements TaskDefinition.Interface<DeleteS3FolderInput> {\n id = \"fileManagerFolderDelete\";\n title = \"Delete folder and all of its contents from the bucket.\";\n description = \"A task to delete all files from a given folder.\";\n maxIterations = 5;\n isPrivate = true;\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<DeleteS3FolderInput>): Promise<\n TaskDefinition.Result<DeleteS3FolderInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n if (!input.bucket) {\n return controller.response.error({ message: `Bucket is not defined.` });\n }\n\n const s3 = new S3();\n\n // List objects in the folder with pagination support.\n const filesList = await s3.listObjectsV2({\n Bucket: input.bucket,\n Prefix: `${input.folderKey}/`,\n ContinuationToken: input.continuationToken\n });\n\n // Delete all files in the folder using batch delete.\n if (filesList.Contents && filesList.Contents.length > 0) {\n const objectsToDelete = filesList.Contents.filter(file => file.Key).map(file => ({\n Key: file.Key!\n }));\n\n if (objectsToDelete.length > 0) {\n await s3.deleteObjects({\n Bucket: input.bucket,\n Delete: {\n Objects: objectsToDelete\n }\n });\n }\n }\n\n // If there are more objects to delete, continue in the next iteration.\n if (filesList.IsTruncated && filesList.NextContinuationToken) {\n return controller.response.continue({\n ...input,\n continuationToken: filesList.NextContinuationToken\n });\n }\n\n return controller.response.done();\n }\n}\n\nexport const DeleteS3FolderTaskDefinition = TaskDefinition.createImplementation({\n implementation: DeleteS3FolderTask,\n dependencies: []\n});\n"],"mappings":"AAAA,SAASA,EAAE,QAAQ,oCAAoC;AACvD,SAASC,cAAc,QAAQ,wDAAwD;AAqBvF,MAAMC,kBAAkB,CAA0D;EAC9EC,EAAE,GAAG,yBAAyB;EAC9BC,KAAK,GAAG,wDAAwD;EAChEC,WAAW,GAAG,iDAAiD;EAC/DC,aAAa,GAAG,CAAC;EACjBC,SAAS,GAAG,IAAI;EAEhB,MAAaC,GAAGA,CAAC;IACbC,KAAK;IACLC;EAC2C,CAAC,EAE9C;IACE,IAAIA,UAAU,CAACC,OAAO,CAACC,SAAS,CAAC,CAAC,EAAE;MAChC,OAAOF,UAAU,CAACG,QAAQ,CAACC,OAAO,CAAC,CAAC;IACxC;IAEA,IAAI,CAACL,KAAK,CAACM,MAAM,EAAE;MACf,OAAOL,UAAU,CAACG,QAAQ,CAACG,KAAK,CAAC;QAAEC,OAAO,EAAE;MAAyB,CAAC,CAAC;IAC3E;IAEA,MAAMC,EAAE,GAAG,IAAIlB,EAAE,CAAC,CAAC;;IAEnB;IACA,MAAMmB,SAAS,GAAG,MAAMD,EAAE,CAACE,aAAa,CAAC;MACrCC,MAAM,EAAEZ,KAAK,CAACM,MAAM;MACpBO,MAAM,EAAE,GAAGb,KAAK,CAACc,SAAS,GAAG;MAC7BC,iBAAiB,EAAEf,KAAK,CAACgB;IAC7B,CAAC,CAAC;;IAEF;IACA,IAAIN,SAAS,CAACO,QAAQ,IAAIP,SAAS,CAACO,QAAQ,CAACC,MAAM,GAAG,CAAC,EAAE;MACrD,MAAMC,eAAe,GAAGT,SAAS,CAACO,QAAQ,CAACG,MAAM,CAACC,IAAI,IAAIA,IAAI,CAACC,GAAG,CAAC,CAACC,GAAG,CAACF,IAAI,KAAK;QAC7EC,GAAG,EAAED,IAAI,CAACC;MACd,CAAC,CAAC,CAAC;MAEH,IAAIH,eAAe,CAACD,MAAM,GAAG,CAAC,EAAE;QAC5B,MAAMT,EAAE,CAACe,aAAa,CAAC;UACnBZ,MAAM,EAAEZ,KAAK,CAACM,MAAM;UACpBmB,MAAM,EAAE;YACJC,OAAO,EAAEP;UACb;QACJ,CAAC,CAAC;MACN;IACJ;;IAEA;IACA,IAAIT,SAAS,CAACiB,WAAW,IAAIjB,SAAS,CAACkB,qBAAqB,EAAE;MAC1D,OAAO3B,UAAU,CAACG,QAAQ,CAACyB,QAAQ,CAAC;QAChC,GAAG7B,KAAK;QACRgB,iBAAiB,EAAEN,SAAS,CAACkB;MACjC,CAAC,CAAC;IACN;IAEA,OAAO3B,UAAU,CAACG,QAAQ,CAAC0B,IAAI,CAAC,CAAC;EACrC;AACJ;AAEA,OAAO,MAAMC,4BAA4B,GAAGvC,cAAc,CAACwC,oBAAoB,CAAC;EAC5EC,cAAc,EAAExC,kBAAkB;EAClCyC,YAAY,EAAE;AAClB,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["S3","TaskDefinition","DeleteS3FolderTask","id","title","description","maxIterations","isPrivate","selfCleanup","run","input","controller","runtime","isAborted","response","aborted","bucket","error","message","s3","filesList","listObjectsV2","Bucket","Prefix","folderKey","ContinuationToken","continuationToken","Contents","length","objectsToDelete","filter","file","Key","map","deleteObjects","Delete","Objects","IsTruncated","NextContinuationToken","continue","done","DeleteS3FolderTaskDefinition","createImplementation","implementation","dependencies"],"sources":["DeleteS3FolderTask.ts"],"sourcesContent":["import { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\n\nexport interface DeleteS3FolderInput {\n /**\n * Caller of the task (e.g., `fm-after-delete`).\n */\n caller: string;\n /**\n * Cache paths to invalidate.\n */\n bucket: string;\n /**\n * FM file directory key to delete.\n */\n folderKey: string;\n /**\n * Continuation token for pagination.\n */\n continuationToken?: string;\n}\n\nclass DeleteS3FolderTask implements TaskDefinition.Interface<DeleteS3FolderInput> {\n id = \"fileManagerFolderDelete\";\n title = \"Delete folder and all of its contents from the bucket.\";\n description = \"A task to delete all files from a given folder.\";\n maxIterations = 5;\n isPrivate = true;\n\n public readonly selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<DeleteS3FolderInput>): Promise<\n TaskDefinition.Result<DeleteS3FolderInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n if (!input.bucket) {\n return controller.response.error({ message: `Bucket is not defined.` });\n }\n\n const s3 = new S3();\n\n // List objects in the folder with pagination support.\n const filesList = await s3.listObjectsV2({\n Bucket: input.bucket,\n Prefix: `${input.folderKey}/`,\n ContinuationToken: input.continuationToken\n });\n\n // Delete all files in the folder using batch delete.\n if (filesList.Contents && filesList.Contents.length > 0) {\n const objectsToDelete = filesList.Contents.filter(file => file.Key).map(file => ({\n Key: file.Key!\n }));\n\n if (objectsToDelete.length > 0) {\n await s3.deleteObjects({\n Bucket: input.bucket,\n Delete: {\n Objects: objectsToDelete\n }\n });\n }\n }\n\n // If there are more objects to delete, continue in the next iteration.\n if (filesList.IsTruncated && filesList.NextContinuationToken) {\n return controller.response.continue({\n ...input,\n continuationToken: filesList.NextContinuationToken\n });\n }\n\n return controller.response.done();\n }\n}\n\nexport const DeleteS3FolderTaskDefinition = TaskDefinition.createImplementation({\n implementation: DeleteS3FolderTask,\n dependencies: []\n});\n"],"mappings":"AAAA,SAASA,EAAE,QAAQ,oCAAoC;AACvD,SAASC,cAAc,QAAQ,wDAAwD;AAqBvF,MAAMC,kBAAkB,CAA0D;EAC9EC,EAAE,GAAG,yBAAyB;EAC9BC,KAAK,GAAG,wDAAwD;EAChEC,WAAW,GAAG,iDAAiD;EAC/DC,aAAa,GAAG,CAAC;EACjBC,SAAS,GAAG,IAAI;EAEAC,WAAW,GAAG,CAAC,WAAW,EAAW,SAAS,CAAU;EAExE,MAAaC,GAAGA,CAAC;IACbC,KAAK;IACLC;EAC2C,CAAC,EAE9C;IACE,IAAIA,UAAU,CAACC,OAAO,CAACC,SAAS,CAAC,CAAC,EAAE;MAChC,OAAOF,UAAU,CAACG,QAAQ,CAACC,OAAO,CAAC,CAAC;IACxC;IAEA,IAAI,CAACL,KAAK,CAACM,MAAM,EAAE;MACf,OAAOL,UAAU,CAACG,QAAQ,CAACG,KAAK,CAAC;QAAEC,OAAO,EAAE;MAAyB,CAAC,CAAC;IAC3E;IAEA,MAAMC,EAAE,GAAG,IAAInB,EAAE,CAAC,CAAC;;IAEnB;IACA,MAAMoB,SAAS,GAAG,MAAMD,EAAE,CAACE,aAAa,CAAC;MACrCC,MAAM,EAAEZ,KAAK,CAACM,MAAM;MACpBO,MAAM,EAAE,GAAGb,KAAK,CAACc,SAAS,GAAG;MAC7BC,iBAAiB,EAAEf,KAAK,CAACgB;IAC7B,CAAC,CAAC;;IAEF;IACA,IAAIN,SAAS,CAACO,QAAQ,IAAIP,SAAS,CAACO,QAAQ,CAACC,MAAM,GAAG,CAAC,EAAE;MACrD,MAAMC,eAAe,GAAGT,SAAS,CAACO,QAAQ,CAACG,MAAM,CAACC,IAAI,IAAIA,IAAI,CAACC,GAAG,CAAC,CAACC,GAAG,CAACF,IAAI,KAAK;QAC7EC,GAAG,EAAED,IAAI,CAACC;MACd,CAAC,CAAC,CAAC;MAEH,IAAIH,eAAe,CAACD,MAAM,GAAG,CAAC,EAAE;QAC5B,MAAMT,EAAE,CAACe,aAAa,CAAC;UACnBZ,MAAM,EAAEZ,KAAK,CAACM,MAAM;UACpBmB,MAAM,EAAE;YACJC,OAAO,EAAEP;UACb;QACJ,CAAC,CAAC;MACN;IACJ;;IAEA;IACA,IAAIT,SAAS,CAACiB,WAAW,IAAIjB,SAAS,CAACkB,qBAAqB,EAAE;MAC1D,OAAO3B,UAAU,CAACG,QAAQ,CAACyB,QAAQ,CAAC;QAChC,GAAG7B,KAAK;QACRgB,iBAAiB,EAAEN,SAAS,CAACkB;MACjC,CAAC,CAAC;IACN;IAEA,OAAO3B,UAAU,CAACG,QAAQ,CAAC0B,IAAI,CAAC,CAAC;EACrC;AACJ;AAEA,OAAO,MAAMC,4BAA4B,GAAGxC,cAAc,CAACyC,oBAAoB,CAAC;EAC5EC,cAAc,EAAEzC,kBAAkB;EAClC0C,YAAY,EAAE;AAClB,CAAC,CAAC","ignoreList":[]}
@@ -13,6 +13,7 @@ declare class ExtractMetadataTask implements TaskDefinition.Interface<ExtractMet
13
13
  maxIterations: number;
14
14
  isPrivate: boolean;
15
15
  databaseLogs: boolean;
16
+ selfCleanup: ("onSuccess" | "onAbort")[];
16
17
  constructor(keyValueStore: GlobalKeyValueStore.Interface, updateFileUseCase: UpdateFileUseCase.Interface);
17
18
  run({ input, controller }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<TaskDefinition.Result<ExtractMetadataInput>>;
18
19
  private cleanValues;
@@ -10,6 +10,7 @@ class ExtractMetadataTask {
10
10
  maxIterations = 1;
11
11
  isPrivate = true;
12
12
  databaseLogs = false;
13
+ selfCleanup = ["onSuccess", "onAbort"];
13
14
  constructor(keyValueStore, updateFileUseCase) {
14
15
  this.keyValueStore = keyValueStore;
15
16
  this.updateFileUseCase = updateFileUseCase;
@@ -1 +1 @@
1
- {"version":3,"names":["S3","TaskDefinition","GlobalKeyValueStore","UpdateFileUseCase","MetadataReader","ExtractMetadataTask","id","title","description","maxIterations","isPrivate","databaseLogs","constructor","keyValueStore","updateFileUseCase","run","input","controller","runtime","isAborted","response","aborted","metadataReader","fileMetadata","read","fileId","error","message","contentType","startsWith","done","s3","bucket","String","process","env","S3_BUCKET","s3Object","getObject","Bucket","Key","bucketKey","Body","sharp","then","m","default","ExifReader","buffer","Buffer","from","transformToByteArray","sharpInstance","sharpMetadata","metadata","tags","load","expanded","image","width","height","format","orientation","exif","cleanValues","iptc","updateResult","execute","isFail","Error","cleaned","key","tag","Object","entries","undefined","Array","isArray","value","length","ExtractMetadataTaskDefinition","createImplementation","implementation","dependencies"],"sources":["ExtractMetadataTask.ts"],"sourcesContent":["import type { ExifTags } from \"exifreader\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"../WriteFileMetadata/MetadataReader.js\";\n\nexport interface ExtractMetadataInput {\n fileId: string;\n}\n\nclass ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {\n id = \"fileManagerExtractMetadata\";\n title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n description = \"A task to extract metadata from uploaded image files\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private updateFileUseCase: UpdateFileUseCase.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<\n TaskDefinition.Result<ExtractMetadataInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Load file metadata\n const metadataReader = new MetadataReader(this.keyValueStore);\n const fileMetadata = await metadataReader.read(input.fileId);\n\n if (!fileMetadata) {\n return controller.response.error({\n message: `File metadata not found for file ID: ${input.fileId}`\n });\n }\n\n // Check if it's an image file\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n // Fetch the image from S3\n const s3 = new S3();\n const bucket = String(process.env.S3_BUCKET);\n\n try {\n const s3Object = await s3.getObject({\n Bucket: bucket,\n Key: fileMetadata.bucketKey\n });\n\n if (!s3Object.Body) {\n return controller.response.error({\n message: `S3 object body is empty for file: ${input.fileId}`\n });\n }\n\n const sharp = await import(/* webpackChunkName: \"sharp\" */ \"sharp\").then(\n m => m.default\n );\n\n const ExifReader = await import(/* webpackChunkName: \"exifreader\" */ \"exifreader\").then(\n m => m.default\n );\n\n // Convert S3 body to buffer\n const buffer = Buffer.from(await s3Object.Body.transformToByteArray());\n\n // Extract metadata using Sharp for image dimensions\n const sharpInstance = sharp(buffer);\n const sharpMetadata = await sharpInstance.metadata();\n\n // Use ExifReader to extract EXIF and IPTC data\n const tags = ExifReader.load(buffer, { expanded: true });\n\n // Build metadata object\n const metadata: Record<string, any> = {\n image: {\n width: sharpMetadata.width,\n height: sharpMetadata.height,\n format: sharpMetadata.format,\n orientation: sharpMetadata.orientation ?? 1\n }\n };\n\n // Extract EXIF data if available\n if (tags.exif) {\n metadata.exif = this.cleanValues(tags.exif);\n }\n\n // Extract IPTC data if available\n if (tags.iptc) {\n metadata.iptc = this.cleanValues(tags.iptc);\n }\n\n // Update the file with extracted metadata\n const updateResult = await this.updateFileUseCase.execute({\n id: input.fileId,\n metadata\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file with metadata: ${updateResult.error.message}`\n });\n }\n\n return controller.response.done();\n } catch (error) {\n return controller.response.error({\n message: `Failed to extract metadata: ${\n error instanceof Error ? error.message : String(error)\n }`\n });\n }\n }\n\n private cleanValues(tags: ExifTags) {\n const cleaned: Record<string, any> = {};\n\n for (const [key, tag] of Object.entries(tags)) {\n if (!tag || typeof tag !== \"object\") {\n continue;\n }\n\n // Use description if available, otherwise value\n if (tag.description !== undefined && tag.description !== null) {\n cleaned[key] = tag.description;\n } else if (Array.isArray(tag.value) && tag.value.length > 20) {\n // Skip large byte arrays\n } else if (tag.value !== undefined) {\n cleaned[key] = tag.value;\n }\n }\n\n return cleaned;\n }\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTask,\n dependencies: [GlobalKeyValueStore, UpdateFileUseCase]\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["S3","TaskDefinition","GlobalKeyValueStore","UpdateFileUseCase","MetadataReader","ExtractMetadataTask","id","title","description","maxIterations","isPrivate","databaseLogs","selfCleanup","constructor","keyValueStore","updateFileUseCase","run","input","controller","runtime","isAborted","response","aborted","metadataReader","fileMetadata","read","fileId","error","message","contentType","startsWith","done","s3","bucket","String","process","env","S3_BUCKET","s3Object","getObject","Bucket","Key","bucketKey","Body","sharp","then","m","default","ExifReader","buffer","Buffer","from","transformToByteArray","sharpInstance","sharpMetadata","metadata","tags","load","expanded","image","width","height","format","orientation","exif","cleanValues","iptc","updateResult","execute","isFail","Error","cleaned","key","tag","Object","entries","undefined","Array","isArray","value","length","ExtractMetadataTaskDefinition","createImplementation","implementation","dependencies"],"sources":["ExtractMetadataTask.ts"],"sourcesContent":["import type { ExifTags } from \"exifreader\";\nimport { S3 } from \"@webiny/aws-sdk/client-s3/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { GlobalKeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { UpdateFileUseCase } from \"@webiny/api-file-manager/features/file/UpdateFile/index.js\";\nimport { MetadataReader } from \"../WriteFileMetadata/MetadataReader.js\";\n\nexport interface ExtractMetadataInput {\n fileId: string;\n}\n\nclass ExtractMetadataTask implements TaskDefinition.Interface<ExtractMetadataInput> {\n id = \"fileManagerExtractMetadata\";\n title = \"Extract image metadata (dimensions, EXIF, IPTC)\";\n description = \"A task to extract metadata from uploaded image files\";\n maxIterations = 1;\n isPrivate = true;\n databaseLogs = false;\n\n selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n constructor(\n private keyValueStore: GlobalKeyValueStore.Interface,\n private updateFileUseCase: UpdateFileUseCase.Interface\n ) {}\n\n public async run({\n input,\n controller\n }: TaskDefinition.RunParams<ExtractMetadataInput>): Promise<\n TaskDefinition.Result<ExtractMetadataInput>\n > {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n // Load file metadata\n const metadataReader = new MetadataReader(this.keyValueStore);\n const fileMetadata = await metadataReader.read(input.fileId);\n\n if (!fileMetadata) {\n return controller.response.error({\n message: `File metadata not found for file ID: ${input.fileId}`\n });\n }\n\n // Check if it's an image file\n if (!fileMetadata.contentType.startsWith(\"image/\")) {\n return controller.response.done();\n }\n\n // Fetch the image from S3\n const s3 = new S3();\n const bucket = String(process.env.S3_BUCKET);\n\n try {\n const s3Object = await s3.getObject({\n Bucket: bucket,\n Key: fileMetadata.bucketKey\n });\n\n if (!s3Object.Body) {\n return controller.response.error({\n message: `S3 object body is empty for file: ${input.fileId}`\n });\n }\n\n const sharp = await import(/* webpackChunkName: \"sharp\" */ \"sharp\").then(\n m => m.default\n );\n\n const ExifReader = await import(/* webpackChunkName: \"exifreader\" */ \"exifreader\").then(\n m => m.default\n );\n\n // Convert S3 body to buffer\n const buffer = Buffer.from(await s3Object.Body.transformToByteArray());\n\n // Extract metadata using Sharp for image dimensions\n const sharpInstance = sharp(buffer);\n const sharpMetadata = await sharpInstance.metadata();\n\n // Use ExifReader to extract EXIF and IPTC data\n const tags = ExifReader.load(buffer, { expanded: true });\n\n // Build metadata object\n const metadata: Record<string, any> = {\n image: {\n width: sharpMetadata.width,\n height: sharpMetadata.height,\n format: sharpMetadata.format,\n orientation: sharpMetadata.orientation ?? 1\n }\n };\n\n // Extract EXIF data if available\n if (tags.exif) {\n metadata.exif = this.cleanValues(tags.exif);\n }\n\n // Extract IPTC data if available\n if (tags.iptc) {\n metadata.iptc = this.cleanValues(tags.iptc);\n }\n\n // Update the file with extracted metadata\n const updateResult = await this.updateFileUseCase.execute({\n id: input.fileId,\n metadata\n });\n\n if (updateResult.isFail()) {\n return controller.response.error({\n message: `Failed to update file with metadata: ${updateResult.error.message}`\n });\n }\n\n return controller.response.done();\n } catch (error) {\n return controller.response.error({\n message: `Failed to extract metadata: ${\n error instanceof Error ? error.message : String(error)\n }`\n });\n }\n }\n\n private cleanValues(tags: ExifTags) {\n const cleaned: Record<string, any> = {};\n\n for (const [key, tag] of Object.entries(tags)) {\n if (!tag || typeof tag !== \"object\") {\n continue;\n }\n\n // Use description if available, otherwise value\n if (tag.description !== undefined && tag.description !== null) {\n cleaned[key] = tag.description;\n } else if (Array.isArray(tag.value) && tag.value.length > 20) {\n // Skip large byte arrays\n } else if (tag.value !== undefined) {\n cleaned[key] = tag.value;\n }\n }\n\n return cleaned;\n }\n}\n\nexport const ExtractMetadataTaskDefinition = TaskDefinition.createImplementation({\n implementation: ExtractMetadataTask,\n dependencies: [GlobalKeyValueStore, UpdateFileUseCase]\n});\n"],"mappings":"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","ignoreList":[]}
@@ -15,6 +15,7 @@ declare class InvalidateCloudfrontCacheTask implements TaskDefinition.Interface<
15
15
  description: string;
16
16
  maxIterations: number;
17
17
  isPrivate: boolean;
18
+ selfCleanup: ("onSuccess" | "onAbort")[];
18
19
  private continueIfCode;
19
20
  run({ input, controller }: TaskDefinition.RunParams<InvalidateCacheInput>): Promise<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskResultError | import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskResultAborted | TaskDefinition.ResultDone<import("@webiny/api-core/features/task/TaskDefinition/abstractions").ITaskOutput> | TaskDefinition.ResultContinue<InvalidateCacheInput>>;
20
21
  private invalidateCache;
@@ -9,6 +9,7 @@ class InvalidateCloudfrontCacheTask {
9
9
  description = "A task to invalidate Cloudfront cache by given paths.";
10
10
  maxIterations = 100;
11
11
  isPrivate = true;
12
+ selfCleanup = ["onSuccess", "onAbort"];
12
13
  continueIfCode = ["TooManyInvalidationsInProgress", "Throttling"];
13
14
  async run({
14
15
  input,
@@ -1 +1 @@
1
- {"version":3,"names":["ServiceDiscovery","CloudFront","TaskDefinition","executeWithRetry","ReturnContinue","Error","InvalidateCloudfrontCacheTask","id","title","description","maxIterations","isPrivate","continueIfCode","run","input","controller","runtime","isAborted","response","aborted","manifest","load","error","message","code","data","distributionId","api","cloudfront","invalidateCache","caller","paths","minTimeout","retries","onFailedAttempt","includes","name","isCloseToTimeout","continue","done","createInvalidation","DistributionId","InvalidationBatch","CallerReference","Date","getTime","Paths","Quantity","length","Items","InvalidateCloudfrontCacheTaskDefinition","createImplementation","implementation","dependencies"],"sources":["InvalidateCacheTask.ts"],"sourcesContent":["import { ServiceDiscovery } from \"@webiny/api\";\nimport { CloudFront } from \"@webiny/aws-sdk/client-cloudfront/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { executeWithRetry } from \"@webiny/utils\";\n\nclass ReturnContinue extends Error {}\n\nexport interface InvalidateCacheInput {\n /**\n * Caller of the task (e.g., `fm-before-update`, `fm-after-delete`).\n */\n caller: string;\n /**\n * Cache paths to invalidate.\n */\n paths: string[];\n}\n\nclass InvalidateCloudfrontCacheTask implements TaskDefinition.Interface<InvalidateCacheInput> {\n id = \"cloudfrontInvalidateCache\";\n title = \"Invalidate CloudFront Cache\";\n description = \"A task to invalidate Cloudfront cache by given paths.\";\n maxIterations = 100;\n isPrivate = true;\n\n private continueIfCode = [\"TooManyInvalidationsInProgress\", \"Throttling\"];\n\n public async run({ input, controller }: TaskDefinition.RunParams<InvalidateCacheInput>) {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const manifest = await ServiceDiscovery.load();\n\n if (!manifest) {\n return controller.response.error({\n message: `Unable to invalidate cache due to a missing service manifest.`,\n code: \"MISSING_SERVICE_MANIFEST\",\n data: {\n manifest: \"api\"\n }\n });\n }\n\n const { distributionId } = manifest.api.cloudfront;\n\n const invalidateCache = () => {\n return this.invalidateCache(input.caller, distributionId as string, input.paths);\n };\n\n try {\n await executeWithRetry(invalidateCache, {\n minTimeout: 2000,\n // instead of forever: true\n retries: 10000,\n onFailedAttempt: ({ error }) => {\n if (this.continueIfCode.includes(error.name)) {\n throw new ReturnContinue();\n }\n\n if (error.message.includes(\"not authorized to perform\")) {\n throw error;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n throw new ReturnContinue();\n }\n }\n });\n } catch (error) {\n if (error instanceof ReturnContinue) {\n return controller.response.continue(input);\n }\n\n return controller.response.error({\n message: error.message,\n code: \"EXECUTE_WITH_RETRY_FAILED\",\n data: input.paths\n });\n }\n\n return controller.response.done();\n }\n\n private async invalidateCache(\n caller: string,\n distributionId: string,\n paths: string[]\n ): Promise<void> {\n const cloudfront = new CloudFront();\n await cloudfront.createInvalidation({\n DistributionId: distributionId,\n InvalidationBatch: {\n CallerReference: `${new Date().getTime()}-${caller}`,\n Paths: {\n Quantity: paths.length,\n Items: paths\n }\n }\n });\n }\n}\n\nexport const InvalidateCloudfrontCacheTaskDefinition = TaskDefinition.createImplementation({\n implementation: InvalidateCloudfrontCacheTask,\n dependencies: []\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["ServiceDiscovery","CloudFront","TaskDefinition","executeWithRetry","ReturnContinue","Error","InvalidateCloudfrontCacheTask","id","title","description","maxIterations","isPrivate","selfCleanup","continueIfCode","run","input","controller","runtime","isAborted","response","aborted","manifest","load","error","message","code","data","distributionId","api","cloudfront","invalidateCache","caller","paths","minTimeout","retries","onFailedAttempt","includes","name","isCloseToTimeout","continue","done","createInvalidation","DistributionId","InvalidationBatch","CallerReference","Date","getTime","Paths","Quantity","length","Items","InvalidateCloudfrontCacheTaskDefinition","createImplementation","implementation","dependencies"],"sources":["InvalidateCacheTask.ts"],"sourcesContent":["import { ServiceDiscovery } from \"@webiny/api\";\nimport { CloudFront } from \"@webiny/aws-sdk/client-cloudfront/index.js\";\nimport { TaskDefinition } from \"@webiny/api-core/features/task/TaskDefinition/index.js\";\nimport { executeWithRetry } from \"@webiny/utils\";\n\nclass ReturnContinue extends Error {}\n\nexport interface InvalidateCacheInput {\n /**\n * Caller of the task (e.g., `fm-before-update`, `fm-after-delete`).\n */\n caller: string;\n /**\n * Cache paths to invalidate.\n */\n paths: string[];\n}\n\nclass InvalidateCloudfrontCacheTask implements TaskDefinition.Interface<InvalidateCacheInput> {\n id = \"cloudfrontInvalidateCache\";\n title = \"Invalidate CloudFront Cache\";\n description = \"A task to invalidate Cloudfront cache by given paths.\";\n maxIterations = 100;\n isPrivate = true;\n\n selfCleanup = [\"onSuccess\" as const, \"onAbort\" as const];\n\n private continueIfCode = [\"TooManyInvalidationsInProgress\", \"Throttling\"];\n\n public async run({ input, controller }: TaskDefinition.RunParams<InvalidateCacheInput>) {\n if (controller.runtime.isAborted()) {\n return controller.response.aborted();\n }\n\n const manifest = await ServiceDiscovery.load();\n\n if (!manifest) {\n return controller.response.error({\n message: `Unable to invalidate cache due to a missing service manifest.`,\n code: \"MISSING_SERVICE_MANIFEST\",\n data: {\n manifest: \"api\"\n }\n });\n }\n\n const { distributionId } = manifest.api.cloudfront;\n\n const invalidateCache = () => {\n return this.invalidateCache(input.caller, distributionId as string, input.paths);\n };\n\n try {\n await executeWithRetry(invalidateCache, {\n minTimeout: 2000,\n // instead of forever: true\n retries: 10000,\n onFailedAttempt: ({ error }) => {\n if (this.continueIfCode.includes(error.name)) {\n throw new ReturnContinue();\n }\n\n if (error.message.includes(\"not authorized to perform\")) {\n throw error;\n }\n\n if (controller.runtime.isCloseToTimeout()) {\n throw new ReturnContinue();\n }\n }\n });\n } catch (error) {\n if (error instanceof ReturnContinue) {\n return controller.response.continue(input);\n }\n\n return controller.response.error({\n message: error.message,\n code: \"EXECUTE_WITH_RETRY_FAILED\",\n data: input.paths\n });\n }\n\n return controller.response.done();\n }\n\n private async invalidateCache(\n caller: string,\n distributionId: string,\n paths: string[]\n ): Promise<void> {\n const cloudfront = new CloudFront();\n await cloudfront.createInvalidation({\n DistributionId: distributionId,\n InvalidationBatch: {\n CallerReference: `${new Date().getTime()}-${caller}`,\n Paths: {\n Quantity: paths.length,\n Items: paths\n }\n }\n });\n }\n}\n\nexport const InvalidateCloudfrontCacheTaskDefinition = TaskDefinition.createImplementation({\n implementation: InvalidateCloudfrontCacheTask,\n dependencies: []\n});\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@webiny/api-file-manager-s3",
3
- "version": "6.3.0-beta.1",
3
+ "version": "6.3.0-beta.3",
4
4
  "type": "module",
5
- "main": "index.js",
5
+ "exports": {
6
+ ".": "./index.js",
7
+ "./*": "./*"
8
+ },
6
9
  "repository": {
7
10
  "type": "git",
8
11
  "url": "https://github.com/webiny/webiny-js.git"
@@ -11,19 +14,19 @@
11
14
  "author": "Webiny Ltd",
12
15
  "license": "MIT",
13
16
  "dependencies": {
14
- "@webiny/api": "6.3.0-beta.1",
15
- "@webiny/api-core": "6.3.0-beta.1",
16
- "@webiny/api-file-manager": "6.3.0-beta.1",
17
- "@webiny/api-websockets": "6.3.0-beta.1",
18
- "@webiny/aws-sdk": "6.3.0-beta.1",
19
- "@webiny/feature": "6.3.0-beta.1",
20
- "@webiny/handler": "6.3.0-beta.1",
21
- "@webiny/handler-aws": "6.3.0-beta.1",
22
- "@webiny/handler-graphql": "6.3.0-beta.1",
23
- "@webiny/plugins": "6.3.0-beta.1",
24
- "@webiny/tasks": "6.3.0-beta.1",
25
- "@webiny/utils": "6.3.0-beta.1",
26
- "@webiny/validation": "6.3.0-beta.1",
17
+ "@webiny/api": "6.3.0-beta.3",
18
+ "@webiny/api-core": "6.3.0-beta.3",
19
+ "@webiny/api-file-manager": "6.3.0-beta.3",
20
+ "@webiny/api-websockets": "6.3.0-beta.3",
21
+ "@webiny/aws-sdk": "6.3.0-beta.3",
22
+ "@webiny/feature": "6.3.0-beta.3",
23
+ "@webiny/handler": "6.3.0-beta.3",
24
+ "@webiny/handler-aws": "6.3.0-beta.3",
25
+ "@webiny/handler-graphql": "6.3.0-beta.3",
26
+ "@webiny/plugins": "6.3.0-beta.3",
27
+ "@webiny/tasks": "6.3.0-beta.3",
28
+ "@webiny/utils": "6.3.0-beta.3",
29
+ "@webiny/validation": "6.3.0-beta.3",
27
30
  "exifreader": "4.38.1",
28
31
  "mime": "4.1.0",
29
32
  "object-hash": "3.0.0",
@@ -33,14 +36,14 @@
33
36
  "sharp": "0.34.5"
34
37
  },
35
38
  "devDependencies": {
36
- "@webiny/build-tools": "6.3.0-beta.1",
39
+ "@webiny/build-tools": "6.3.0-beta.3",
37
40
  "rimraf": "6.1.3",
38
41
  "typescript": "6.0.3",
39
- "vitest": "4.1.4"
42
+ "vitest": "4.1.5"
40
43
  },
41
44
  "publishConfig": {
42
45
  "access": "public",
43
46
  "directory": "dist"
44
47
  },
45
- "gitHead": "664b273a9f0a971f9ca7e6ffe920db77fefdced1"
48
+ "gitHead": "e154ec3326903876c357d35422dc60d29e061419"
46
49
  }