deepagents-s3-backend 1.8.0
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/LICENSE +7 -0
- package/README.md +20 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +220 -0
- package/coverage/coverage-final.json +2 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +116 -0
- package/coverage/index.ts.html +2317 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +107 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
- package/src/index.test.ts +1819 -0
- package/src/index.ts +788 -0
- package/tsconfig.json +8 -0
- package/tsdown.config.ts +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);
|
|
Binary file
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
var addSorting = (function() {
|
|
3
|
+
'use strict';
|
|
4
|
+
var cols,
|
|
5
|
+
currentSort = {
|
|
6
|
+
index: 0,
|
|
7
|
+
desc: false
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// returns the summary table element
|
|
11
|
+
function getTable() {
|
|
12
|
+
return document.querySelector('.coverage-summary');
|
|
13
|
+
}
|
|
14
|
+
// returns the thead element of the summary table
|
|
15
|
+
function getTableHeader() {
|
|
16
|
+
return getTable().querySelector('thead tr');
|
|
17
|
+
}
|
|
18
|
+
// returns the tbody element of the summary table
|
|
19
|
+
function getTableBody() {
|
|
20
|
+
return getTable().querySelector('tbody');
|
|
21
|
+
}
|
|
22
|
+
// returns the th element for nth column
|
|
23
|
+
function getNthColumn(n) {
|
|
24
|
+
return getTableHeader().querySelectorAll('th')[n];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function onFilterInput() {
|
|
28
|
+
const searchValue = document.getElementById('fileSearch').value;
|
|
29
|
+
const rows = document.getElementsByTagName('tbody')[0].children;
|
|
30
|
+
|
|
31
|
+
// Try to create a RegExp from the searchValue. If it fails (invalid regex),
|
|
32
|
+
// it will be treated as a plain text search
|
|
33
|
+
let searchRegex;
|
|
34
|
+
try {
|
|
35
|
+
searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive
|
|
36
|
+
} catch (error) {
|
|
37
|
+
searchRegex = null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < rows.length; i++) {
|
|
41
|
+
const row = rows[i];
|
|
42
|
+
let isMatch = false;
|
|
43
|
+
|
|
44
|
+
if (searchRegex) {
|
|
45
|
+
// If a valid regex was created, use it for matching
|
|
46
|
+
isMatch = searchRegex.test(row.textContent);
|
|
47
|
+
} else {
|
|
48
|
+
// Otherwise, fall back to the original plain text search
|
|
49
|
+
isMatch = row.textContent
|
|
50
|
+
.toLowerCase()
|
|
51
|
+
.includes(searchValue.toLowerCase());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
row.style.display = isMatch ? '' : 'none';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// loads the search box
|
|
59
|
+
function addSearchBox() {
|
|
60
|
+
var template = document.getElementById('filterTemplate');
|
|
61
|
+
var templateClone = template.content.cloneNode(true);
|
|
62
|
+
templateClone.getElementById('fileSearch').oninput = onFilterInput;
|
|
63
|
+
template.parentElement.appendChild(templateClone);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// loads all columns
|
|
67
|
+
function loadColumns() {
|
|
68
|
+
var colNodes = getTableHeader().querySelectorAll('th'),
|
|
69
|
+
colNode,
|
|
70
|
+
cols = [],
|
|
71
|
+
col,
|
|
72
|
+
i;
|
|
73
|
+
|
|
74
|
+
for (i = 0; i < colNodes.length; i += 1) {
|
|
75
|
+
colNode = colNodes[i];
|
|
76
|
+
col = {
|
|
77
|
+
key: colNode.getAttribute('data-col'),
|
|
78
|
+
sortable: !colNode.getAttribute('data-nosort'),
|
|
79
|
+
type: colNode.getAttribute('data-type') || 'string'
|
|
80
|
+
};
|
|
81
|
+
cols.push(col);
|
|
82
|
+
if (col.sortable) {
|
|
83
|
+
col.defaultDescSort = col.type === 'number';
|
|
84
|
+
colNode.innerHTML =
|
|
85
|
+
colNode.innerHTML + '<span class="sorter"></span>';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return cols;
|
|
89
|
+
}
|
|
90
|
+
// attaches a data attribute to every tr element with an object
|
|
91
|
+
// of data values keyed by column name
|
|
92
|
+
function loadRowData(tableRow) {
|
|
93
|
+
var tableCols = tableRow.querySelectorAll('td'),
|
|
94
|
+
colNode,
|
|
95
|
+
col,
|
|
96
|
+
data = {},
|
|
97
|
+
i,
|
|
98
|
+
val;
|
|
99
|
+
for (i = 0; i < tableCols.length; i += 1) {
|
|
100
|
+
colNode = tableCols[i];
|
|
101
|
+
col = cols[i];
|
|
102
|
+
val = colNode.getAttribute('data-value');
|
|
103
|
+
if (col.type === 'number') {
|
|
104
|
+
val = Number(val);
|
|
105
|
+
}
|
|
106
|
+
data[col.key] = val;
|
|
107
|
+
}
|
|
108
|
+
return data;
|
|
109
|
+
}
|
|
110
|
+
// loads all row data
|
|
111
|
+
function loadData() {
|
|
112
|
+
var rows = getTableBody().querySelectorAll('tr'),
|
|
113
|
+
i;
|
|
114
|
+
|
|
115
|
+
for (i = 0; i < rows.length; i += 1) {
|
|
116
|
+
rows[i].data = loadRowData(rows[i]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// sorts the table using the data for the ith column
|
|
120
|
+
function sortByIndex(index, desc) {
|
|
121
|
+
var key = cols[index].key,
|
|
122
|
+
sorter = function(a, b) {
|
|
123
|
+
a = a.data[key];
|
|
124
|
+
b = b.data[key];
|
|
125
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
126
|
+
},
|
|
127
|
+
finalSorter = sorter,
|
|
128
|
+
tableBody = document.querySelector('.coverage-summary tbody'),
|
|
129
|
+
rowNodes = tableBody.querySelectorAll('tr'),
|
|
130
|
+
rows = [],
|
|
131
|
+
i;
|
|
132
|
+
|
|
133
|
+
if (desc) {
|
|
134
|
+
finalSorter = function(a, b) {
|
|
135
|
+
return -1 * sorter(a, b);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for (i = 0; i < rowNodes.length; i += 1) {
|
|
140
|
+
rows.push(rowNodes[i]);
|
|
141
|
+
tableBody.removeChild(rowNodes[i]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
rows.sort(finalSorter);
|
|
145
|
+
|
|
146
|
+
for (i = 0; i < rows.length; i += 1) {
|
|
147
|
+
tableBody.appendChild(rows[i]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// removes sort indicators for current column being sorted
|
|
151
|
+
function removeSortIndicators() {
|
|
152
|
+
var col = getNthColumn(currentSort.index),
|
|
153
|
+
cls = col.className;
|
|
154
|
+
|
|
155
|
+
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
|
|
156
|
+
col.className = cls;
|
|
157
|
+
}
|
|
158
|
+
// adds sort indicators for current column being sorted
|
|
159
|
+
function addSortIndicators() {
|
|
160
|
+
getNthColumn(currentSort.index).className += currentSort.desc
|
|
161
|
+
? ' sorted-desc'
|
|
162
|
+
: ' sorted';
|
|
163
|
+
}
|
|
164
|
+
// adds event listeners for all sorter widgets
|
|
165
|
+
function enableUI() {
|
|
166
|
+
var i,
|
|
167
|
+
el,
|
|
168
|
+
ithSorter = function ithSorter(i) {
|
|
169
|
+
var col = cols[i];
|
|
170
|
+
|
|
171
|
+
return function() {
|
|
172
|
+
var desc = col.defaultDescSort;
|
|
173
|
+
|
|
174
|
+
if (currentSort.index === i) {
|
|
175
|
+
desc = !currentSort.desc;
|
|
176
|
+
}
|
|
177
|
+
sortByIndex(i, desc);
|
|
178
|
+
removeSortIndicators();
|
|
179
|
+
currentSort.index = i;
|
|
180
|
+
currentSort.desc = desc;
|
|
181
|
+
addSortIndicators();
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
for (i = 0; i < cols.length; i += 1) {
|
|
185
|
+
if (cols[i].sortable) {
|
|
186
|
+
// add the click event handler on the th so users
|
|
187
|
+
// dont have to click on those tiny arrows
|
|
188
|
+
el = getNthColumn(i).querySelector('.sorter').parentElement;
|
|
189
|
+
if (el.addEventListener) {
|
|
190
|
+
el.addEventListener('click', ithSorter(i));
|
|
191
|
+
} else {
|
|
192
|
+
el.attachEvent('onclick', ithSorter(i));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// adds sorting functionality to the UI
|
|
198
|
+
return function() {
|
|
199
|
+
if (!getTable()) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
cols = loadColumns();
|
|
203
|
+
loadData();
|
|
204
|
+
addSearchBox();
|
|
205
|
+
addSortIndicators();
|
|
206
|
+
enableUI();
|
|
207
|
+
};
|
|
208
|
+
})();
|
|
209
|
+
|
|
210
|
+
window.addEventListener('load', addSorting);
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`@aws-sdk/client-s3`),l=require(`micromatch`);l=s(l);var u=class{s3Client;bucketName;cwd;maxFileSizeBytes;getErrorMessage(e,t){return e instanceof Error&&e.message?e.message:typeof e==`string`&&e.length>0?e:t}constructor(e={}){if(this.s3Client=new c.S3Client(e?.s3ClientConfig||{}),this.cwd=e?.rootPrefix||`/`,this.maxFileSizeBytes=e?.maxFileSizeMb?e?.maxFileSizeMb*1024*1024:void 0,e?.bucketName)this.bucketName=e.bucketName;else throw Error(`bucketName is required in options`)}resolvePath(e){if(typeof e!=`string`)throw Error(`Path must be a string`);let t=e.replace(/\\/g,`/`);if(t.includes(`\0`))throw Error(`Path contains invalid characters`);let n=this.cwd.replace(/\\/g,`/`).split(`/`).filter(Boolean);for(let e of n)if(e===`.`||e===`..`)throw Error(`Invalid rootPrefix; path traversal is not allowed`);let r=t.split(`/`).filter(e=>e.length>0&&e!==`.`);for(let e of r){if(e===`..`)throw Error(`Path traversal is not allowed`);if(e===`~`||e.startsWith(`~`))throw Error(`Home-relative paths are not allowed`);if(e.includes(`\0`))throw Error(`Path contains invalid characters`)}return`/${[...n,...r].join(`/`)}`}async lsInfo(e){try{let t=this.resolvePath(e),n=t===`/`?``:`${t.slice(1).replace(/\/+$/,``)}/`,r=await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:n,Delimiter:`/`}),i=(r.Contents||[]).filter(e=>{let t=e.Key||``;if(!t.startsWith(n))return!1;let r=t.slice(n.length);return r.length>0&&!r.includes(`/`)}).map(e=>({path:`/${e.Key}`,is_dir:!1,size:e.Size,modified_at:e.LastModified?.toISOString()})),a=(r.CommonPrefixes||[]).map(e=>e.Prefix||``).filter(e=>{if(!e.startsWith(n))return!1;let t=e.slice(n.length).replace(/\/+$/,``);return t.length>0&&!t.includes(`/`)}).map(e=>({path:`/${e}`,is_dir:!0,size:void 0,modified_at:void 0}));return[...i,...a]}catch{return[]}}async read(e,t=0,n=500){try{return(await this.readRaw(e)).content.slice(t,t+n).map((e,n)=>`${t+n+1}: ${e}`).join(`
|
|
2
|
+
`)}catch(e){return this.getErrorMessage(e,`Unknown error during read operation`)}}async readRaw(e){try{let t=this.resolvePath(e),[n,r]=await Promise.all([this.s3Client.send(new c.GetObjectCommand({Bucket:this.bucketName,Key:t.slice(1)})),this.s3Client.send(new c.HeadObjectCommand({Bucket:this.bucketName,Key:t.slice(1)}))]);if(!n.Body)return{content:[],created_at:``,modified_at:``};let i={size:r.ContentLength,created_at:r.Metadata?.CreatedAt||r.LastModified?.toISOString()||``,modified_at:r.LastModified?.toISOString()||``},a=n.Body.getReader(),o=new TextDecoder(`utf-8`),s=``,l=!1;for(;!l;){let{value:e,done:t}=await a.read();e&&(s+=o.decode(e,{stream:!0})),l=t}return s+=o.decode(),{content:s.split(/\r?\n/),created_at:i.created_at,modified_at:i.modified_at}}catch(e){return{content:[this.getErrorMessage(e,`Unknown error during readRaw operation`)],created_at:``,modified_at:``}}}async grepRaw(e,t,n){try{let r=t?this.resolvePath(t):this.cwd,i=r===`/`?``:r.slice(1).replace(/^\/+/,``).replace(/\/+$/,``),a=((await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:i})).Contents||[]).filter(e=>{let t=e.Key||``;return t?n?this.matchesGlob(t,i,n):!0:!1}).filter(e=>!this.maxFileSizeBytes||e.Size===void 0?!0:e.Size<=this.maxFileSizeBytes);return(await Promise.all(a.map(async t=>{let n=t.Key;if(!n)return[];try{let t=await this.s3Client.send(new c.GetObjectCommand({Bucket:this.bucketName,Key:n}));if(!t.Body)return[];let r=(await t.Body.transformToString()).split(/\r?\n/),i=[];for(let t=0;t<r.length;t++){let a=r[t];a.includes(e)&&i.push({path:`/${n}`,line:t+1,text:a})}return i}catch{return[]}}))).flat()}catch(e){return this.getErrorMessage(e,`Unknown error during grep operation`)}}matchesGlob(e,t,n){let r=t&&e.startsWith(t)?e.slice(t.length).replace(/^\/+/,``):e,i=e.split(`/`).pop()||e;return l.isMatch(r,n,{dot:!0})||l.isMatch(i,n,{dot:!0})||l.isMatch(e,n,{dot:!0})}async globInfo(e,t){try{let n=this.resolvePath(t??`/`),r=n===`/`?``:n.slice(1).replace(/^\/+/,``).replace(/\/+$/,``);return((await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:r})).Contents||[]).filter(t=>{let n=t.Key||``;return!n||n.endsWith(`/`)?!1:this.matchesGlob(n,r,e)}).map(e=>({path:`/${e.Key}`,is_dir:!1,size:e.Size,modified_at:e.LastModified?.toISOString()}))}catch(e){return[{path:this.getErrorMessage(e,`Unknown error during glob operation`),is_dir:!1,size:void 0,modified_at:void 0}]}}async write(e,t){try{let n=this.resolvePath(e);if((await this.s3Client.send(new c.GetObjectCommand({Bucket:this.bucketName,Key:n.slice(1)}))).Body)return{error:`File already exists at path: ${n}`};let r=new Date().toISOString();return await this.s3Client.send(new c.PutObjectCommand({Bucket:this.bucketName,Key:n.slice(1),Body:t,Metadata:{CreatedAt:r}})),{path:n,filesUpdate:null}}catch(e){return{error:this.getErrorMessage(e,`Unknown error during write operation`)}}}async edit(e,t,n,r=!1){try{let i=this.resolvePath(e),a=await this.readRaw(i),o=a.content.join(`
|
|
3
|
+
`);if(!o.includes(t))return{error:`The string "${t}" was not found in the file.`};let s=r?o.split(t).length-1:1,l=r?o.split(t).join(n):o.replace(t,n);return await this.s3Client.send(new c.PutObjectCommand({Bucket:this.bucketName,Key:i.slice(1),Body:l,Metadata:{CreatedAt:a.created_at||new Date().toISOString()}})),{path:i,filesUpdate:null,occurrences:s}}catch(e){return{error:this.getErrorMessage(e,`Unknown error during edit operation`)}}}async uploadFiles(e){let t=[];return await Promise.all(e.map(async([e,n])=>{try{let r=this.resolvePath(e);await this.s3Client.send(new c.PutObjectCommand({Bucket:this.bucketName,Key:r.slice(1),Body:n,Metadata:{CreatedAt:new Date().toISOString()}})),t.push({path:r,error:null})}catch(n){t.push({path:e,error:this.mapError(n)})}})),t}async downloadFiles(e){return await Promise.all(e.map(async e=>{try{let t=this.resolvePath(e),n=await this.s3Client.send(new c.GetObjectCommand({Bucket:this.bucketName,Key:t.slice(1)}));if(!n.Body)return{path:e,content:null,error:`file_not_found`};let r=n.Body,i;if(typeof r.transformToByteArray==`function`)i=await r.transformToByteArray();else if(typeof r.transformToString==`function`)i=new TextEncoder().encode(await r.transformToString(`utf-8`));else if(typeof r.transformToWebStream==`function`){let e=r.transformToWebStream().getReader(),t=[],n=0;for(;;){let{value:r,done:i}=await e.read();if(i)break;let a=r??new Uint8Array;t.push(a),n+=a.length}let a=new Uint8Array(n),o=0;for(let e of t)a.set(e,o),o+=e.length;i=a}else return{path:e,content:null,error:`invalid_path`};return{path:e,content:i,error:null}}catch(t){return{path:e,content:null,error:this.mapError(t)}}}))}mapError(e){let t=e,n=t?.code,r=t?.name,i=t?.message;return n===`NoSuchKey`||n===`ENOENT`||r===`NoSuchKey`||i===`NoSuchKey`?`file_not_found`:n===`AccessDenied`||n===`Forbidden`||n===`EACCES`||r===`AccessDenied`||i===`AccessDenied`||i===`Forbidden`?`permission_denied`:n===`EISDIR`||i===`EISDIR`?`is_directory`:`invalid_path`}async dangerouslyListAllObjects(e){let t=!0,n,r=[],i=[],a,o,s,l;for(;t;){let u=await this.s3Client.send(new c.ListObjectsV2Command({...e,ContinuationToken:n}));a===void 0&&u.Name!==void 0&&(a=u.Name),o===void 0&&u.Prefix!==void 0&&(o=u.Prefix),s===void 0&&u.Delimiter!==void 0&&(s=u.Delimiter),l===void 0&&u.MaxKeys!==void 0&&(l=u.MaxKeys),u.Contents?.length&&r.push(...u.Contents),u.CommonPrefixes?.length&&i.push(...u.CommonPrefixes),t=u.IsTruncated===!0,n=u.NextContinuationToken}return{Name:a,Prefix:o??e.Prefix,Delimiter:s??e.Delimiter,MaxKeys:l??e.MaxKeys,Contents:r,CommonPrefixes:i}}};exports.S3Backend=u;
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["S3Client","GetObjectCommand","HeadObjectCommand","m","PutObjectCommand","ListObjectsV2Command"],"sources":["../src/index.ts"],"sourcesContent":["import {\n S3Client,\n ListObjectsV2Command,\n ListObjectsV2CommandInput,\n GetObjectCommand,\n HeadObjectCommand,\n _Object,\n ListObjectsV2CommandOutput,\n PutObjectCommand,\n} from \"@aws-sdk/client-s3\";\nimport type { NodeJsRuntimeStreamingBlobPayloadOutputTypes } from \"@smithy/types\";\nimport {\n EditResult,\n FileData,\n FileDownloadResponse,\n FileInfo,\n FileUploadResponse,\n GrepMatch,\n WriteResult,\n BackendProtocol,\n} from \"deepagents\";\nimport * as m from \"micromatch\";\n\nexport class S3Backend implements BackendProtocol {\n private s3Client: S3Client;\n protected bucketName: string;\n protected cwd: string;\n private maxFileSizeBytes: number | undefined;\n\n private getErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message) {\n return error.message;\n }\n\n if (typeof error === \"string\" && error.length > 0) {\n return error;\n }\n\n return fallback;\n }\n\n constructor(\n options: {\n s3ClientConfig?: ConstructorParameters<typeof S3Client>;\n bucketName?: string;\n rootPrefix?: string;\n maxFileSizeMb?: number;\n } = {},\n ) {\n this.s3Client = new S3Client(options?.s3ClientConfig || {});\n this.cwd = options?.rootPrefix || \"/\";\n this.maxFileSizeBytes = options?.maxFileSizeMb\n ? options?.maxFileSizeMb * 1024 * 1024\n : undefined;\n\n if (!options?.bucketName) {\n throw new Error(\"bucketName is required in options\");\n } else {\n this.bucketName = options.bucketName;\n }\n }\n\n /**\n * Resolve a path with security checks. This behaves similarly to the original\n * `resolvePath` in the `FilesystemBackend`, but it always act in virtual mode.\n *\n * @param key - The S3 object key to resolve. It should be an absolute path starting with /, but if not, it will be treated as relative to the root.\n * @returns Resolve the key to a normalized S3 object key.\n * @throws Error if the key contains path traversal patterns or is invalid.\n */\n private resolvePath(key: string): string {\n if (typeof key !== \"string\") {\n throw new Error(\"Path must be a string\");\n }\n\n const normalizedInput = key.replace(/\\\\/g, \"/\");\n if (normalizedInput.includes(\"\\0\")) {\n throw new Error(\"Path contains invalid characters\");\n }\n\n const rootSegments = this.cwd\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter(Boolean);\n\n for (const segment of rootSegments) {\n if (segment === \".\" || segment === \"..\") {\n throw new Error(\"Invalid rootPrefix; path traversal is not allowed\");\n }\n }\n\n const inputSegments = normalizedInput\n .split(\"/\")\n .filter((segment) => segment.length > 0 && segment !== \".\");\n\n for (const segment of inputSegments) {\n if (segment === \"..\") {\n throw new Error(\"Path traversal is not allowed\");\n }\n\n if (segment === \"~\" || segment.startsWith(\"~\")) {\n throw new Error(\"Home-relative paths are not allowed\");\n }\n\n if (segment.includes(\"\\0\")) {\n throw new Error(\"Path contains invalid characters\");\n }\n }\n\n const fullPathSegments = [...rootSegments, ...inputSegments];\n return `/${fullPathSegments.join(\"/\")}`;\n }\n\n /**\n * List files and directories in the specified directory (non-recursive).\n *\n * @param dirPath - Absolute directory path to list files from\n * @returns List of FileInfo objects for files and directories directly in the directory.\n * Directories have a trailing / in their path and is_dir=true.\n */\n async lsInfo(dirPath: string): Promise<FileInfo[]> {\n try {\n const resolvedPath = this.resolvePath(dirPath);\n const listPrefix =\n resolvedPath === \"/\"\n ? \"\"\n : `${resolvedPath.slice(1).replace(/\\/+$/, \"\")}/`;\n const result = await this.dangerouslyListAllObjects({\n Bucket: this.bucketName,\n Prefix: listPrefix,\n Delimiter: \"/\",\n });\n\n const directFiles = (result.Contents || [])\n .filter((obj) => {\n const key = obj.Key || \"\";\n if (!key.startsWith(listPrefix)) {\n return false;\n }\n\n const relativeKey = key.slice(listPrefix.length);\n return relativeKey.length > 0 && !relativeKey.includes(\"/\");\n })\n .map((obj) => ({\n path: `/${obj.Key}`,\n is_dir: false,\n size: obj.Size,\n modified_at: obj.LastModified?.toISOString(),\n }));\n\n const directDirectories = (result.CommonPrefixes || [])\n .map((prefix) => prefix.Prefix || \"\")\n .filter((prefix) => {\n if (!prefix.startsWith(listPrefix)) {\n return false;\n }\n\n const relativePrefix = prefix\n .slice(listPrefix.length)\n .replace(/\\/+$/, \"\");\n\n return relativePrefix.length > 0 && !relativePrefix.includes(\"/\");\n })\n .map(\n (prefix) =>\n ({\n path: `/${prefix}`,\n is_dir: true,\n size: undefined,\n modified_at: undefined,\n }) as FileInfo,\n );\n\n return [...directFiles, ...directDirectories];\n } catch {\n return [];\n }\n }\n\n /**\n * Read file content with line numbers.\n *\n * @param filePath - Absolute or relative file path\n * @param offset - Line offset to start reading from (0-indexed)\n * @param limit - Maximum number of lines to read\n * @returns Formatted file content with line numbers, or error message\n */\n async read(\n filePath: string,\n offset: number = 0,\n limit: number = 500,\n ): Promise<string> {\n try {\n const fileData = await this.readRaw(filePath);\n const selectedLines = fileData.content.slice(offset, offset + limit);\n return selectedLines\n .map((line, index) => `${offset + index + 1}: ${line}`)\n .join(\"\\n\");\n } catch (error) {\n return this.getErrorMessage(error, \"Unknown error during read operation\");\n }\n }\n\n /**\n * Read file content as raw FileData.\n *\n * @param filePath - Absolute file path\n * @returns Raw file content as FileData\n */\n async readRaw(filePath: string): Promise<FileData> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n const [getObjectResult, headObjectResult] = await Promise.all([\n this.s3Client.send(\n new GetObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n }),\n ),\n this.s3Client.send(\n new HeadObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n }),\n ),\n ]);\n\n if (!getObjectResult.Body) {\n return { content: [], created_at: \"\", modified_at: \"\" };\n }\n\n const headInfo = {\n size: headObjectResult.ContentLength,\n created_at:\n headObjectResult.Metadata?.CreatedAt ||\n headObjectResult.LastModified?.toISOString() ||\n \"\",\n modified_at: headObjectResult.LastModified?.toISOString() || \"\",\n };\n\n const stream = getObjectResult.Body as ReadableStream;\n const reader = stream.getReader();\n const decoder = new TextDecoder(\"utf-8\");\n let content = \"\";\n let done = false;\n\n while (!done) {\n const { value, done: streamDone } = await reader.read();\n if (value) {\n content += decoder.decode(value, { stream: true });\n }\n done = streamDone;\n }\n\n content += decoder.decode();\n\n const lines = content.split(/\\r?\\n/);\n\n return {\n content: lines,\n created_at: headInfo.created_at,\n modified_at: headInfo.modified_at,\n };\n } catch (error) {\n return {\n content: [\n this.getErrorMessage(error, \"Unknown error during readRaw operation\"),\n ],\n created_at: \"\",\n modified_at: \"\",\n };\n }\n }\n\n /**\n * Search for a literal text pattern in files (recursive).\n *\n * @param pattern - Literal string to search for (NOT regex).\n * @param dirPath - Directory or file path to search in. Defaults to current directory.\n * @param glob - Optional glob pattern to filter which files to search.\n * @returns List of GrepMatch dicts containing path, line number, and matched text.\n */\n async grepRaw(\n pattern: string,\n dirPath?: string | null,\n glob?: string | null,\n ): Promise<GrepMatch[] | string> {\n try {\n const searchPath = dirPath ? this.resolvePath(dirPath) : this.cwd;\n const prefix =\n searchPath === \"/\"\n ? \"\"\n : searchPath.slice(1).replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n\n const listedObjects = await this.dangerouslyListAllObjects({\n Bucket: this.bucketName,\n Prefix: prefix,\n });\n\n const matchingObjects = (listedObjects.Contents || [])\n .filter((obj) => {\n const key = obj.Key || \"\";\n if (!key) {\n return false;\n }\n\n if (!glob) {\n return true;\n }\n\n return this.matchesGlob(key, prefix, glob);\n })\n .filter((obj) => {\n if (!this.maxFileSizeBytes || obj.Size === undefined) {\n return true;\n }\n\n return obj.Size <= this.maxFileSizeBytes;\n });\n\n const objectMatches = await Promise.all(\n matchingObjects.map(async (obj) => {\n const key = obj.Key;\n if (!key) {\n return [] as GrepMatch[];\n }\n\n try {\n const getObjectResult = await this.s3Client.send(\n new GetObjectCommand({\n Bucket: this.bucketName,\n Key: key,\n }),\n );\n\n if (!getObjectResult.Body) {\n return [] as GrepMatch[];\n }\n\n const content = await getObjectResult.Body.transformToString();\n const lines = content.split(/\\r?\\n/);\n const fileMatches: GrepMatch[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line.includes(pattern)) {\n continue;\n }\n\n fileMatches.push({\n path: `/${key}`,\n line: i + 1,\n text: line,\n });\n }\n\n return fileMatches;\n } catch {\n return [] as GrepMatch[];\n }\n }),\n );\n\n return objectMatches.flat();\n } catch (error) {\n return this.getErrorMessage(error, \"Unknown error during grep operation\");\n }\n }\n\n private matchesGlob(\n key: string,\n prefix: string,\n globPattern: string,\n ): boolean {\n const relativeToPrefix =\n prefix && key.startsWith(prefix)\n ? key.slice(prefix.length).replace(/^\\/+/, \"\")\n : key;\n const fileName = key.split(\"/\").pop() || key;\n\n return (\n m.isMatch(relativeToPrefix, globPattern, { dot: true }) ||\n m.isMatch(fileName, globPattern, { dot: true }) ||\n m.isMatch(key, globPattern, { dot: true })\n );\n }\n\n /**\n * Structured glob matching returning FileInfo objects.\n *\n * @param pattern - Glob pattern (e.g., `*.py`, `**\\/*.ts`)\n * @param path - Base path to search from (default: \"/\")\n * @returns List of FileInfo objects matching the pattern\n */\n async globInfo(pattern: string, path?: string): Promise<FileInfo[]> {\n try {\n const searchPath = this.resolvePath(path ?? \"/\");\n const prefix =\n searchPath === \"/\"\n ? \"\"\n : searchPath.slice(1).replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n\n const listedObjects = await this.dangerouslyListAllObjects({\n Bucket: this.bucketName,\n Prefix: prefix,\n });\n\n return (listedObjects.Contents || [])\n .filter((obj) => {\n const key = obj.Key || \"\";\n if (!key || key.endsWith(\"/\")) {\n return false;\n }\n\n return this.matchesGlob(key, prefix, pattern);\n })\n .map((obj) => ({\n path: `/${obj.Key}`,\n is_dir: false,\n size: obj.Size,\n modified_at: obj.LastModified?.toISOString(),\n }));\n } catch (error) {\n return [\n {\n path: this.getErrorMessage(\n error,\n \"Unknown error during glob operation\",\n ),\n is_dir: false,\n size: undefined,\n modified_at: undefined,\n },\n ];\n }\n }\n\n /**\n * Create a new file.\n *\n * @param filePath - Absolute file path\n * @param content - File content as string\n * @returns WriteResult with error populated on failure\n */\n async write(filePath: string, content: string): Promise<WriteResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n\n const getObjectResult = await this.s3Client.send(\n new GetObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n }),\n );\n\n if (getObjectResult.Body) {\n return {\n error: `File already exists at path: ${resolvedPath}`,\n };\n }\n\n const creationTime = new Date().toISOString();\n await this.s3Client.send(\n new PutObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n Body: content,\n Metadata: {\n CreatedAt: creationTime,\n },\n }),\n );\n\n return {\n path: resolvedPath,\n filesUpdate: null,\n };\n } catch (error) {\n return {\n error: this.getErrorMessage(\n error,\n \"Unknown error during write operation\",\n ),\n };\n }\n }\n\n /**\n * Edit a file by replacing string occurrences.\n *\n * @param filePath - Absolute file path\n * @param oldString - String to find and replace\n * @param newString - Replacement string\n * @param replaceAll - If true, replace all occurrences (default: false)\n * @returns EditResult with error, path, filesUpdate, and occurrences\n */\n async edit(\n filePath: string,\n oldString: string,\n newString: string,\n replaceAll: boolean = false,\n ): Promise<EditResult> {\n try {\n const resolvedPath = this.resolvePath(filePath);\n const fileData = await this.readRaw(resolvedPath);\n const content = fileData.content.join(\"\\n\");\n\n if (!content.includes(oldString)) {\n return {\n error: `The string \"${oldString}\" was not found in the file.`,\n };\n }\n\n const occurrences = replaceAll ? content.split(oldString).length - 1 : 1;\n\n const newContent = replaceAll\n ? content.split(oldString).join(newString)\n : content.replace(oldString, newString);\n\n await this.s3Client.send(\n new PutObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n Body: newContent,\n Metadata: {\n CreatedAt: fileData.created_at || new Date().toISOString(),\n },\n }),\n );\n\n return {\n path: resolvedPath,\n filesUpdate: null,\n occurrences,\n };\n } catch (error) {\n return {\n error: this.getErrorMessage(\n error,\n \"Unknown error during edit operation\",\n ),\n };\n }\n }\n\n /**\n * Upload multiple files.\n * Optional - backends that don't support file upload can omit this.\n *\n * @param files - List of [path, content] tuples to upload\n * @returns List of FileUploadResponse objects, one per input file\n */\n async uploadFiles(\n files: Array<[string, Uint8Array]>,\n ): Promise<FileUploadResponse[]> {\n const uploadResults: FileUploadResponse[] = [];\n\n await Promise.all(\n files.map(async ([filePath, content]) => {\n try {\n const resolvedPath = this.resolvePath(filePath);\n await this.s3Client.send(\n new PutObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n Body: content,\n Metadata: {\n CreatedAt: new Date().toISOString(),\n },\n }),\n );\n\n uploadResults.push({\n path: resolvedPath,\n error: null,\n });\n } catch (error) {\n uploadResults.push({\n path: filePath,\n error: this.mapError(error),\n });\n }\n }),\n );\n\n return uploadResults;\n }\n\n /**\n * Download multiple files.\n * Optional - backends that don't support file download can omit this.\n *\n * @param paths - List of file paths to download\n * @returns List of FileDownloadResponse objects, one per input path\n */\n async downloadFiles(paths: string[]): Promise<FileDownloadResponse[]> {\n const downloadResults = await Promise.all(\n paths.map(async (filePath) => {\n try {\n const resolvedPath = this.resolvePath(filePath);\n const getObjectResult = await this.s3Client.send(\n new GetObjectCommand({\n Bucket: this.bucketName,\n Key: resolvedPath.slice(1),\n }),\n );\n\n if (!getObjectResult.Body) {\n return {\n path: filePath,\n content: null,\n error: \"file_not_found\" as const,\n };\n }\n\n const body =\n getObjectResult.Body as NodeJsRuntimeStreamingBlobPayloadOutputTypes;\n\n let content: Uint8Array;\n\n if (typeof body.transformToByteArray === \"function\") {\n content = await body.transformToByteArray();\n } else if (typeof body.transformToString === \"function\") {\n content = new TextEncoder().encode(\n await body.transformToString(\"utf-8\"),\n );\n } else if (typeof body.transformToWebStream === \"function\") {\n const reader = body.transformToWebStream().getReader();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n break;\n }\n\n const chunk = value ?? new Uint8Array();\n chunks.push(chunk);\n totalLength += chunk.length;\n }\n\n const merged = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n merged.set(chunk, offset);\n offset += chunk.length;\n }\n\n content = merged;\n } else {\n return {\n path: filePath,\n content: null,\n error: \"invalid_path\" as const,\n };\n }\n\n return {\n path: filePath,\n content,\n error: null,\n };\n } catch (error) {\n return {\n path: filePath,\n content: null,\n error: this.mapError(error),\n };\n }\n }),\n );\n\n return downloadResults;\n }\n\n private mapError(\n error: unknown,\n ): FileDownloadResponse[\"error\"] | FileUploadResponse[\"error\"] {\n const candidate = error as {\n name?: string;\n code?: string;\n message?: string;\n };\n const code = candidate?.code;\n const name = candidate?.name;\n const message = candidate?.message;\n\n if (\n code === \"NoSuchKey\" ||\n code === \"ENOENT\" ||\n name === \"NoSuchKey\" ||\n message === \"NoSuchKey\"\n ) {\n return \"file_not_found\";\n }\n\n if (\n code === \"AccessDenied\" ||\n code === \"Forbidden\" ||\n code === \"EACCES\" ||\n name === \"AccessDenied\" ||\n message === \"AccessDenied\" ||\n message === \"Forbidden\"\n ) {\n return \"permission_denied\";\n }\n\n if (code === \"EISDIR\" || message === \"EISDIR\") {\n return \"is_directory\";\n }\n\n return \"invalid_path\";\n }\n\n async dangerouslyListAllObjects(\n param: Omit<ListObjectsV2CommandInput, \"ContinuationToken\">,\n ): Promise<\n Pick<\n ListObjectsV2CommandOutput,\n | \"Name\"\n | \"Contents\"\n | \"CommonPrefixes\"\n | \"Prefix\"\n | \"Delimiter\"\n | \"MaxKeys\"\n >\n > {\n let isTruncated = true;\n let continuationToken: string | undefined;\n\n const allContents: _Object[] = [];\n const allCommonPrefixes: NonNullable<\n ListObjectsV2CommandOutput[\"CommonPrefixes\"]\n > = [];\n\n let name: ListObjectsV2CommandOutput[\"Name\"];\n let prefix: ListObjectsV2CommandOutput[\"Prefix\"];\n let delimiter: ListObjectsV2CommandOutput[\"Delimiter\"];\n let maxKeys: ListObjectsV2CommandOutput[\"MaxKeys\"];\n\n while (isTruncated) {\n const result = await this.s3Client.send(\n new ListObjectsV2Command({\n ...param,\n ContinuationToken: continuationToken,\n }),\n );\n\n if (name === undefined && result.Name !== undefined) {\n name = result.Name;\n }\n\n if (prefix === undefined && result.Prefix !== undefined) {\n prefix = result.Prefix;\n }\n\n if (delimiter === undefined && result.Delimiter !== undefined) {\n delimiter = result.Delimiter;\n }\n\n if (maxKeys === undefined && result.MaxKeys !== undefined) {\n maxKeys = result.MaxKeys;\n }\n\n if (result.Contents?.length) {\n allContents.push(...result.Contents);\n }\n\n if (result.CommonPrefixes?.length) {\n allCommonPrefixes.push(...result.CommonPrefixes);\n }\n\n isTruncated = result.IsTruncated === true;\n continuationToken = result.NextContinuationToken;\n }\n\n return {\n Name: name,\n Prefix: prefix ?? param.Prefix,\n Delimiter: delimiter ?? param.Delimiter,\n MaxKeys: maxKeys ?? param.MaxKeys,\n Contents: allContents,\n CommonPrefixes: allCommonPrefixes,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ListObjectsV2CommandInput, ListObjectsV2CommandOutput, S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
import { BackendProtocol, EditResult, FileData, FileDownloadResponse, FileInfo, FileUploadResponse, GrepMatch, WriteResult } from "deepagents";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
declare class S3Backend implements BackendProtocol {
|
|
6
|
+
private s3Client;
|
|
7
|
+
protected bucketName: string;
|
|
8
|
+
protected cwd: string;
|
|
9
|
+
private maxFileSizeBytes;
|
|
10
|
+
private getErrorMessage;
|
|
11
|
+
constructor(options?: {
|
|
12
|
+
s3ClientConfig?: ConstructorParameters<typeof S3Client>;
|
|
13
|
+
bucketName?: string;
|
|
14
|
+
rootPrefix?: string;
|
|
15
|
+
maxFileSizeMb?: number;
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a path with security checks. This behaves similarly to the original
|
|
19
|
+
* `resolvePath` in the `FilesystemBackend`, but it always act in virtual mode.
|
|
20
|
+
*
|
|
21
|
+
* @param key - The S3 object key to resolve. It should be an absolute path starting with /, but if not, it will be treated as relative to the root.
|
|
22
|
+
* @returns Resolve the key to a normalized S3 object key.
|
|
23
|
+
* @throws Error if the key contains path traversal patterns or is invalid.
|
|
24
|
+
*/
|
|
25
|
+
private resolvePath;
|
|
26
|
+
/**
|
|
27
|
+
* List files and directories in the specified directory (non-recursive).
|
|
28
|
+
*
|
|
29
|
+
* @param dirPath - Absolute directory path to list files from
|
|
30
|
+
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
31
|
+
* Directories have a trailing / in their path and is_dir=true.
|
|
32
|
+
*/
|
|
33
|
+
lsInfo(dirPath: string): Promise<FileInfo[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Read file content with line numbers.
|
|
36
|
+
*
|
|
37
|
+
* @param filePath - Absolute or relative file path
|
|
38
|
+
* @param offset - Line offset to start reading from (0-indexed)
|
|
39
|
+
* @param limit - Maximum number of lines to read
|
|
40
|
+
* @returns Formatted file content with line numbers, or error message
|
|
41
|
+
*/
|
|
42
|
+
read(filePath: string, offset?: number, limit?: number): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Read file content as raw FileData.
|
|
45
|
+
*
|
|
46
|
+
* @param filePath - Absolute file path
|
|
47
|
+
* @returns Raw file content as FileData
|
|
48
|
+
*/
|
|
49
|
+
readRaw(filePath: string): Promise<FileData>;
|
|
50
|
+
/**
|
|
51
|
+
* Search for a literal text pattern in files (recursive).
|
|
52
|
+
*
|
|
53
|
+
* @param pattern - Literal string to search for (NOT regex).
|
|
54
|
+
* @param dirPath - Directory or file path to search in. Defaults to current directory.
|
|
55
|
+
* @param glob - Optional glob pattern to filter which files to search.
|
|
56
|
+
* @returns List of GrepMatch dicts containing path, line number, and matched text.
|
|
57
|
+
*/
|
|
58
|
+
grepRaw(pattern: string, dirPath?: string | null, glob?: string | null): Promise<GrepMatch[] | string>;
|
|
59
|
+
private matchesGlob;
|
|
60
|
+
/**
|
|
61
|
+
* Structured glob matching returning FileInfo objects.
|
|
62
|
+
*
|
|
63
|
+
* @param pattern - Glob pattern (e.g., `*.py`, `**\/*.ts`)
|
|
64
|
+
* @param path - Base path to search from (default: "/")
|
|
65
|
+
* @returns List of FileInfo objects matching the pattern
|
|
66
|
+
*/
|
|
67
|
+
globInfo(pattern: string, path?: string): Promise<FileInfo[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Create a new file.
|
|
70
|
+
*
|
|
71
|
+
* @param filePath - Absolute file path
|
|
72
|
+
* @param content - File content as string
|
|
73
|
+
* @returns WriteResult with error populated on failure
|
|
74
|
+
*/
|
|
75
|
+
write(filePath: string, content: string): Promise<WriteResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Edit a file by replacing string occurrences.
|
|
78
|
+
*
|
|
79
|
+
* @param filePath - Absolute file path
|
|
80
|
+
* @param oldString - String to find and replace
|
|
81
|
+
* @param newString - Replacement string
|
|
82
|
+
* @param replaceAll - If true, replace all occurrences (default: false)
|
|
83
|
+
* @returns EditResult with error, path, filesUpdate, and occurrences
|
|
84
|
+
*/
|
|
85
|
+
edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise<EditResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Upload multiple files.
|
|
88
|
+
* Optional - backends that don't support file upload can omit this.
|
|
89
|
+
*
|
|
90
|
+
* @param files - List of [path, content] tuples to upload
|
|
91
|
+
* @returns List of FileUploadResponse objects, one per input file
|
|
92
|
+
*/
|
|
93
|
+
uploadFiles(files: Array<[string, Uint8Array]>): Promise<FileUploadResponse[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Download multiple files.
|
|
96
|
+
* Optional - backends that don't support file download can omit this.
|
|
97
|
+
*
|
|
98
|
+
* @param paths - List of file paths to download
|
|
99
|
+
* @returns List of FileDownloadResponse objects, one per input path
|
|
100
|
+
*/
|
|
101
|
+
downloadFiles(paths: string[]): Promise<FileDownloadResponse[]>;
|
|
102
|
+
private mapError;
|
|
103
|
+
dangerouslyListAllObjects(param: Omit<ListObjectsV2CommandInput, "ContinuationToken">): Promise<Pick<ListObjectsV2CommandOutput, "Name" | "Contents" | "CommonPrefixes" | "Prefix" | "Delimiter" | "MaxKeys">>;
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { S3Backend };
|
|
107
|
+
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ListObjectsV2CommandInput, ListObjectsV2CommandOutput, S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
import { BackendProtocol, EditResult, FileData, FileDownloadResponse, FileInfo, FileUploadResponse, GrepMatch, WriteResult } from "deepagents";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
declare class S3Backend implements BackendProtocol {
|
|
6
|
+
private s3Client;
|
|
7
|
+
protected bucketName: string;
|
|
8
|
+
protected cwd: string;
|
|
9
|
+
private maxFileSizeBytes;
|
|
10
|
+
private getErrorMessage;
|
|
11
|
+
constructor(options?: {
|
|
12
|
+
s3ClientConfig?: ConstructorParameters<typeof S3Client>;
|
|
13
|
+
bucketName?: string;
|
|
14
|
+
rootPrefix?: string;
|
|
15
|
+
maxFileSizeMb?: number;
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a path with security checks. This behaves similarly to the original
|
|
19
|
+
* `resolvePath` in the `FilesystemBackend`, but it always act in virtual mode.
|
|
20
|
+
*
|
|
21
|
+
* @param key - The S3 object key to resolve. It should be an absolute path starting with /, but if not, it will be treated as relative to the root.
|
|
22
|
+
* @returns Resolve the key to a normalized S3 object key.
|
|
23
|
+
* @throws Error if the key contains path traversal patterns or is invalid.
|
|
24
|
+
*/
|
|
25
|
+
private resolvePath;
|
|
26
|
+
/**
|
|
27
|
+
* List files and directories in the specified directory (non-recursive).
|
|
28
|
+
*
|
|
29
|
+
* @param dirPath - Absolute directory path to list files from
|
|
30
|
+
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
31
|
+
* Directories have a trailing / in their path and is_dir=true.
|
|
32
|
+
*/
|
|
33
|
+
lsInfo(dirPath: string): Promise<FileInfo[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Read file content with line numbers.
|
|
36
|
+
*
|
|
37
|
+
* @param filePath - Absolute or relative file path
|
|
38
|
+
* @param offset - Line offset to start reading from (0-indexed)
|
|
39
|
+
* @param limit - Maximum number of lines to read
|
|
40
|
+
* @returns Formatted file content with line numbers, or error message
|
|
41
|
+
*/
|
|
42
|
+
read(filePath: string, offset?: number, limit?: number): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Read file content as raw FileData.
|
|
45
|
+
*
|
|
46
|
+
* @param filePath - Absolute file path
|
|
47
|
+
* @returns Raw file content as FileData
|
|
48
|
+
*/
|
|
49
|
+
readRaw(filePath: string): Promise<FileData>;
|
|
50
|
+
/**
|
|
51
|
+
* Search for a literal text pattern in files (recursive).
|
|
52
|
+
*
|
|
53
|
+
* @param pattern - Literal string to search for (NOT regex).
|
|
54
|
+
* @param dirPath - Directory or file path to search in. Defaults to current directory.
|
|
55
|
+
* @param glob - Optional glob pattern to filter which files to search.
|
|
56
|
+
* @returns List of GrepMatch dicts containing path, line number, and matched text.
|
|
57
|
+
*/
|
|
58
|
+
grepRaw(pattern: string, dirPath?: string | null, glob?: string | null): Promise<GrepMatch[] | string>;
|
|
59
|
+
private matchesGlob;
|
|
60
|
+
/**
|
|
61
|
+
* Structured glob matching returning FileInfo objects.
|
|
62
|
+
*
|
|
63
|
+
* @param pattern - Glob pattern (e.g., `*.py`, `**\/*.ts`)
|
|
64
|
+
* @param path - Base path to search from (default: "/")
|
|
65
|
+
* @returns List of FileInfo objects matching the pattern
|
|
66
|
+
*/
|
|
67
|
+
globInfo(pattern: string, path?: string): Promise<FileInfo[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Create a new file.
|
|
70
|
+
*
|
|
71
|
+
* @param filePath - Absolute file path
|
|
72
|
+
* @param content - File content as string
|
|
73
|
+
* @returns WriteResult with error populated on failure
|
|
74
|
+
*/
|
|
75
|
+
write(filePath: string, content: string): Promise<WriteResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Edit a file by replacing string occurrences.
|
|
78
|
+
*
|
|
79
|
+
* @param filePath - Absolute file path
|
|
80
|
+
* @param oldString - String to find and replace
|
|
81
|
+
* @param newString - Replacement string
|
|
82
|
+
* @param replaceAll - If true, replace all occurrences (default: false)
|
|
83
|
+
* @returns EditResult with error, path, filesUpdate, and occurrences
|
|
84
|
+
*/
|
|
85
|
+
edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise<EditResult>;
|
|
86
|
+
/**
|
|
87
|
+
* Upload multiple files.
|
|
88
|
+
* Optional - backends that don't support file upload can omit this.
|
|
89
|
+
*
|
|
90
|
+
* @param files - List of [path, content] tuples to upload
|
|
91
|
+
* @returns List of FileUploadResponse objects, one per input file
|
|
92
|
+
*/
|
|
93
|
+
uploadFiles(files: Array<[string, Uint8Array]>): Promise<FileUploadResponse[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Download multiple files.
|
|
96
|
+
* Optional - backends that don't support file download can omit this.
|
|
97
|
+
*
|
|
98
|
+
* @param paths - List of file paths to download
|
|
99
|
+
* @returns List of FileDownloadResponse objects, one per input path
|
|
100
|
+
*/
|
|
101
|
+
downloadFiles(paths: string[]): Promise<FileDownloadResponse[]>;
|
|
102
|
+
private mapError;
|
|
103
|
+
dangerouslyListAllObjects(param: Omit<ListObjectsV2CommandInput, "ContinuationToken">): Promise<Pick<ListObjectsV2CommandOutput, "Name" | "Contents" | "CommonPrefixes" | "Prefix" | "Delimiter" | "MaxKeys">>;
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { S3Backend };
|
|
107
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{GetObjectCommand as e,HeadObjectCommand as t,ListObjectsV2Command as n,PutObjectCommand as r,S3Client as i}from"@aws-sdk/client-s3";import*as a from"micromatch";var o=class{s3Client;bucketName;cwd;maxFileSizeBytes;getErrorMessage(e,t){return e instanceof Error&&e.message?e.message:typeof e==`string`&&e.length>0?e:t}constructor(e={}){if(this.s3Client=new i(e?.s3ClientConfig||{}),this.cwd=e?.rootPrefix||`/`,this.maxFileSizeBytes=e?.maxFileSizeMb?e?.maxFileSizeMb*1024*1024:void 0,e?.bucketName)this.bucketName=e.bucketName;else throw Error(`bucketName is required in options`)}resolvePath(e){if(typeof e!=`string`)throw Error(`Path must be a string`);let t=e.replace(/\\/g,`/`);if(t.includes(`\0`))throw Error(`Path contains invalid characters`);let n=this.cwd.replace(/\\/g,`/`).split(`/`).filter(Boolean);for(let e of n)if(e===`.`||e===`..`)throw Error(`Invalid rootPrefix; path traversal is not allowed`);let r=t.split(`/`).filter(e=>e.length>0&&e!==`.`);for(let e of r){if(e===`..`)throw Error(`Path traversal is not allowed`);if(e===`~`||e.startsWith(`~`))throw Error(`Home-relative paths are not allowed`);if(e.includes(`\0`))throw Error(`Path contains invalid characters`)}return`/${[...n,...r].join(`/`)}`}async lsInfo(e){try{let t=this.resolvePath(e),n=t===`/`?``:`${t.slice(1).replace(/\/+$/,``)}/`,r=await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:n,Delimiter:`/`}),i=(r.Contents||[]).filter(e=>{let t=e.Key||``;if(!t.startsWith(n))return!1;let r=t.slice(n.length);return r.length>0&&!r.includes(`/`)}).map(e=>({path:`/${e.Key}`,is_dir:!1,size:e.Size,modified_at:e.LastModified?.toISOString()})),a=(r.CommonPrefixes||[]).map(e=>e.Prefix||``).filter(e=>{if(!e.startsWith(n))return!1;let t=e.slice(n.length).replace(/\/+$/,``);return t.length>0&&!t.includes(`/`)}).map(e=>({path:`/${e}`,is_dir:!0,size:void 0,modified_at:void 0}));return[...i,...a]}catch{return[]}}async read(e,t=0,n=500){try{return(await this.readRaw(e)).content.slice(t,t+n).map((e,n)=>`${t+n+1}: ${e}`).join(`
|
|
2
|
+
`)}catch(e){return this.getErrorMessage(e,`Unknown error during read operation`)}}async readRaw(n){try{let r=this.resolvePath(n),[i,a]=await Promise.all([this.s3Client.send(new e({Bucket:this.bucketName,Key:r.slice(1)})),this.s3Client.send(new t({Bucket:this.bucketName,Key:r.slice(1)}))]);if(!i.Body)return{content:[],created_at:``,modified_at:``};let o={size:a.ContentLength,created_at:a.Metadata?.CreatedAt||a.LastModified?.toISOString()||``,modified_at:a.LastModified?.toISOString()||``},s=i.Body.getReader(),c=new TextDecoder(`utf-8`),l=``,u=!1;for(;!u;){let{value:e,done:t}=await s.read();e&&(l+=c.decode(e,{stream:!0})),u=t}return l+=c.decode(),{content:l.split(/\r?\n/),created_at:o.created_at,modified_at:o.modified_at}}catch(e){return{content:[this.getErrorMessage(e,`Unknown error during readRaw operation`)],created_at:``,modified_at:``}}}async grepRaw(t,n,r){try{let i=n?this.resolvePath(n):this.cwd,a=i===`/`?``:i.slice(1).replace(/^\/+/,``).replace(/\/+$/,``),o=((await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:a})).Contents||[]).filter(e=>{let t=e.Key||``;return t?r?this.matchesGlob(t,a,r):!0:!1}).filter(e=>!this.maxFileSizeBytes||e.Size===void 0?!0:e.Size<=this.maxFileSizeBytes);return(await Promise.all(o.map(async n=>{let r=n.Key;if(!r)return[];try{let n=await this.s3Client.send(new e({Bucket:this.bucketName,Key:r}));if(!n.Body)return[];let i=(await n.Body.transformToString()).split(/\r?\n/),a=[];for(let e=0;e<i.length;e++){let n=i[e];n.includes(t)&&a.push({path:`/${r}`,line:e+1,text:n})}return a}catch{return[]}}))).flat()}catch(e){return this.getErrorMessage(e,`Unknown error during grep operation`)}}matchesGlob(e,t,n){let r=t&&e.startsWith(t)?e.slice(t.length).replace(/^\/+/,``):e,i=e.split(`/`).pop()||e;return a.isMatch(r,n,{dot:!0})||a.isMatch(i,n,{dot:!0})||a.isMatch(e,n,{dot:!0})}async globInfo(e,t){try{let n=this.resolvePath(t??`/`),r=n===`/`?``:n.slice(1).replace(/^\/+/,``).replace(/\/+$/,``);return((await this.dangerouslyListAllObjects({Bucket:this.bucketName,Prefix:r})).Contents||[]).filter(t=>{let n=t.Key||``;return!n||n.endsWith(`/`)?!1:this.matchesGlob(n,r,e)}).map(e=>({path:`/${e.Key}`,is_dir:!1,size:e.Size,modified_at:e.LastModified?.toISOString()}))}catch(e){return[{path:this.getErrorMessage(e,`Unknown error during glob operation`),is_dir:!1,size:void 0,modified_at:void 0}]}}async write(t,n){try{let i=this.resolvePath(t);if((await this.s3Client.send(new e({Bucket:this.bucketName,Key:i.slice(1)}))).Body)return{error:`File already exists at path: ${i}`};let a=new Date().toISOString();return await this.s3Client.send(new r({Bucket:this.bucketName,Key:i.slice(1),Body:n,Metadata:{CreatedAt:a}})),{path:i,filesUpdate:null}}catch(e){return{error:this.getErrorMessage(e,`Unknown error during write operation`)}}}async edit(e,t,n,i=!1){try{let a=this.resolvePath(e),o=await this.readRaw(a),s=o.content.join(`
|
|
3
|
+
`);if(!s.includes(t))return{error:`The string "${t}" was not found in the file.`};let c=i?s.split(t).length-1:1,l=i?s.split(t).join(n):s.replace(t,n);return await this.s3Client.send(new r({Bucket:this.bucketName,Key:a.slice(1),Body:l,Metadata:{CreatedAt:o.created_at||new Date().toISOString()}})),{path:a,filesUpdate:null,occurrences:c}}catch(e){return{error:this.getErrorMessage(e,`Unknown error during edit operation`)}}}async uploadFiles(e){let t=[];return await Promise.all(e.map(async([e,n])=>{try{let i=this.resolvePath(e);await this.s3Client.send(new r({Bucket:this.bucketName,Key:i.slice(1),Body:n,Metadata:{CreatedAt:new Date().toISOString()}})),t.push({path:i,error:null})}catch(n){t.push({path:e,error:this.mapError(n)})}})),t}async downloadFiles(t){return await Promise.all(t.map(async t=>{try{let n=this.resolvePath(t),r=await this.s3Client.send(new e({Bucket:this.bucketName,Key:n.slice(1)}));if(!r.Body)return{path:t,content:null,error:`file_not_found`};let i=r.Body,a;if(typeof i.transformToByteArray==`function`)a=await i.transformToByteArray();else if(typeof i.transformToString==`function`)a=new TextEncoder().encode(await i.transformToString(`utf-8`));else if(typeof i.transformToWebStream==`function`){let e=i.transformToWebStream().getReader(),t=[],n=0;for(;;){let{value:r,done:i}=await e.read();if(i)break;let a=r??new Uint8Array;t.push(a),n+=a.length}let r=new Uint8Array(n),o=0;for(let e of t)r.set(e,o),o+=e.length;a=r}else return{path:t,content:null,error:`invalid_path`};return{path:t,content:a,error:null}}catch(e){return{path:t,content:null,error:this.mapError(e)}}}))}mapError(e){let t=e,n=t?.code,r=t?.name,i=t?.message;return n===`NoSuchKey`||n===`ENOENT`||r===`NoSuchKey`||i===`NoSuchKey`?`file_not_found`:n===`AccessDenied`||n===`Forbidden`||n===`EACCES`||r===`AccessDenied`||i===`AccessDenied`||i===`Forbidden`?`permission_denied`:n===`EISDIR`||i===`EISDIR`?`is_directory`:`invalid_path`}async dangerouslyListAllObjects(e){let t=!0,r,i=[],a=[],o,s,c,l;for(;t;){let u=await this.s3Client.send(new n({...e,ContinuationToken:r}));o===void 0&&u.Name!==void 0&&(o=u.Name),s===void 0&&u.Prefix!==void 0&&(s=u.Prefix),c===void 0&&u.Delimiter!==void 0&&(c=u.Delimiter),l===void 0&&u.MaxKeys!==void 0&&(l=u.MaxKeys),u.Contents?.length&&i.push(...u.Contents),u.CommonPrefixes?.length&&a.push(...u.CommonPrefixes),t=u.IsTruncated===!0,r=u.NextContinuationToken}return{Name:o,Prefix:s??e.Prefix,Delimiter:c??e.Delimiter,MaxKeys:l??e.MaxKeys,Contents:i,CommonPrefixes:a}}};export{o as S3Backend};
|
|
4
|
+
//# sourceMappingURL=index.js.map
|