s3it 1.1.1 → 1.1.2
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.js +6 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{basename as h,extname as u}from"node:path";import{randomUUID as
|
|
2
|
+
import{basename as h,extname as u}from"node:path";import{randomUUID as p,createHash as f,createHmac as Y}from"node:crypto";import{promises as C}from"node:fs";var M=process.env.S3_ENDPOINT||"https://s3.reily.app",z=process.env.S3_BUCKET||"public",O=process.env.S3_ACCESS_KEY||"bhEJaGR0UGgmZtxEi2yY",D=process.env.S3_SECRET_KEY||"lE1fn0FdAAhQwFLnumJt0th0Q2j684h4v8EIQdzy",U=process.env.S3_REGION||"auto",n=104857600,R=104857600;function i(j,V,w,J){let X=Y("sha256",`AWS4${j}`).update(V).digest(),W=Y("sha256",X).update(w).digest(),$=Y("sha256",W).update(J).digest();return Y("sha256",$).update("aws4_request").digest()}function k(j,V,w,J,X,W,$){let Z=new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),G=Z.slice(0,8),L=V.pathname,b=new URLSearchParams(V.search),K=Array.from(b.entries()).sort((x,q)=>x[0].localeCompare(q[0])).map(([x,q])=>`${encodeURIComponent(x)}=${encodeURIComponent(q)}`).join("&"),A=f("sha256").update(typeof J==="string"?J:J).digest("hex"),v={};for(let[x,q]of Object.entries(w))v[x.toLowerCase()]=q;v.host=V.host,v["x-amz-date"]=Z,v["x-amz-content-sha256"]=A;let H=Object.keys(v).sort(),_=H.map((x)=>`${x}:${v[x].trim()}`).join(`
|
|
3
3
|
`)+`
|
|
4
|
-
`,N=H.join(";"),E=[j,
|
|
5
|
-
`),T="AWS4-HMAC-SHA256",y=`${
|
|
6
|
-
`),c=i(W,
|
|
7
|
-
`);let Q=await l(W,$),
|
|
8
|
-
`);let
|
|
4
|
+
`,N=H.join(";"),E=[j,L,K,_,N,A].join(`
|
|
5
|
+
`),T="AWS4-HMAC-SHA256",y=`${G}/${$}/s3/aws4_request`,P=[T,Z,y,f("sha256").update(E).digest("hex")].join(`
|
|
6
|
+
`),c=i(W,G,$,"s3"),m=Y("sha256",c).update(P).digest("hex"),S=`${T} Credential=${X}/${y}, SignedHeaders=${N}, Signature=${m}`,B={};for(let[x,q]of Object.entries(w))B[x]=q;return B.Host=V.host,B["X-Amz-Date"]=Z,B["X-Amz-Content-Sha256"]=A,B.Authorization=S,B}function o(j){let V=u(j).toLowerCase();return{".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".bmp":"image/bmp",".ico":"image/x-icon",".tiff":"image/tiff",".tif":"image/tiff",".avif":"image/avif",".heic":"image/heic",".heif":"image/heif",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".html":"text/html",".htm":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".json":"application/json",".xml":"application/xml",".csv":"text/csv",".md":"text/markdown",".yaml":"text/yaml",".yml":"text/yaml",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".tgz":"application/gzip",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".flac":"audio/flac",".mp4":"video/mp4",".avi":"video/x-msvideo",".mov":"video/quicktime",".wmv":"video/x-ms-wmv",".webm":"video/webm",".mkv":"video/x-matroska",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/javascript",".py":"text/x-python",".java":"text/x-java",".c":"text/x-c",".cpp":"text/x-c++",".rs":"text/x-rust",".go":"text/x-go",".rb":"text/x-ruby",".php":"text/x-php",".sh":"text/x-shellscript",".sql":"text/x-sql",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".wasm":"application/wasm"}[V]||"application/octet-stream"}async function l(j,V){let w=new URL(`${M}/${z}/${j}?uploads`),J=k("POST",w,{"Content-Type":V},"",O,D,U),X=await fetch(w.toString(),{method:"POST",headers:J});if(!X.ok)throw Error(`Failed to initiate multipart upload: ${X.status}`);let $=(await X.text()).match(/<UploadId>(.+?)<\/UploadId>/);if(!$)throw Error("Failed to parse UploadId");return $[1]}async function d(j,V,w,J){let X=new URL(`${M}/${z}/${j}?partNumber=${w}&uploadId=${encodeURIComponent(V)}`),W=k("PUT",X,{"Content-Length":String(J.length)},J,O,D,U),$=await fetch(X.toString(),{method:"PUT",headers:W,body:J});if(!$.ok)throw Error(`Failed to upload part ${w}: ${$.status}`);let F=$.headers.get("ETag");if(!F)throw Error(`No ETag for part ${w}`);return F}async function s(j,V,w){let J=new URL(`${M}/${z}/${j}?uploadId=${encodeURIComponent(V)}`),W=`<?xml version="1.0" encoding="UTF-8"?><CompleteMultipartUpload>${w.map((Q)=>`<Part><PartNumber>${Q.partNumber}</PartNumber><ETag>${Q.etag}</ETag></Part>`).join("")}</CompleteMultipartUpload>`,$=k("POST",J,{"Content-Type":"application/xml"},W,O,D,U),F=await fetch(J.toString(),{method:"POST",headers:$,body:W});if(!F.ok)throw Error(`Failed to complete multipart upload: ${F.status}`)}async function r(j,V){let w=new URL(`${M}/${z}/${j}?uploadId=${encodeURIComponent(V)}`),J=k("DELETE",w,{},"",O,D,U);await fetch(w.toString(),{method:"DELETE",headers:J})}async function t(j,V,w){let J=new URL(`${M}/${z}/${j}`),X=k("PUT",J,{"Content-Type":w,"Content-Length":String(V.length)},V,O,D,U),W=await fetch(J.toString(),{method:"PUT",headers:X,body:V});if(!W.ok)throw Error(`Upload failed: ${W.status}`)}async function a(j,V,w){let J=await C.open(j,"r");try{let X=Buffer.alloc(w),{bytesRead:W}=await J.read(X,0,w,V);return X.subarray(0,W)}finally{await J.close()}}async function e(j){try{await C.access(j)}catch{throw Error(`File not found: ${j}`)}let w=(await C.stat(j)).size,J=p(),X=h(j),W=`${J}/${X}`,$=o(j);if(w<=n){let Q=await C.readFile(j);await t(W,Q,$)}else{process.stderr.write(`Uploading ${(w/1024/1024).toFixed(1)}MB...
|
|
7
|
+
`);let Q=await l(W,$),Z=[];try{let G=Math.ceil(w/R);for(let L=1;L<=G;L++){let b=(L-1)*R,I=Math.min(R,w-b);process.stderr.write(`Part ${L}/${G}
|
|
8
|
+
`);let K=await a(j,b,I),A=await d(W,Q,L,K);Z.push({partNumber:L,etag:A})}await s(W,Q,Z)}catch(G){throw await r(W,Q),G}}let F=W.split("/").map((Q)=>encodeURIComponent(Q)).join("/");return`${M}/${z}/${F}`}var g=process.argv[2];if(!g)console.error("Usage: s3it <file>"),process.exit(1);e(g).then((j)=>console.log(j)).catch((j)=>{console.error(j.message),process.exit(1)});
|