datocms-plugin-asset-optimization 0.7.6 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>DatoCMS Plugin</title>
8
- <script type="module" crossorigin src="./assets/index-CqRkSJk3.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-CFTYESMw.css">
8
+ <script type="module" crossorigin src="./assets/index-ZNVa5Sti.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-QKXhJ4Sk.css">
10
10
  </head>
11
11
 
12
12
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "datocms-plugin-asset-optimization",
3
3
  "homepage": "https://github.com/datocms/plugins/tree/master/asset-optimization#readme",
4
- "version": "0.7.6",
4
+ "version": "0.7.7",
5
5
  "author": "DatoCMS <support@datocms.com>",
6
6
  "description": "A plugin that allows you to mass apply optimizations to your DatoCMS assets.",
7
7
  "keywords": [
@@ -41,7 +41,7 @@
41
41
  "@types/lodash.debounce": "^4.0.9",
42
42
  "@types/react": "^19.2.14",
43
43
  "@types/react-dom": "^19.2.3",
44
- "@vitejs/plugin-react": "^5.1.4",
44
+ "@vitejs/plugin-react": "^5.2.0",
45
45
  "globals": "^17.4.0",
46
46
  "typescript": "^5.9.3",
47
47
  "vite": "^7.3.1"
@@ -1 +0,0 @@
1
- async function T(e,t,o,r=60,u=2e3){const n="https://site-api.datocms.com",h={Authorization:`Bearer ${t}`,"Content-Type":"application/json",Accept:"application/json","X-Api-Version":"3","X-Environment":o};let c=0;for(;c<r;){c++;try{console.log(`Checking job status (attempt ${c}/${r}): ${e}`);const s=await fetch(`${n}/job-results/${e}`,{method:"GET",headers:h});if(!s.ok){const l=await s.text();throw new Error(`API error: ${s.status} ${l}`)}const a=await s.json();if(a.data.attributes&&a.data.attributes.status===200)return console.log(`Job completed successfully: ${e}`),a;console.log(`Job in progress (${c}/${r}), waiting ${u}ms...`),await new Promise(l=>setTimeout(l,u))}catch(s){console.error(`Error checking job status: ${s instanceof Error?s.message:String(s)}`),await new Promise(a=>setTimeout(a,u))}}throw new Error(`Job timed out after ${r} attempts: ${e}`)}const y=e=>new Promise(t=>setTimeout(t,e)),A=(e,t,o,r)=>{const u=t*r**e;return Math.min(u,o)};async function $(e,t,o,r,u,n=0,h=1e3,c=6e4,s=2){if(console.log(`Replacing DatoCMS asset ID ${e} with image from URL: ${t}${n>0?` (retry ${n})`:""}`),!e||!o)throw new Error("Missing required parameters: assetId and apiToken are required");try{const a="https://site-api.datocms.com",l={Authorization:`Bearer ${o}`,"Content-Type":"application/json",Accept:"application/json","X-Api-Version":"3","X-Environment":r},p=await fetch(`${a}/upload-requests`,{method:"POST",headers:l,body:JSON.stringify({data:{type:"upload_request",attributes:{filename:u||"optimized-image.jpg"}}})});if(p.status===429){const i=p.headers.get("Retry-After"),d=i?Number.parseInt(i,10):0,m=d>0?d*1e3:A(n,h,c,s);return console.log(`Rate limit exceeded. Retrying after ${m}ms`),await y(m),$(e,t,o,r,u,n+1,h,c,s)}if(!p.ok){const i=await p.text();throw new Error(`Failed to create upload request: ${p.status} ${i}`)}const C=await p.json(),{id:P,attributes:{url:q,request_headers:R}}=C.data,w=await fetch(t);if(!w.ok)throw new Error(`Failed to fetch image from URL: ${w.status} ${w.statusText}`);const j=await(await w.blob()).arrayBuffer(),E=new Uint8Array(j),b=await fetch(q,{method:"PUT",headers:{...R,"Content-Length":E.length.toString()},body:E});if(!b.ok)throw new Error(`Failed to upload file to S3: ${b.status} ${b.statusText}`);const f=await fetch(`${a}/uploads/${e}`,{method:"PUT",headers:l,body:JSON.stringify({data:{id:e,type:"upload",attributes:{path:P}}})});if(f.status===429){const i=f.headers.get("Retry-After"),d=i?Number.parseInt(i,10):0,m=d>0?d*1e3:A(n,h,c,s);return console.log(`Rate limit exceeded during asset update. Retrying after ${m}ms`),await y(m),$(e,t,o,r,u,n+1,h,c,s)}if(!f.ok){const i=await f.text();throw new Error(`Failed to update asset metadata: ${f.status} ${i}`)}const g=await f.json();if(g.data&&g.data.type==="job"){const i=g.data.id;console.log(`Asset update initiated as job ${i}, waiting for completion...`);const d=await T(i,o,r);if(d.data.attributes?.status!==200)throw new Error(`Job completed with error status: ${d.data.attributes?.status}`);return d.data.attributes.payload}return console.log("Asset replaced successfully:",g),g}catch(a){if(a instanceof Error&&a.message.includes("API error")&&n<5){const l=A(n,h,c,s);return console.error(`Error replacing asset: ${a.message}. Retrying in ${l}ms...`),await y(l),$(e,t,o,r,u,n+1,h,c,s)}throw console.error("Error replacing asset:",a),a}}class v{queue=[];activeCount=0;config;processing=!1;completedCount=0;failedCount=0;resolvePromise=null;constructor(t){this.config={...t,concurrency:t.concurrency||3,initialRetryDelay:t.initialRetryDelay||1e3,maxRetryDelay:t.maxRetryDelay||6e4,retryBackoffFactor:t.retryBackoffFactor||2}}addTask(t,o,r){this.queue.push({assetId:t,newImageUrl:o,filename:r,retryCount:0})}async processTask(t){try{await $(t.assetId,t.newImageUrl,this.config.apiToken,this.config.environment,t.filename,t.retryCount,this.config.initialRetryDelay,this.config.maxRetryDelay,this.config.retryBackoffFactor),this.completedCount++}catch(o){console.error(`Failed to replace asset ${t.assetId} after multiple retries:`,o),this.failedCount++}finally{this.activeCount--,this.processQueue()}}processQueue(){if(this.queue.length===0&&this.activeCount===0&&this.resolvePromise){this.resolvePromise({succeeded:this.completedCount,failed:this.failedCount}),this.resolvePromise=null,this.processing=!1;return}for(;this.queue.length>0&&this.activeCount<(this.config.concurrency||3);){const t=this.queue.shift();t&&(this.activeCount++,this.processTask(t))}}start(){return this.processing?Promise.reject(new Error("Asset replacer is already processing")):(this.processing=!0,this.completedCount=0,this.failedCount=0,new Promise(t=>{this.resolvePromise=t,this.processQueue()}))}getStatus(){return{queued:this.queue.length,active:this.activeCount,completed:this.completedCount,failed:this.failedCount}}}export{v as AssetReplacer,$ as default};