difit 3.1.10 → 3.1.12
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/README.ja.md +11 -3
- package/README.ko.md +9 -1
- package/README.md +10 -2
- package/README.zh.md +9 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.test.js +29 -0
- package/dist/cli/utils.d.ts +3 -3
- package/dist/cli/utils.js +10 -4
- package/dist/client/assets/index-AQuNl5mW.js +92 -0
- package/dist/client/assets/{prism-csharp-omuTcU4j.js → prism-csharp-C7x4qFLG.js} +1 -1
- package/dist/client/assets/{prism-hcl-BVGrHlPv.js → prism-hcl-CBjfvIjf.js} +1 -1
- package/dist/client/assets/{prism-java-BjHLe7qM.js → prism-java-Ca4SeKTf.js} +1 -1
- package/dist/client/assets/{prism-perl-Cl4F-f2r.js → prism-perl-B_RTNjmx.js} +1 -1
- package/dist/client/assets/{prism-php-BbsdsICU.js → prism-php-Y4QWW5YT.js} +1 -1
- package/dist/client/assets/{prism-ruby-CSLiFfIy.js → prism-ruby-CQyeYrqM.js} +1 -1
- package/dist/client/assets/{prism-solidity-C3yStBME.js → prism-solidity-DNiu86MI.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/server/generated-file-check.d.ts +2 -1
- package/dist/server/git-diff.d.ts +9 -1
- package/dist/server/git-diff.js +56 -88
- package/dist/server/git-diff.test.js +19 -28
- package/dist/server/server.js +59 -14
- package/dist/server/server.test.js +67 -0
- package/dist/types/diff.d.ts +7 -0
- package/dist/utils/suggestionUtils.d.ts +2 -1
- package/package.json +35 -34
- package/dist/client/assets/index-CH5h4Jfu.js +0 -92
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as U}from"./index-
|
|
1
|
+
import{g as U}from"./index-AQuNl5mW.js";function W(r,t){for(var e=0;e<t.length;e++){const a=t[e];if(typeof a!="string"&&!Array.isArray(a)){for(const s in a)if(s!=="default"&&!(s in r)){const u=Object.getOwnPropertyDescriptor(a,s);u&&Object.defineProperty(r,s,u.get?u:{enumerable:!0,get:()=>a[s]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}var I={},O;function Z(){return O||(O=1,(function(r){function t(n,l){return n.replace(/<<(\d+)>>/g,function(f,M){return"(?:"+l[+M]+")"})}function e(n,l,f){return RegExp(t(n,l),"")}function a(n,l){for(var f=0;f<l;f++)n=n.replace(/<<self>>/g,function(){return"(?:"+n+")"});return n.replace(/<<self>>/g,"[^\\s\\S]")}var s={type:"bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",typeDeclaration:"class enum interface record struct",contextual:"add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",other:"abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield"};function u(n){return"\\b(?:"+n.trim().replace(/ /g,"|")+")\\b"}var v=u(s.typeDeclaration),d=RegExp(u(s.type+" "+s.typeDeclaration+" "+s.contextual+" "+s.other)),T=u(s.typeDeclaration+" "+s.contextual+" "+s.other),z=u(s.type+" "+s.typeDeclaration+" "+s.other),g=a(/<(?:[^<>;=+\-*/%&|^]|<<self>>)*>/.source,2),h=a(/\((?:[^()]|<<self>>)*\)/.source,2),i=/@?\b[A-Za-z_]\w*\b/.source,b=t(/<<0>>(?:\s*<<1>>)?/.source,[i,g]),c=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[T,b]),y=/\[\s*(?:,\s*)*\]/.source,A=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[c,y]),K=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[g,h,y]),q=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[K]),p=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[q,c,y]),o={keyword:d,punctuation:/[<>()?,.:[\]]/},k=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,w=/"(?:\\.|[^\\"\r\n])*"/.source,F=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;r.languages.csharp=r.languages.extend("clike",{string:[{pattern:e(/(^|[^$\\])<<0>>/.source,[F]),lookbehind:!0,greedy:!0},{pattern:e(/(^|[^@$\\])<<0>>/.source,[w]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:e(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[c]),lookbehind:!0,inside:o},{pattern:e(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[i,p]),lookbehind:!0,inside:o},{pattern:e(/(\busing\s+)<<0>>(?=\s*=)/.source,[i]),lookbehind:!0},{pattern:e(/(\b<<0>>\s+)<<1>>/.source,[v,b]),lookbehind:!0,inside:o},{pattern:e(/(\bcatch\s*\(\s*)<<0>>/.source,[c]),lookbehind:!0,inside:o},{pattern:e(/(\bwhere\s+)<<0>>/.source,[i]),lookbehind:!0},{pattern:e(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[A]),lookbehind:!0,inside:o},{pattern:e(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[p,z,i]),inside:o}],keyword:d,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),r.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),r.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:e(/([(,]\s*)<<0>>(?=\s*:)/.source,[i]),lookbehind:!0,alias:"punctuation"}}),r.languages.insertBefore("csharp","class-name",{namespace:{pattern:e(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[i]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:e(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[h]),lookbehind:!0,alias:"class-name",inside:o},"return-type":{pattern:e(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[p,c]),inside:o,alias:"class-name"},"constructor-invocation":{pattern:e(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[p]),lookbehind:!0,inside:o,alias:"class-name"},"generic-method":{pattern:e(/<<0>>\s*<<1>>(?=\s*\()/.source,[i,g]),inside:{function:e(/^<<0>>/.source,[i]),generic:{pattern:RegExp(g),alias:"class-name",inside:o}}},"type-list":{pattern:e(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[v,b,i,p,d.source,h,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:e(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[b,h]),lookbehind:!0,greedy:!0,inside:r.languages.csharp},keyword:d,"class-name":{pattern:RegExp(p),greedy:!0,inside:o},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var x=w+"|"+k,E=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[x]),S=a(t(/[^"'/()]|<<0>>|\(<<self>>*\)/.source,[E]),2),_=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,N=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[c,S]);r.languages.insertBefore("csharp","class-name",{attribute:{pattern:e(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[_,N]),lookbehind:!0,greedy:!0,inside:{target:{pattern:e(/^<<0>>(?=\s*:)/.source,[_]),alias:"keyword"},"attribute-arguments":{pattern:e(/\(<<0>>*\)/.source,[S]),inside:r.languages.csharp},"class-name":{pattern:RegExp(c),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var m=/:[^}\r\n]+/.source,C=a(t(/[^"'/()]|<<0>>|\(<<self>>*\)/.source,[E]),2),$=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[C,m]),R=a(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<<self>>*\)/.source,[x]),2),D=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[R,m]);function j(n,l){return{interpolation:{pattern:e(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[n]),lookbehind:!0,inside:{"format-string":{pattern:e(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[l,m]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:r.languages.csharp}}},string:/[\s\S]+/}}r.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:e(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[$]),lookbehind:!0,greedy:!0,inside:j($,C)},{pattern:e(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[D]),lookbehind:!0,greedy:!0,inside:j(D,R)}],char:{pattern:RegExp(k),greedy:!0}}),r.languages.dotnet=r.languages.cs=r.languages.csharp})(Prism)),I}var B=Z();const G=U(B),J=W({__proto__:null,default:G},[B]);export{J as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-AQuNl5mW.js";function d(t,o){for(var a=0;a<o.length;a++){const e=o[a];if(typeof e!="string"&&!Array.isArray(e)){for(const r in e)if(r!=="default"&&!(r in t)){const i=Object.getOwnPropertyDescriptor(e,r);i&&Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var s={},n;function p(){return n||(n=1,Prism.languages.hcl={comment:/(?:\/\/|#).*|\/\*[\s\S]*?(?:\*\/|$)/,heredoc:{pattern:/<<-?(\w+\b)[\s\S]*?^[ \t]*\1/m,greedy:!0,alias:"string"},keyword:[{pattern:/(?:data|resource)\s+(?:"(?:\\[\s\S]|[^\\"])*")(?=\s+"[\w-]+"\s+\{)/i,inside:{type:{pattern:/(resource|data|\s+)(?:"(?:\\[\s\S]|[^\\"])*")/i,lookbehind:!0,alias:"variable"}}},{pattern:/(?:backend|module|output|provider|provisioner|variable)\s+(?:[\w-]+|"(?:\\[\s\S]|[^\\"])*")\s+(?=\{)/i,inside:{type:{pattern:/(backend|module|output|provider|provisioner|variable)\s+(?:[\w-]+|"(?:\\[\s\S]|[^\\"])*")\s+/i,lookbehind:!0,alias:"variable"}}},/[\w-]+(?=\s+\{)/],property:[/[-\w\.]+(?=\s*=(?!=))/,/"(?:\\[\s\S]|[^\\"])+"(?=\s*[:=])/],string:{pattern:/"(?:[^\\$"]|\\[\s\S]|\$(?:(?=")|\$+(?!\$)|[^"${])|\$\{(?:[^{}"]|"(?:[^\\"]|\\[\s\S])*")*\})*"/,greedy:!0,inside:{interpolation:{pattern:/(^|[^$])\$\{(?:[^{}"]|"(?:[^\\"]|\\[\s\S])*")*\}/,lookbehind:!0,inside:{type:{pattern:/(\b(?:count|data|local|module|path|self|terraform|var)\b\.)[\w\*]+/i,lookbehind:!0,alias:"variable"},keyword:/\b(?:count|data|local|module|path|self|terraform|var)\b/i,function:/\w+(?=\()/,string:{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0},number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i,punctuation:/[!\$#%&'()*+,.\/;<=>@\[\\\]^`{|}~?:]/}}}},number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i,boolean:/\b(?:false|true)\b/i,punctuation:/[=\[\]{}]/}),s}var l=p();const b=u(l),f=d({__proto__:null,default:b},[l]);export{f as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-AQuNl5mW.js";function p(t,a){for(var r=0;r<a.length;r++){const e=a[r];if(typeof e!="string"&&!Array.isArray(e)){for(const s in e)if(s!=="default"&&!(s in t)){const n=Object.getOwnPropertyDescriptor(e,s);n&&Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:()=>e[s]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var o={},i;function d(){return i||(i=1,(function(t){var a=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,r=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,e={pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};t.languages.java=t.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[e,{pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:e.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+r+/[A-Z]\w*\b/.source),lookbehind:!0,inside:e.inside}],keyword:a,function:[t.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),t.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),t.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":e,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+r+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:e.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+r+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:e.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(/<keyword>/g,function(){return a.source})),lookbehind:!0,inside:{punctuation:/\./}}})})(Prism)),o}var c=d();const l=u(c),w=p({__proto__:null,default:l},[c]);export{w as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as l}from"./index-
|
|
1
|
+
import{g as l}from"./index-AQuNl5mW.js";function d(r,e){for(var o=0;o<e.length;o++){const t=e[o];if(typeof t!="string"&&!Array.isArray(t)){for(const s in t)if(s!=="default"&&!(s in r)){const n=Object.getOwnPropertyDescriptor(t,s);n&&Object.defineProperty(r,s,n.get?n:{enumerable:!0,get:()=>t[s]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}var a={},u;function c(){return u||(u=1,(function(r){var e=/(?:\((?:[^()\\]|\\[\s\S])*\)|\{(?:[^{}\\]|\\[\s\S])*\}|\[(?:[^[\]\\]|\\[\s\S])*\]|<(?:[^<>\\]|\\[\s\S])*>)/.source;r.languages.perl={comment:[{pattern:/(^\s*)=\w[\s\S]*?=cut.*/m,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],string:[{pattern:RegExp(/\b(?:q|qq|qw|qx)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,e].join("|")+")"),greedy:!0},{pattern:/("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/'(?:[^'\\\r\n]|\\.)*'/,greedy:!0}],regex:[{pattern:RegExp(/\b(?:m|qr)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,e].join("|")+")"+/[msixpodualngc]*/.source),greedy:!0},{pattern:RegExp(/(^|[^-])\b(?:s|tr|y)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,/([a-zA-Z0-9])(?:(?!\3)[^\\]|\\[\s\S])*\3(?:(?!\3)[^\\]|\\[\s\S])*\3/.source,e+/\s*/.source+e].join("|")+")"+/[msixpodualngcer]*/.source),lookbehind:!0,greedy:!0},{pattern:/\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,greedy:!0}],variable:[/[&*$@%]\{\^[A-Z]+\}/,/[&*$@%]\^[A-Z_]/,/[&*$@%]#?(?=\{)/,/[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,/[&*$@%]\d+/,/(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?![<=])\S*?>|\b_\b/,alias:"symbol"},"v-string":{pattern:/v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,alias:"string"},function:{pattern:/(\bsub[ \t]+)\w+/,lookbehind:!0},keyword:/\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,punctuation:/[{}[\];(),:]/}})(Prism)),a}var i=c();const p=l(i),b=d({__proto__:null,default:p},[i]);export{b as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as c}from"./index-
|
|
1
|
+
import{g as c}from"./index-AQuNl5mW.js";function f(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const a in t)if(a!=="default"&&!(a in e)){const i=Object.getOwnPropertyDescriptor(t,a);i&&Object.defineProperty(e,a,i.get?i:{enumerable:!0,get:()=>t[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var u={},d;function g(){return d||(d=1,(function(e){var r=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],t=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,a=/<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,i=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:r,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:t,operator:a,punctuation:i};var l={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:r,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:t,operator:a,punctuation:i}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",function(s){if(/<\?/.test(s.code)){var p=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;e.languages["markup-templating"].buildPlaceholders(s,"php",p)}}),e.hooks.add("after-tokenize",function(s){e.languages["markup-templating"].tokenizePlaceholders(s,"php")})})(Prism)),u}var b=g();const y=c(b),m=f({__proto__:null,default:y},[b]);export{m as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as l}from"./index-
|
|
1
|
+
import{g as l}from"./index-AQuNl5mW.js";function d(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const i in t)if(i!=="default"&&!(i in e)){const s=Object.getOwnPropertyDescriptor(t,i);s&&Object.defineProperty(e,i,s.get?s:{enumerable:!0,get:()=>t[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var a={},o;function g(){return o||(o=1,(function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var r={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",t=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+t),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+t+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby})(Prism)),a}var u=g();const p=l(u),b=d({__proto__:null,default:p},[u]);export{b as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-AQuNl5mW.js";function d(t,n){for(var i=0;i<n.length;i++){const e=n[i];if(typeof e!="string"&&!Array.isArray(e)){for(const r in e)if(r!=="default"&&!(r in t)){const s=Object.getOwnPropertyDescriptor(e,r);s&&Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:()=>e[r]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var o={},a;function c(){return a||(a=1,Prism.languages.solidity=Prism.languages.extend("clike",{"class-name":{pattern:/(\b(?:contract|enum|interface|library|new|struct|using)\s+)(?!\d)[\w$]+/,lookbehind:!0},keyword:/\b(?:_|anonymous|as|assembly|assert|break|calldata|case|constant|constructor|continue|contract|default|delete|do|else|emit|enum|event|external|for|from|function|if|import|indexed|inherited|interface|internal|is|let|library|mapping|memory|modifier|new|payable|pragma|private|public|pure|require|returns?|revert|selfdestruct|solidity|storage|struct|suicide|switch|this|throw|using|var|view|while)\b/,operator:/=>|->|:=|=:|\*\*|\+\+|--|\|\||&&|<<=?|>>=?|[-+*/%^&|<>!=]=?|[~?]/}),Prism.languages.insertBefore("solidity","keyword",{builtin:/\b(?:address|bool|byte|u?int(?:8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|string|bytes(?:[1-9]|[12]\d|3[0-2])?)\b/}),Prism.languages.insertBefore("solidity","number",{version:{pattern:/([<>]=?|\^)\d+\.\d+\.\d+\b/,lookbehind:!0,alias:"number"}}),Prism.languages.sol=Prism.languages.solidity),o}var l=c();const m=u(l),y=d({__proto__:null,default:m},[l]);export{y as p};
|
package/dist/client/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<link rel="icon" href="/favicon-white.svg" media="(prefers-color-scheme: dark)" />
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
9
|
<title>difit - Git Diff Viewer</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-AQuNl5mW.js"></script>
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/index-D4vctQX_.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface GeneratedCheckResult {
|
|
2
2
|
isGenerated: boolean;
|
|
3
3
|
reason?: 'path' | 'universal' | 'language-specific';
|
|
4
4
|
matchedPattern?: string;
|
|
@@ -14,3 +14,4 @@ export interface GeneratedCheckResult {
|
|
|
14
14
|
* @param getHeaderLines A function that lazily provides the first 20 lines of the file content
|
|
15
15
|
*/
|
|
16
16
|
export declare function isGeneratedFile(parsedPath: string, getHeaderLines?: () => string[]): GeneratedCheckResult;
|
|
17
|
+
export {};
|
|
@@ -2,13 +2,15 @@ import { type DiffResponse } from '../types/diff.js';
|
|
|
2
2
|
export declare class GitDiffParser {
|
|
3
3
|
private git;
|
|
4
4
|
private repoPath;
|
|
5
|
+
private readonly resolvedCommitCache;
|
|
6
|
+
private static readonly RESOLVED_COMMIT_CACHE_TTL_MS;
|
|
7
|
+
private static readonly GENERATED_HEADER_SCAN_BYTES;
|
|
5
8
|
constructor(repoPath?: string);
|
|
6
9
|
parseDiff(targetCommitish: string, baseCommitish: string, ignoreWhitespace?: boolean): Promise<DiffResponse>;
|
|
7
10
|
private parseUnifiedDiff;
|
|
8
11
|
private decodeGitPath;
|
|
9
12
|
private extractPathFromLine;
|
|
10
13
|
private parseDiffHeaderPaths;
|
|
11
|
-
private hasRenameInfo;
|
|
12
14
|
private parseFileBlock;
|
|
13
15
|
private countLinesFromChunks;
|
|
14
16
|
private parseChunks;
|
|
@@ -16,7 +18,13 @@ export declare class GitDiffParser {
|
|
|
16
18
|
parseStdinDiff(diffContent: string): DiffResponse;
|
|
17
19
|
getBlobContent(filepath: string, ref: string): Promise<Buffer>;
|
|
18
20
|
getLineCount(filepath: string, ref: string): Promise<number>;
|
|
21
|
+
private extractHeaderLines;
|
|
22
|
+
getGeneratedStatus(filepath: string, ref: string): Promise<{
|
|
23
|
+
isGenerated: boolean;
|
|
24
|
+
source: 'path' | 'content';
|
|
25
|
+
}>;
|
|
19
26
|
resolveCommitish(commitish: string): Promise<string>;
|
|
27
|
+
clearResolvedCommitCache(): void;
|
|
20
28
|
getDefaultBranch(): Promise<string | null>;
|
|
21
29
|
getRevisionOptions(currentBase?: string, currentTarget?: string): Promise<{
|
|
22
30
|
branches: Array<{
|
package/dist/server/git-diff.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { simpleGit
|
|
1
|
+
import { simpleGit } from 'simple-git';
|
|
2
2
|
import { validateDiffArguments, shortHash, createCommitRangeString } from '../cli/utils.js';
|
|
3
3
|
import { isGeneratedFile } from './generated-file-check.js';
|
|
4
4
|
export class GitDiffParser {
|
|
5
5
|
git;
|
|
6
6
|
repoPath;
|
|
7
|
+
resolvedCommitCache = new Map();
|
|
8
|
+
static RESOLVED_COMMIT_CACHE_TTL_MS = 5_000;
|
|
9
|
+
static GENERATED_HEADER_SCAN_BYTES = 4 * 1024;
|
|
7
10
|
constructor(repoPath = process.cwd()) {
|
|
8
11
|
this.repoPath = repoPath;
|
|
9
12
|
this.git = simpleGit(repoPath);
|
|
@@ -48,31 +51,9 @@ export class GitDiffParser {
|
|
|
48
51
|
// Ignore external diff-tools to unify output.
|
|
49
52
|
// https://github.com/yoshiko-pg/difit/issues/19
|
|
50
53
|
diffArgs.push('--no-ext-diff', '--color=never');
|
|
51
|
-
//
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const files = this.parseUnifiedDiff(diffRaw, diffSummary.files);
|
|
55
|
-
// Check generated status with content for files not yet identified
|
|
56
|
-
await Promise.all(files.map(async (file) => {
|
|
57
|
-
if (file.isGenerated)
|
|
58
|
-
return;
|
|
59
|
-
if (file.status === 'deleted')
|
|
60
|
-
return;
|
|
61
|
-
try {
|
|
62
|
-
// For content-based checks, we read the first 20 lines of the file
|
|
63
|
-
// We use targetCommitish to get the version of the file we are looking at
|
|
64
|
-
const buffer = await this.getBlobContent(file.path, targetCommitish);
|
|
65
|
-
const content = buffer.toString('utf8');
|
|
66
|
-
const lines = content.split('\n').slice(0, 20);
|
|
67
|
-
const result = isGeneratedFile(file.path, () => lines);
|
|
68
|
-
if (result.isGenerated) {
|
|
69
|
-
file.isGenerated = true;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// Ignore errors (e.g. file too large, file not found in target ref)
|
|
74
|
-
}
|
|
75
|
-
}));
|
|
54
|
+
// Single git invocation for better startup latency on large repositories.
|
|
55
|
+
const diffRaw = await this.git.diff(diffArgs);
|
|
56
|
+
const files = this.parseUnifiedDiff(diffRaw);
|
|
76
57
|
return {
|
|
77
58
|
commit: resolvedCommit,
|
|
78
59
|
files,
|
|
@@ -83,21 +64,12 @@ export class GitDiffParser {
|
|
|
83
64
|
throw new Error(`Failed to parse diff for ${targetCommitish} vs ${baseCommitish}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
84
65
|
}
|
|
85
66
|
}
|
|
86
|
-
parseUnifiedDiff(diffText
|
|
67
|
+
parseUnifiedDiff(diffText) {
|
|
87
68
|
const files = [];
|
|
88
69
|
const fileBlocks = diffText.split(/^diff --git /m).slice(1);
|
|
89
|
-
for (
|
|
90
|
-
const block = `diff --git ${
|
|
91
|
-
const
|
|
92
|
-
// For stdin diff, we don't have summary
|
|
93
|
-
if (!summaryItem) {
|
|
94
|
-
const file = this.parseFileBlock(block, null);
|
|
95
|
-
if (file) {
|
|
96
|
-
files.push(file);
|
|
97
|
-
}
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
const file = this.parseFileBlock(block, summaryItem);
|
|
70
|
+
for (const fileBlock of fileBlocks) {
|
|
71
|
+
const block = `diff --git ${fileBlock}`;
|
|
72
|
+
const file = this.parseFileBlock(block);
|
|
101
73
|
if (file) {
|
|
102
74
|
files.push(file);
|
|
103
75
|
}
|
|
@@ -229,10 +201,7 @@ export class GitDiffParser {
|
|
|
229
201
|
newPath: this.decodeGitPath(rawNewPath),
|
|
230
202
|
};
|
|
231
203
|
}
|
|
232
|
-
|
|
233
|
-
return 'from' in summary && typeof summary.from === 'string';
|
|
234
|
-
}
|
|
235
|
-
parseFileBlock(block, summary) {
|
|
204
|
+
parseFileBlock(block) {
|
|
236
205
|
const lines = block.split('\n');
|
|
237
206
|
const headerLine = lines[0];
|
|
238
207
|
const headerPaths = this.parseDiffHeaderPaths(headerLine);
|
|
@@ -244,13 +213,8 @@ export class GitDiffParser {
|
|
|
244
213
|
const minusPath = this.extractPathFromLine(minusLine, '--- ');
|
|
245
214
|
const renameFromPath = this.extractPathFromLine(renameFromLine, 'rename from ');
|
|
246
215
|
const renameToPath = this.extractPathFromLine(renameToLine, 'rename to ');
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
if (summary && this.hasRenameInfo(summary)) {
|
|
250
|
-
summaryOldPath = this.decodeGitPath(summary.from);
|
|
251
|
-
}
|
|
252
|
-
const newPath = renameToPath ?? plusPath ?? headerPaths?.newPath ?? summaryNewPath;
|
|
253
|
-
const oldPath = renameFromPath ?? minusPath ?? headerPaths?.oldPath ?? summaryOldPath ?? newPath;
|
|
216
|
+
const newPath = renameToPath ?? plusPath ?? headerPaths?.newPath;
|
|
217
|
+
const oldPath = renameFromPath ?? minusPath ?? headerPaths?.oldPath ?? newPath;
|
|
254
218
|
if (!newPath) {
|
|
255
219
|
return null;
|
|
256
220
|
}
|
|
@@ -277,38 +241,14 @@ export class GitDiffParser {
|
|
|
277
241
|
};
|
|
278
242
|
// Parse chunks
|
|
279
243
|
const chunks = this.parseChunks(lines);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
chunks,
|
|
289
|
-
isGenerated: isGeneratedFile(path).isGenerated,
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
else if ('binary' in summary && summary.binary) {
|
|
293
|
-
// Binary file
|
|
294
|
-
return {
|
|
295
|
-
...baseFile,
|
|
296
|
-
additions: 0,
|
|
297
|
-
deletions: 0,
|
|
298
|
-
chunks: [], // No chunks for binary files
|
|
299
|
-
isGenerated: isGeneratedFile(path).isGenerated,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
// Text file with summary
|
|
304
|
-
return {
|
|
305
|
-
...baseFile,
|
|
306
|
-
additions: summary.insertions,
|
|
307
|
-
deletions: summary.deletions,
|
|
308
|
-
chunks,
|
|
309
|
-
isGenerated: isGeneratedFile(path).isGenerated,
|
|
310
|
-
};
|
|
311
|
-
}
|
|
244
|
+
const { additions, deletions } = this.countLinesFromChunks(chunks);
|
|
245
|
+
return {
|
|
246
|
+
...baseFile,
|
|
247
|
+
additions,
|
|
248
|
+
deletions,
|
|
249
|
+
chunks,
|
|
250
|
+
isGenerated: isGeneratedFile(path).isGenerated,
|
|
251
|
+
};
|
|
312
252
|
}
|
|
313
253
|
countLinesFromChunks(chunks) {
|
|
314
254
|
let additions = 0;
|
|
@@ -387,11 +327,7 @@ export class GitDiffParser {
|
|
|
387
327
|
}
|
|
388
328
|
}
|
|
389
329
|
parseStdinDiff(diffContent) {
|
|
390
|
-
|
|
391
|
-
// parseUnifiedDiff will handle it by counting additions/deletions from the actual diff content
|
|
392
|
-
const emptySummary = [];
|
|
393
|
-
// Use the existing parseUnifiedDiff method
|
|
394
|
-
const files = this.parseUnifiedDiff(diffContent, emptySummary);
|
|
330
|
+
const files = this.parseUnifiedDiff(diffContent);
|
|
395
331
|
return {
|
|
396
332
|
commit: 'stdin diff',
|
|
397
333
|
files,
|
|
@@ -456,9 +392,41 @@ export class GitDiffParser {
|
|
|
456
392
|
}
|
|
457
393
|
return count;
|
|
458
394
|
}
|
|
395
|
+
extractHeaderLines(buffer, maxLines = 20) {
|
|
396
|
+
const headerSlice = buffer.subarray(0, GitDiffParser.GENERATED_HEADER_SCAN_BYTES);
|
|
397
|
+
return headerSlice.toString('utf8').split('\n').slice(0, maxLines);
|
|
398
|
+
}
|
|
399
|
+
async getGeneratedStatus(filepath, ref) {
|
|
400
|
+
const pathResult = isGeneratedFile(filepath);
|
|
401
|
+
if (pathResult.isGenerated) {
|
|
402
|
+
return { isGenerated: true, source: 'path' };
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
const buffer = await this.getBlobContent(filepath, ref);
|
|
406
|
+
const lines = this.extractHeaderLines(buffer);
|
|
407
|
+
const result = isGeneratedFile(filepath, () => lines);
|
|
408
|
+
return { isGenerated: result.isGenerated, source: 'content' };
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
return { isGenerated: false, source: 'path' };
|
|
412
|
+
}
|
|
413
|
+
}
|
|
459
414
|
async resolveCommitish(commitish) {
|
|
415
|
+
const now = Date.now();
|
|
416
|
+
const cached = this.resolvedCommitCache.get(commitish);
|
|
417
|
+
if (cached && cached.expiresAt > now) {
|
|
418
|
+
return cached.value;
|
|
419
|
+
}
|
|
460
420
|
const hash = await this.git.revparse([commitish]);
|
|
461
|
-
|
|
421
|
+
const value = hash.substring(0, 7);
|
|
422
|
+
this.resolvedCommitCache.set(commitish, {
|
|
423
|
+
value,
|
|
424
|
+
expiresAt: now + GitDiffParser.RESOLVED_COMMIT_CACHE_TTL_MS,
|
|
425
|
+
});
|
|
426
|
+
return value;
|
|
427
|
+
}
|
|
428
|
+
clearResolvedCommitCache() {
|
|
429
|
+
this.resolvedCommitCache.clear();
|
|
462
430
|
}
|
|
463
431
|
async getDefaultBranch() {
|
|
464
432
|
try {
|
|
@@ -4,7 +4,6 @@ import { GitDiffParser } from './git-diff';
|
|
|
4
4
|
vi.mock('simple-git', () => ({
|
|
5
5
|
simpleGit: vi.fn(() => ({
|
|
6
6
|
revparse: vi.fn(),
|
|
7
|
-
diffSummary: vi.fn(),
|
|
8
7
|
diff: vi.fn(),
|
|
9
8
|
})),
|
|
10
9
|
}));
|
|
@@ -911,7 +910,7 @@ index abc123..def456 100644
|
|
|
911
910
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
912
911
|
expect(result.isGenerated).toBe(true);
|
|
913
912
|
});
|
|
914
|
-
it('
|
|
913
|
+
it('defers content-based generated detection until getGeneratedStatus is called', async () => {
|
|
915
914
|
const file = 'src/query.ts';
|
|
916
915
|
const diffLines = [
|
|
917
916
|
`diff --git a/${file} b/${file}`,
|
|
@@ -922,39 +921,31 @@ index abc123..def456 100644
|
|
|
922
921
|
`-old`,
|
|
923
922
|
`+new`,
|
|
924
923
|
];
|
|
925
|
-
|
|
926
|
-
file,
|
|
927
|
-
insertions: 1,
|
|
928
|
-
deletions: 1,
|
|
929
|
-
binary: false,
|
|
930
|
-
};
|
|
931
|
-
// Mock git.diff and git.diffSummary
|
|
924
|
+
// Mock git.diff
|
|
932
925
|
const gitDiff = parser.git.diff;
|
|
933
|
-
const gitDiffSummary = parser.git.diffSummary;
|
|
934
|
-
// Check if revparse is already mocked by vi.mock('simple-git') structure, if not we add it.
|
|
935
|
-
// Actually (parser as any).git is the mock object returned by simpleGit().
|
|
936
|
-
// In line 8 of git-diff.test.ts: simpleGit: vi.fn(() => ({ revparse: vi.fn(), ... }))
|
|
937
|
-
// So revparse IS a mock.
|
|
938
926
|
gitDiff.mockResolvedValue(diffLines.join('\n'));
|
|
939
|
-
gitDiffSummary.mockResolvedValue({
|
|
940
|
-
files: [summary],
|
|
941
|
-
insertions: 1,
|
|
942
|
-
deletions: 1,
|
|
943
|
-
});
|
|
944
927
|
parser.git.revparse.mockResolvedValue('abc1234567890abcdef1234567890abcdef12');
|
|
945
|
-
// Mock getBlobContent to return generated content
|
|
946
|
-
// We need to spy on the prototype or the instance method?
|
|
947
|
-
// parser is instance.
|
|
948
|
-
// parser.getBlobContent is the method.
|
|
949
|
-
// But getBlobContent is on the class.
|
|
950
|
-
// modifying the instance method is easiest if it's not private (it is public-ish in TS but private in class def?)
|
|
951
|
-
// It is defined as `async getBlobContent(...)`.
|
|
952
|
-
// Since it's on the class, we can spy on it if we cast to any.
|
|
953
928
|
const getBlobContentSpy = vi.spyOn(parser, 'getBlobContent');
|
|
954
929
|
getBlobContentSpy.mockResolvedValue(Buffer.from('// @generated\nconst x = 1;'));
|
|
955
930
|
const response = await parser.parseDiff('HEAD', 'HEAD~1');
|
|
956
931
|
expect(response.files[0].path).toBe(file);
|
|
957
|
-
expect(response.files[0].isGenerated).toBe(
|
|
932
|
+
expect(response.files[0].isGenerated).toBe(false);
|
|
933
|
+
expect(getBlobContentSpy).not.toHaveBeenCalled();
|
|
934
|
+
const generatedStatus = await parser.getGeneratedStatus(file, 'HEAD');
|
|
935
|
+
expect(getBlobContentSpy).toHaveBeenCalledTimes(1);
|
|
936
|
+
expect(generatedStatus).toEqual({ isGenerated: true, source: 'content' });
|
|
937
|
+
});
|
|
938
|
+
it('returns source=path for path-based generated files without reading content', async () => {
|
|
939
|
+
const getBlobContentSpy = vi.spyOn(parser, 'getBlobContent');
|
|
940
|
+
const generatedStatus = await parser.getGeneratedStatus('package-lock.json', 'HEAD');
|
|
941
|
+
expect(generatedStatus).toEqual({ isGenerated: true, source: 'path' });
|
|
942
|
+
expect(getBlobContentSpy).not.toHaveBeenCalled();
|
|
943
|
+
});
|
|
944
|
+
it('returns false when content cannot be read for content-based generated detection', async () => {
|
|
945
|
+
const getBlobContentSpy = vi.spyOn(parser, 'getBlobContent');
|
|
946
|
+
getBlobContentSpy.mockRejectedValue(new Error('missing blob'));
|
|
947
|
+
const generatedStatus = await parser.getGeneratedStatus('src/query.ts', 'HEAD');
|
|
948
|
+
expect(generatedStatus).toEqual({ isGenerated: false, source: 'path' });
|
|
958
949
|
});
|
|
959
950
|
it('detects minified files as generated', () => {
|
|
960
951
|
const minFiles = ['script.min.js', 'style.min.css', 'vendor/lib.min.js'];
|
package/dist/server/server.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
|
-
import {
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { join, dirname, isAbsolute, resolve, sep } from 'path';
|
|
3
4
|
import { fileURLToPath } from 'url';
|
|
4
5
|
import express from 'express';
|
|
5
6
|
import open from 'open';
|
|
@@ -11,10 +12,14 @@ import { resolveEditorOption } from '../utils/editorOptions.js';
|
|
|
11
12
|
import { getFileExtension } from '../utils/fileUtils.js';
|
|
12
13
|
import { FileWatcherService } from './file-watcher.js';
|
|
13
14
|
import { GitDiffParser } from './git-diff.js';
|
|
15
|
+
const GENERATED_STATUS_CACHE_TTL_MS = 60_000;
|
|
14
16
|
export async function startServer(options) {
|
|
15
17
|
const app = express();
|
|
16
|
-
const
|
|
18
|
+
const repositoryPath = resolve(options.repoPath ?? process.cwd());
|
|
19
|
+
const repositoryId = createHash('sha256').update(repositoryPath).digest('hex');
|
|
20
|
+
const parser = new GitDiffParser(repositoryPath);
|
|
17
21
|
const fileWatcher = new FileWatcherService();
|
|
22
|
+
const generatedStatusCache = new Map();
|
|
18
23
|
let diffDataCache = null;
|
|
19
24
|
let currentIgnoreWhitespace = options.ignoreWhitespace || false;
|
|
20
25
|
const diffMode = normalizeDiffViewMode(options.mode);
|
|
@@ -44,6 +49,8 @@ export async function startServer(options) {
|
|
|
44
49
|
// Function to invalidate cache when file changes are detected
|
|
45
50
|
const invalidateCache = () => {
|
|
46
51
|
diffDataCache = null;
|
|
52
|
+
generatedStatusCache.clear();
|
|
53
|
+
parser.clearResolvedCommitCache();
|
|
47
54
|
};
|
|
48
55
|
// Track current revisions for cache invalidation
|
|
49
56
|
let currentBaseCommitish = options.baseCommitish ?? '';
|
|
@@ -61,17 +68,7 @@ export async function startServer(options) {
|
|
|
61
68
|
currentBaseCommitish = requestedBase;
|
|
62
69
|
currentTargetCommitish = requestedTarget;
|
|
63
70
|
diffDataCache = await parser.parseDiff(requestedTarget, requestedBase, ignoreWhitespace);
|
|
64
|
-
|
|
65
|
-
// Get repository identifier for storage isolation
|
|
66
|
-
// Uses repository path for simplicity and worktree support
|
|
67
|
-
let repositoryId;
|
|
68
|
-
try {
|
|
69
|
-
const repositoryPath = process.cwd();
|
|
70
|
-
const crypto = await import('crypto');
|
|
71
|
-
repositoryId = crypto.createHash('sha256').update(repositoryPath).digest('hex');
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
// If we can't get repository path, leave undefined
|
|
71
|
+
generatedStatusCache.clear();
|
|
75
72
|
}
|
|
76
73
|
// Resolve symbolic refs like HEAD/HEAD^ to actual hashes for the UI
|
|
77
74
|
let resolvedBase = currentBaseCommitish || 'stdin';
|
|
@@ -102,6 +99,7 @@ export async function startServer(options) {
|
|
|
102
99
|
...diffDataCache,
|
|
103
100
|
ignoreWhitespace,
|
|
104
101
|
mode: diffMode,
|
|
102
|
+
openInEditorAvailable: !options.stdinDiff,
|
|
105
103
|
baseCommitish: resolvedBase,
|
|
106
104
|
targetCommitish: resolvedTarget,
|
|
107
105
|
requestedBaseCommitish,
|
|
@@ -110,6 +108,53 @@ export async function startServer(options) {
|
|
|
110
108
|
repositoryId,
|
|
111
109
|
});
|
|
112
110
|
});
|
|
111
|
+
app.get(/^\/api\/generated-status\/(.*)$/, async (req, res) => {
|
|
112
|
+
if (options.stdinDiff) {
|
|
113
|
+
res.status(400).json({ error: 'Generated status is not available for stdin diff' });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const filepath = req.params[0];
|
|
118
|
+
if (typeof filepath !== 'string' || filepath.length === 0) {
|
|
119
|
+
res.status(400).json({ error: 'Invalid file path' });
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const normalizedFilepath = filepath.replace(/\\/g, '/');
|
|
123
|
+
const hasParentTraversal = normalizedFilepath.split('/').some((segment) => segment === '..');
|
|
124
|
+
if (isAbsolute(filepath) || normalizedFilepath.startsWith('/') || hasParentTraversal) {
|
|
125
|
+
res.status(400).json({ error: 'File path outside repository' });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const resolvedPath = resolve(repositoryPath, normalizedFilepath);
|
|
129
|
+
if (resolvedPath !== repositoryPath && !resolvedPath.startsWith(`${repositoryPath}${sep}`)) {
|
|
130
|
+
res.status(400).json({ error: 'File path outside repository' });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const ref = req.query.ref || currentTargetCommitish || 'HEAD';
|
|
134
|
+
const cacheKey = `${ref}:${normalizedFilepath}`;
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const cached = generatedStatusCache.get(cacheKey);
|
|
137
|
+
if (cached && cached.expiresAt > now) {
|
|
138
|
+
res.json(cached.value);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const status = await parser.getGeneratedStatus(normalizedFilepath, ref);
|
|
142
|
+
const response = {
|
|
143
|
+
path: normalizedFilepath,
|
|
144
|
+
ref,
|
|
145
|
+
...status,
|
|
146
|
+
};
|
|
147
|
+
generatedStatusCache.set(cacheKey, {
|
|
148
|
+
value: response,
|
|
149
|
+
expiresAt: now + GENERATED_STATUS_CACHE_TTL_MS,
|
|
150
|
+
});
|
|
151
|
+
res.json(response);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error('Error fetching generated status:', error);
|
|
155
|
+
res.status(500).json({ error: 'Failed to get generated status' });
|
|
156
|
+
}
|
|
157
|
+
});
|
|
113
158
|
// Get available revisions for revision selector
|
|
114
159
|
app.get('/api/revisions', async (_req, res) => {
|
|
115
160
|
if (options.stdinDiff) {
|
|
@@ -395,7 +440,7 @@ export async function startServer(options) {
|
|
|
395
440
|
// Start file watcher
|
|
396
441
|
if (options.diffMode) {
|
|
397
442
|
try {
|
|
398
|
-
await fileWatcher.start(options.diffMode,
|
|
443
|
+
await fileWatcher.start(options.diffMode, repositoryPath, 300, invalidateCache);
|
|
399
444
|
}
|
|
400
445
|
catch (error) {
|
|
401
446
|
console.warn('⚠️ File watcher failed to start:', error);
|