difit 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +2 -1
- package/README.ko.md +2 -1
- package/README.md +2 -1
- package/README.zh.md +2 -1
- package/dist/cli/index.js +40 -28
- package/dist/cli/index.test.js +187 -116
- package/dist/cli/tuiDeprecation.d.ts +3 -0
- package/dist/cli/tuiDeprecation.js +16 -0
- package/dist/cli/tuiDeprecation.test.d.ts +1 -0
- package/dist/cli/tuiDeprecation.test.js +16 -0
- package/dist/cli/utils.d.ts +1 -0
- package/dist/cli/utils.js +17 -0
- package/dist/client/assets/_basePickBy-hOr-yGsE.js +1 -0
- package/dist/client/assets/_baseUniq-b7bzdUSn.js +1 -0
- package/dist/client/assets/arc-D65wG9gm.js +1 -0
- package/dist/client/assets/architecture-PBZL5I3N-DUNTzy9d.js +1 -0
- package/dist/client/assets/architectureDiagram-2XIMDMQ5-BOmef_aT.js +36 -0
- package/dist/client/assets/array-DOVTz2Mq.js +1 -0
- package/dist/client/assets/blockDiagram-WCTKOSBZ-CuovjbLp.js +132 -0
- package/dist/client/assets/c4Diagram-IC4MRINW-l2hgU0UG.js +10 -0
- package/dist/client/assets/channel-BBMOf_Bn.js +1 -0
- package/dist/client/assets/chunk-4BX2VUAB-Bh2XMPGo.js +1 -0
- package/dist/client/assets/chunk-55IACEB6-r9BRoqNs.js +1 -0
- package/dist/client/assets/chunk-7E7YKBS2-BUy3or4g.js +1 -0
- package/dist/client/assets/chunk-7R4GIKGN-C7ClNgvP.js +80 -0
- package/dist/client/assets/chunk-C72U2L5F-_P9RrDdo.js +1 -0
- package/dist/client/assets/chunk-EGIJ26TM-D-xQ2sZ-.js +1 -0
- package/dist/client/assets/{chunk-FMBD7UC4-BSa8SHgd.js → chunk-FMBD7UC4-OuP8NjEM.js} +2 -2
- package/dist/client/assets/chunk-GEFDOKGD-noJ9o8LM.js +2 -0
- package/dist/client/assets/chunk-GLR3WWYH-DVK9OjRZ.js +2 -0
- package/dist/client/assets/chunk-HHEYEP7N-C1QyKuQs.js +1 -0
- package/dist/client/assets/chunk-JSJVCQXG-2AjhqYcu.js +1 -0
- package/dist/client/assets/chunk-KX2RTZJC-tMPTaDcx.js +1 -0
- package/dist/client/assets/chunk-KYZI473N-CGwu81pT.js +53 -0
- package/dist/client/assets/chunk-L3YUKLVL-DFNfIVVw.js +1 -0
- package/dist/client/assets/chunk-MX3YWQON-BnSlIBhe.js +1 -0
- package/dist/client/assets/chunk-NQ4KR5QH-CpfTlpaZ.js +220 -0
- package/dist/client/assets/chunk-O4XLMI2P-BDGKGscp.js +7 -0
- package/dist/client/assets/chunk-OZEHJAEY-3OAEqm17.js +1 -0
- package/dist/client/assets/chunk-PQ6SQG4A-DfQjNfPX.js +1 -0
- package/dist/client/assets/chunk-PU5JKC2W-DRiL1iN6.js +70 -0
- package/dist/client/assets/chunk-QZHKN3VN-DBD5yPlw.js +1 -0
- package/dist/client/assets/chunk-R5LLSJPH-dkcbq1pR.js +1 -0
- package/dist/client/assets/chunk-WL4C6EOR-BeCB6d6F.js +189 -0
- package/dist/client/assets/chunk-XIRO2GV7-BxmEO1Vi.js +1 -0
- package/dist/client/assets/chunk-XPW4576I-jm7TiixU.js +32 -0
- package/dist/client/assets/chunk-XZSTWKYB-BGKYCy46.js +94 -0
- package/dist/client/assets/chunk-YBOYWFTD-C9faLjdm.js +1 -0
- package/dist/client/assets/classDiagram-VBA2DB6C-Depk8rxx.js +1 -0
- package/dist/client/assets/classDiagram-v2-RAHNMMFH-DHvQPm8y.js +1 -0
- package/dist/client/assets/clone-DuY6BQEm.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-BWD5TWFn.js +1 -0
- package/dist/client/assets/cytoscape.esm-B3gzQ1NF.js +321 -0
- package/dist/client/assets/dagre-Dd1VxucU.js +1 -0
- package/dist/client/assets/dagre-KLK3FWXG-BJFTyMud.js +4 -0
- package/dist/client/assets/defaultLocale-Ck2Xxk-C.js +1 -0
- package/dist/client/assets/diagram-E7M64L7V-eWdHIl72.js +24 -0
- package/dist/client/assets/diagram-IFDJBPK2-C1-sqK0o.js +43 -0
- package/dist/client/assets/diagram-P4PSJMXO-DHeUNvSg.js +24 -0
- package/dist/client/assets/dist-FLbYR5UU.js +1 -0
- package/dist/client/assets/erDiagram-INFDFZHY-CX8FAWmU.js +70 -0
- package/dist/client/assets/flowDiagram-PKNHOUZH-DgBnUaHH.js +162 -0
- package/dist/client/assets/ganttDiagram-A5KZAMGK-C331HQ-y.js +292 -0
- package/dist/client/assets/gitGraph-HDMCJU4V-DPGoIMlm.js +1 -0
- package/dist/client/assets/gitGraphDiagram-K3NZZRJ6-zEXLThxN.js +65 -0
- package/dist/client/assets/graphlib-WkJoBgka.js +1 -0
- package/dist/client/assets/index-BGPkswtu.js +79 -0
- package/dist/client/assets/index-Cq_APK7Y.css +2 -0
- package/dist/client/assets/info-3K5VOQVL-CYdIfRwG.js +1 -0
- package/dist/client/assets/infoDiagram-LFFYTUFH-CKx11_2a.js +2 -0
- package/dist/client/assets/init-Bft5Ffpj.js +1 -0
- package/dist/client/assets/isArrayLikeObject-icl0H0jo.js +1 -0
- package/dist/client/assets/isEmpty-Du8sNmkE.js +1 -0
- package/dist/client/assets/ishikawaDiagram-PHBUUO56-BlZMQgOe.js +70 -0
- package/dist/client/assets/journeyDiagram-4ABVD52K-C3p_p4rn.js +139 -0
- package/dist/client/assets/kanban-definition-K7BYSVSG-4XJPQF50.js +89 -0
- package/dist/client/assets/katex-BJrMXEjr.js +261 -0
- package/dist/client/assets/line-Bb6xn3n_.js +1 -0
- package/dist/client/assets/linear-BPttYRJr.js +1 -0
- package/dist/client/assets/math-CNhlSIO3.js +1 -0
- package/dist/client/assets/mermaid-parser.core-CjY9NqXx.js +4 -0
- package/dist/client/assets/mermaid.core-B0ynITdC.js +11 -0
- package/dist/client/assets/mindmap-definition-YRQLILUH-Dya2e4tr.js +68 -0
- package/dist/client/assets/ordinal-DIg8h6NI.js +1 -0
- package/dist/client/assets/packet-RMMSAZCW-D7vTTuAT.js +1 -0
- package/dist/client/assets/path-DfRbCp9y.js +1 -0
- package/dist/client/assets/pie-UPGHQEXC-ptFuye_f.js +1 -0
- package/dist/client/assets/pieDiagram-SKSYHLDU-MZ74L9cN.js +30 -0
- package/dist/client/assets/{prism-bash-DTkDXsAh.js → prism-bash-6uMTC0Q2.js} +1 -1
- package/dist/client/assets/prism-csharp-Dkc2OSmh.js +1 -0
- package/dist/client/assets/prism-dart-iZy_wlz-.js +1 -0
- package/dist/client/assets/prism-elixir-BIzI9WJK.js +1 -0
- package/dist/client/assets/prism-hcl-Bx2FGBKG.js +1 -0
- package/dist/client/assets/prism-java-DBXf7fH0.js +1 -0
- package/dist/client/assets/prism-markup-templating-DS0ksKLt.js +1 -0
- package/dist/client/assets/prism-perl-BlhPiMfT.js +1 -0
- package/dist/client/assets/prism-php-DVtOAJsW.js +1 -0
- package/dist/client/assets/{prism-protobuf-DiQ_z8B5.js → prism-protobuf-BUsrNVvv.js} +1 -1
- package/dist/client/assets/prism-ruby-Saes64I6.js +1 -0
- package/dist/client/assets/{prism-scala-BjNo2HkN.js → prism-scala-ANOINMog.js} +1 -1
- package/dist/client/assets/prism-solidity-C5Mx5y66.js +1 -0
- package/dist/client/assets/{prism-sql-AgAyy5H_.js → prism-sql-D5pwK0Dp.js} +1 -1
- package/dist/client/assets/{prism-vim-uciLQ2PQ.js → prism-vim-BSZSu-gX.js} +1 -1
- package/dist/client/assets/quadrantDiagram-337W2JSQ-Da_T39nG.js +7 -0
- package/dist/client/assets/radar-KQ55EAFF-BR1_ZPLF.js +1 -0
- package/dist/client/assets/requirementDiagram-Z7DCOOCP-DzlKWGt3.js +73 -0
- package/dist/client/assets/rough.esm-KjoEK0it.js +1 -0
- package/dist/client/assets/sankeyDiagram-WA2Y5GQK-BPketwK-.js +10 -0
- package/dist/client/assets/sequenceDiagram-2WXFIKYE-geDrMLZ_.js +145 -0
- package/dist/client/assets/src-BuTVwZtT.js +1 -0
- package/dist/client/assets/stateDiagram-RAJIS63D-DOLTjnid.js +1 -0
- package/dist/client/assets/stateDiagram-v2-FVOUBMTO-BIjVI5d6.js +1 -0
- package/dist/client/assets/timeline-definition-YZTLITO2-Cy6Qm4Pd.js +61 -0
- package/dist/client/assets/treemap-KZPCXAKY-Bw93Vsua.js +1 -0
- package/dist/client/assets/vennDiagram-LZ73GAT5-UUQN9akd.js +34 -0
- package/dist/client/assets/xychartDiagram-JWTSCODW-DiTicxdS.js +7 -0
- package/dist/client/index.html +2 -2
- package/dist/server/git-diff-tui.d.ts +2 -2
- package/dist/server/git-diff-tui.js +12 -7
- package/dist/server/git-diff-tui.test.js +18 -2
- package/dist/server/git-diff.d.ts +3 -2
- package/dist/server/git-diff.js +29 -6
- package/dist/server/git-diff.test.js +52 -3
- package/dist/server/server.d.ts +2 -3
- package/dist/server/server.js +80 -55
- package/dist/server/server.test.js +110 -60
- package/dist/tui/App.d.ts +2 -2
- package/dist/tui/App.js +4 -3
- package/dist/types/diff.d.ts +8 -0
- package/dist/utils/commentImports.js +3 -2
- package/dist/utils/createId.d.ts +1 -0
- package/dist/utils/createId.js +5 -0
- package/dist/utils/createId.test.d.ts +1 -0
- package/dist/utils/createId.test.js +48 -0
- package/dist/utils/diffSelection.d.ts +6 -0
- package/dist/utils/diffSelection.js +30 -0
- package/package.json +5 -5
- package/dist/client/assets/_basePickBy-ChXFkTMC.js +0 -1
- package/dist/client/assets/_baseUniq-Mj_sFFQW.js +0 -1
- package/dist/client/assets/arc-BMA6S9F1.js +0 -1
- package/dist/client/assets/architectureDiagram-2XIMDMQ5-0uiM_v5K.js +0 -36
- package/dist/client/assets/blockDiagram-WCTKOSBZ-CM7ZLL6F.js +0 -132
- package/dist/client/assets/c4Diagram-IC4MRINW-DKtCnVwn.js +0 -10
- package/dist/client/assets/channel-D057yzDp.js +0 -1
- package/dist/client/assets/chunk-4BX2VUAB-Wsl8DxEB.js +0 -1
- package/dist/client/assets/chunk-55IACEB6-CHm9X5i7.js +0 -1
- package/dist/client/assets/chunk-JSJVCQXG-Cpk76oJ3.js +0 -1
- package/dist/client/assets/chunk-KX2RTZJC-D8YvfZVu.js +0 -1
- package/dist/client/assets/chunk-NQ4KR5QH-BogviJOv.js +0 -220
- package/dist/client/assets/chunk-QZHKN3VN-DwLJYu26.js +0 -1
- package/dist/client/assets/chunk-WL4C6EOR-BFDpGxW2.js +0 -189
- package/dist/client/assets/classDiagram-VBA2DB6C---D4iOts.js +0 -1
- package/dist/client/assets/classDiagram-v2-RAHNMMFH---D4iOts.js +0 -1
- package/dist/client/assets/clone-xSR3otEf.js +0 -1
- package/dist/client/assets/cose-bilkent-S5V4N54A-oEosZ_5y.js +0 -1
- package/dist/client/assets/cytoscape.esm-5J0xJHOV.js +0 -321
- package/dist/client/assets/dagre-KLK3FWXG-gFld4u1H.js +0 -4
- package/dist/client/assets/defaultLocale-DX6XiGOO.js +0 -1
- package/dist/client/assets/diagram-E7M64L7V-gJq3kSrf.js +0 -24
- package/dist/client/assets/diagram-IFDJBPK2-BsUm_q22.js +0 -43
- package/dist/client/assets/diagram-P4PSJMXO-juB-sfcR.js +0 -24
- package/dist/client/assets/erDiagram-INFDFZHY-Dn77qXAt.js +0 -70
- package/dist/client/assets/flowDiagram-PKNHOUZH-DtmvDYdN.js +0 -162
- package/dist/client/assets/ganttDiagram-A5KZAMGK-BlDaKLbQ.js +0 -292
- package/dist/client/assets/gitGraphDiagram-K3NZZRJ6-DeAAeuMS.js +0 -65
- package/dist/client/assets/graph-NX9gBP47.js +0 -1
- package/dist/client/assets/index-VxkpzDXr.css +0 -1
- package/dist/client/assets/index-kJdw4DY-.js +0 -98
- package/dist/client/assets/infoDiagram-LFFYTUFH-CAaX023c.js +0 -2
- package/dist/client/assets/init-Gi6I4Gst.js +0 -1
- package/dist/client/assets/ishikawaDiagram-PHBUUO56-CmiTQStv.js +0 -70
- package/dist/client/assets/journeyDiagram-4ABVD52K-B0SHC7mz.js +0 -139
- package/dist/client/assets/kanban-definition-K7BYSVSG-IfRdhzz7.js +0 -89
- package/dist/client/assets/katex-C-M49wc6.js +0 -261
- package/dist/client/assets/layout-l3OdNQhJ.js +0 -1
- package/dist/client/assets/linear-CQ0hx5Qs.js +0 -1
- package/dist/client/assets/mermaid.core-DqlPTabt.js +0 -249
- package/dist/client/assets/mindmap-definition-YRQLILUH-DIgSmG_f.js +0 -68
- package/dist/client/assets/ordinal-Cboi1Yqb.js +0 -1
- package/dist/client/assets/pieDiagram-SKSYHLDU-FzM5qoIB.js +0 -30
- package/dist/client/assets/prism-csharp-DCfUUOUs.js +0 -1
- package/dist/client/assets/prism-dart-MjriiaMt.js +0 -1
- package/dist/client/assets/prism-elixir-riuOL1mm.js +0 -1
- package/dist/client/assets/prism-hcl-CizuX1s4.js +0 -1
- package/dist/client/assets/prism-java-DYCKrDUh.js +0 -1
- package/dist/client/assets/prism-markup-templating-Ct1xsyfA.js +0 -1
- package/dist/client/assets/prism-perl-BJwBYR3Y.js +0 -1
- package/dist/client/assets/prism-php-BMhFuA7y.js +0 -1
- package/dist/client/assets/prism-ruby-Bcu0cDEh.js +0 -1
- package/dist/client/assets/prism-solidity-DDDs3w-w.js +0 -1
- package/dist/client/assets/quadrantDiagram-337W2JSQ-BBrApyD7.js +0 -7
- package/dist/client/assets/requirementDiagram-Z7DCOOCP-CLXiwUaA.js +0 -73
- package/dist/client/assets/sankeyDiagram-WA2Y5GQK-9Y3Ly5qe.js +0 -10
- package/dist/client/assets/sequenceDiagram-2WXFIKYE-DEpX1BA5.js +0 -145
- package/dist/client/assets/stateDiagram-RAJIS63D-Ck3ullwA.js +0 -1
- package/dist/client/assets/stateDiagram-v2-FVOUBMTO-X6UiDsar.js +0 -1
- package/dist/client/assets/timeline-definition-YZTLITO2-CMezf3XV.js +0 -61
- package/dist/client/assets/treemap-KZPCXAKY-DqrcV0gQ.js +0 -162
- package/dist/client/assets/vennDiagram-LZ73GAT5-eQg945Fz.js +0 -34
- package/dist/client/assets/xychartDiagram-JWTSCODW-_hqdXeX1.js +0 -7
|
@@ -5,6 +5,7 @@ vi.mock('simple-git', () => ({
|
|
|
5
5
|
simpleGit: vi.fn(() => ({
|
|
6
6
|
revparse: vi.fn(),
|
|
7
7
|
diff: vi.fn(),
|
|
8
|
+
raw: vi.fn(),
|
|
8
9
|
})),
|
|
9
10
|
}));
|
|
10
11
|
// Mock child_process
|
|
@@ -967,7 +968,10 @@ index abc123..def456 100644
|
|
|
967
968
|
parser.git.revparse.mockResolvedValue('abc1234567890abcdef1234567890abcdef12');
|
|
968
969
|
const getBlobContentSpy = vi.spyOn(parser, 'getBlobContent');
|
|
969
970
|
getBlobContentSpy.mockResolvedValue(Buffer.from('// @generated\nconst x = 1;'));
|
|
970
|
-
const response = await parser.parseDiff(
|
|
971
|
+
const response = await parser.parseDiff({
|
|
972
|
+
targetCommitish: 'HEAD',
|
|
973
|
+
baseCommitish: 'HEAD~1',
|
|
974
|
+
});
|
|
971
975
|
expect(response.files[0].path).toBe(file);
|
|
972
976
|
expect(response.files[0].isGenerated).toBe(false);
|
|
973
977
|
expect(getBlobContentSpy).not.toHaveBeenCalled();
|
|
@@ -1078,7 +1082,10 @@ index abc123..def456 100644
|
|
|
1078
1082
|
.mockResolvedValueOnce('1234567890abcdef1234567890abcdef12345678')
|
|
1079
1083
|
.mockResolvedValueOnce('abcdef1234567890abcdef1234567890abcdef12');
|
|
1080
1084
|
gitDiff.mockResolvedValue('');
|
|
1081
|
-
const response = await parser.parseDiff(
|
|
1085
|
+
const response = await parser.parseDiff({
|
|
1086
|
+
targetCommitish: 'HEAD',
|
|
1087
|
+
baseCommitish: 'HEAD~1',
|
|
1088
|
+
}, false, 5);
|
|
1082
1089
|
expect(gitDiff).toHaveBeenCalledWith([
|
|
1083
1090
|
'abcdef1...1234567',
|
|
1084
1091
|
'-U5',
|
|
@@ -1089,6 +1096,11 @@ index abc123..def456 100644
|
|
|
1089
1096
|
commit: 'abcdef1...1234567',
|
|
1090
1097
|
files: [],
|
|
1091
1098
|
isEmpty: true,
|
|
1099
|
+
baseCommitish: 'abcdef1',
|
|
1100
|
+
targetCommitish: '1234567',
|
|
1101
|
+
requestedBaseCommitish: 'HEAD~1',
|
|
1102
|
+
requestedTargetCommitish: 'HEAD',
|
|
1103
|
+
requestedBaseMode: undefined,
|
|
1092
1104
|
});
|
|
1093
1105
|
});
|
|
1094
1106
|
it('accepts branch refs with revision suffixes', async () => {
|
|
@@ -1098,7 +1110,10 @@ index abc123..def456 100644
|
|
|
1098
1110
|
.mockResolvedValueOnce('1234567890abcdef1234567890abcdef12345678')
|
|
1099
1111
|
.mockResolvedValueOnce('abcdef1234567890abcdef1234567890abcdef12');
|
|
1100
1112
|
gitDiff.mockResolvedValue('');
|
|
1101
|
-
const response = await parser.parseDiff(
|
|
1113
|
+
const response = await parser.parseDiff({
|
|
1114
|
+
targetCommitish: 'codex/comment-thread',
|
|
1115
|
+
baseCommitish: 'codex/comment-thread^',
|
|
1116
|
+
});
|
|
1102
1117
|
expect(gitRevparse).toHaveBeenNthCalledWith(1, ['codex/comment-thread']);
|
|
1103
1118
|
expect(gitRevparse).toHaveBeenNthCalledWith(2, ['codex/comment-thread^']);
|
|
1104
1119
|
expect(gitDiff).toHaveBeenCalledWith(['abcdef1...1234567', '--no-ext-diff', '--color=never']);
|
|
@@ -1106,6 +1121,40 @@ index abc123..def456 100644
|
|
|
1106
1121
|
commit: 'abcdef1...1234567',
|
|
1107
1122
|
files: [],
|
|
1108
1123
|
isEmpty: true,
|
|
1124
|
+
baseCommitish: 'abcdef1',
|
|
1125
|
+
targetCommitish: '1234567',
|
|
1126
|
+
requestedBaseCommitish: 'codex/comment-thread^',
|
|
1127
|
+
requestedTargetCommitish: 'codex/comment-thread',
|
|
1128
|
+
requestedBaseMode: undefined,
|
|
1129
|
+
});
|
|
1130
|
+
});
|
|
1131
|
+
it('uses merge-base when baseMode is merge-base', async () => {
|
|
1132
|
+
const gitDiff = parser.git.diff;
|
|
1133
|
+
const gitRevparse = parser.git.revparse;
|
|
1134
|
+
const gitRaw = parser.git.raw;
|
|
1135
|
+
gitRaw.mockResolvedValue('fedcba9876543210fedcba9876543210fedcba98\n');
|
|
1136
|
+
gitRevparse.mockResolvedValueOnce('fedcba9876543210fedcba9876543210fedcba98');
|
|
1137
|
+
gitDiff.mockResolvedValue('');
|
|
1138
|
+
const response = await parser.parseDiff({
|
|
1139
|
+
targetCommitish: '.',
|
|
1140
|
+
baseCommitish: 'origin/main',
|
|
1141
|
+
baseMode: 'merge-base',
|
|
1142
|
+
});
|
|
1143
|
+
expect(gitRaw).toHaveBeenCalledWith(['merge-base', 'HEAD', 'origin/main']);
|
|
1144
|
+
expect(gitDiff).toHaveBeenCalledWith([
|
|
1145
|
+
'fedcba9876543210fedcba9876543210fedcba98',
|
|
1146
|
+
'--no-ext-diff',
|
|
1147
|
+
'--color=never',
|
|
1148
|
+
]);
|
|
1149
|
+
expect(response).toEqual({
|
|
1150
|
+
commit: 'fedcba9 vs Working Directory (all uncommitted changes)',
|
|
1151
|
+
files: [],
|
|
1152
|
+
isEmpty: true,
|
|
1153
|
+
baseCommitish: 'fedcba9',
|
|
1154
|
+
targetCommitish: '.',
|
|
1155
|
+
requestedBaseCommitish: 'origin/main',
|
|
1156
|
+
requestedTargetCommitish: '.',
|
|
1157
|
+
requestedBaseMode: 'merge-base',
|
|
1109
1158
|
});
|
|
1110
1159
|
});
|
|
1111
1160
|
});
|
package/dist/server/server.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { type Server } from 'http';
|
|
2
2
|
import { type DiffMode } from '../types/watch.js';
|
|
3
|
-
import { type CommentImport } from '@/types/diff.js';
|
|
3
|
+
import { type CommentImport, type DiffSelection } from '@/types/diff.js';
|
|
4
4
|
interface ServerOptions {
|
|
5
|
-
|
|
6
|
-
baseCommitish?: string;
|
|
5
|
+
selection?: DiffSelection;
|
|
7
6
|
stdinDiff?: string;
|
|
8
7
|
preferredPort?: number;
|
|
9
8
|
host?: string;
|
package/dist/server/server.js
CHANGED
|
@@ -13,23 +13,56 @@ import { resolveEditorOption } from '../utils/editorOptions.js';
|
|
|
13
13
|
import { getFileExtension } from '../utils/fileUtils.js';
|
|
14
14
|
import { FileWatcherService } from './file-watcher.js';
|
|
15
15
|
import { GitDiffParser } from './git-diff.js';
|
|
16
|
+
import { createDiffSelection, diffSelectionsEqual, getDiffSelectionKey, } from '../utils/diffSelection.js';
|
|
16
17
|
const GENERATED_STATUS_CACHE_TTL_MS = 60_000;
|
|
18
|
+
const MAX_DIFF_CACHE_ENTRIES = 8;
|
|
19
|
+
function createDiffCacheKey(selection, ignoreWhitespace) {
|
|
20
|
+
return `${getDiffSelectionKey(selection)}\u0000${ignoreWhitespace ? '1' : '0'}`;
|
|
21
|
+
}
|
|
22
|
+
function getCachedDiffResponse(cache, key) {
|
|
23
|
+
const cached = cache.get(key);
|
|
24
|
+
if (!cached) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
// Refresh insertion order to keep the most recently used entry.
|
|
28
|
+
cache.delete(key);
|
|
29
|
+
cache.set(key, cached);
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
function setCachedDiffResponse(cache, key, value) {
|
|
33
|
+
if (cache.has(key)) {
|
|
34
|
+
cache.delete(key);
|
|
35
|
+
}
|
|
36
|
+
cache.set(key, value);
|
|
37
|
+
while (cache.size > MAX_DIFF_CACHE_ENTRIES) {
|
|
38
|
+
const oldestKey = cache.keys().next().value;
|
|
39
|
+
if (typeof oldestKey !== 'string') {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
cache.delete(oldestKey);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
17
45
|
export async function startServer(options) {
|
|
18
46
|
const app = express();
|
|
19
47
|
const repositoryPath = resolve(options.repoPath ?? process.cwd());
|
|
20
48
|
const repositoryId = createHash('sha256').update(repositoryPath).digest('hex');
|
|
21
49
|
const initialCommentImports = options.commentImports || [];
|
|
22
|
-
const
|
|
23
|
-
const initialTargetCommitish = options.targetCommitish ?? '';
|
|
50
|
+
const initialSelection = options.selection ?? createDiffSelection('', '');
|
|
24
51
|
const commentImportId = initialCommentImports.length > 0
|
|
25
52
|
? createHash('sha256').update(serializeCommentImports(initialCommentImports)).digest('hex')
|
|
26
53
|
: undefined;
|
|
27
54
|
const parser = new GitDiffParser(repositoryPath);
|
|
28
55
|
const fileWatcher = new FileWatcherService();
|
|
29
56
|
const generatedStatusCache = new Map();
|
|
30
|
-
|
|
31
|
-
|
|
57
|
+
const diffDataCache = new Map();
|
|
58
|
+
const initialIgnoreWhitespace = options.ignoreWhitespace || false;
|
|
32
59
|
const diffMode = normalizeDiffViewMode(options.mode);
|
|
60
|
+
const parseBaseMode = (value) => {
|
|
61
|
+
if (value === 'merge-base') {
|
|
62
|
+
return 'merge-base';
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
};
|
|
33
66
|
app.use(express.json());
|
|
34
67
|
app.use(express.text()); // For sendBeacon text/plain requests
|
|
35
68
|
app.use((_req, res, next) => {
|
|
@@ -40,28 +73,29 @@ export async function startServer(options) {
|
|
|
40
73
|
});
|
|
41
74
|
// Skip validation if using stdin diff
|
|
42
75
|
if (!options.stdinDiff) {
|
|
43
|
-
const isValidCommit = await parser.validateCommit(
|
|
76
|
+
const isValidCommit = await parser.validateCommit(initialSelection.targetCommitish);
|
|
44
77
|
if (!isValidCommit) {
|
|
45
|
-
throw new Error(`Invalid or non-existent commit: ${
|
|
78
|
+
throw new Error(`Invalid or non-existent commit: ${initialSelection.targetCommitish}`);
|
|
46
79
|
}
|
|
47
80
|
}
|
|
48
81
|
// Generate initial diff data for isEmpty check
|
|
82
|
+
let initialDiffData;
|
|
49
83
|
if (options.stdinDiff) {
|
|
50
84
|
// Parse stdin diff directly
|
|
51
|
-
|
|
85
|
+
initialDiffData = parser.parseStdinDiff(options.stdinDiff);
|
|
52
86
|
}
|
|
53
87
|
else {
|
|
54
|
-
|
|
88
|
+
initialDiffData = await parser.parseDiff(initialSelection, initialIgnoreWhitespace, options.contextLines);
|
|
89
|
+
setCachedDiffResponse(diffDataCache, createDiffCacheKey(initialSelection, initialIgnoreWhitespace), initialDiffData);
|
|
55
90
|
}
|
|
56
91
|
// Function to invalidate cache when file changes are detected
|
|
57
92
|
const invalidateCache = () => {
|
|
58
|
-
diffDataCache
|
|
93
|
+
diffDataCache.clear();
|
|
59
94
|
generatedStatusCache.clear();
|
|
60
95
|
parser.clearResolvedCommitCache();
|
|
61
96
|
};
|
|
62
97
|
// Track current revisions for cache invalidation
|
|
63
|
-
let
|
|
64
|
-
let currentTargetCommitish = options.targetCommitish ?? '';
|
|
98
|
+
let currentSelection = initialSelection;
|
|
65
99
|
function parseRepositoryRelativePath(filepath) {
|
|
66
100
|
if (typeof filepath !== 'string' || filepath.length === 0) {
|
|
67
101
|
return { ok: false, error: 'Invalid file path' };
|
|
@@ -79,56 +113,47 @@ export async function startServer(options) {
|
|
|
79
113
|
}
|
|
80
114
|
app.get('/api/diff', async (req, res) => {
|
|
81
115
|
const ignoreWhitespace = req.query.ignoreWhitespace === 'true';
|
|
82
|
-
const
|
|
83
|
-
const
|
|
116
|
+
const hasBase = typeof req.query.base === 'string';
|
|
117
|
+
const hasTarget = typeof req.query.target === 'string';
|
|
118
|
+
const hasBaseMode = typeof req.query.baseMode === 'string';
|
|
119
|
+
const requestedSelection = createDiffSelection(hasBase ? req.query.base : currentSelection.baseCommitish, hasTarget ? req.query.target : currentSelection.targetCommitish, hasBaseMode
|
|
120
|
+
? parseBaseMode(req.query.baseMode)
|
|
121
|
+
: hasBase || hasTarget
|
|
122
|
+
? undefined
|
|
123
|
+
: currentSelection.baseMode);
|
|
84
124
|
const shouldIncludeCommentImports = initialCommentImports.length > 0 &&
|
|
85
|
-
(Boolean(options.stdinDiff) ||
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
currentBaseCommitish = requestedBase;
|
|
94
|
-
currentTargetCommitish = requestedTarget;
|
|
95
|
-
diffDataCache = await parser.parseDiff(requestedTarget, requestedBase, ignoreWhitespace, options.contextLines);
|
|
96
|
-
generatedStatusCache.clear();
|
|
97
|
-
}
|
|
98
|
-
// Resolve symbolic refs like HEAD/HEAD^ to actual hashes for the UI
|
|
99
|
-
let resolvedBase = currentBaseCommitish || 'stdin';
|
|
100
|
-
let resolvedTarget = currentTargetCommitish || 'stdin';
|
|
101
|
-
if (!options.stdinDiff &&
|
|
102
|
-
currentBaseCommitish &&
|
|
103
|
-
!['working', 'staged', '.'].includes(currentBaseCommitish)) {
|
|
104
|
-
try {
|
|
105
|
-
resolvedBase = await parser.resolveCommitish(currentBaseCommitish);
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
// If resolution fails, keep original value
|
|
125
|
+
(Boolean(options.stdinDiff) || diffSelectionsEqual(requestedSelection, initialSelection));
|
|
126
|
+
currentSelection = requestedSelection;
|
|
127
|
+
let responseDiffData = initialDiffData;
|
|
128
|
+
if (!options.stdinDiff) {
|
|
129
|
+
const cacheKey = createDiffCacheKey(requestedSelection, ignoreWhitespace);
|
|
130
|
+
const cached = getCachedDiffResponse(diffDataCache, cacheKey);
|
|
131
|
+
if (cached) {
|
|
132
|
+
responseDiffData = cached;
|
|
109
133
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
resolvedTarget = await parser.resolveCommitish(currentTargetCommitish);
|
|
116
|
-
}
|
|
117
|
-
catch {
|
|
118
|
-
// If resolution fails, keep original value
|
|
134
|
+
else {
|
|
135
|
+
responseDiffData = await parser.parseDiff(requestedSelection, ignoreWhitespace, options.contextLines);
|
|
136
|
+
setCachedDiffResponse(diffDataCache, cacheKey, responseDiffData);
|
|
137
|
+
generatedStatusCache.clear();
|
|
119
138
|
}
|
|
120
139
|
}
|
|
121
|
-
const
|
|
122
|
-
const
|
|
140
|
+
const baseCommitish = responseDiffData.baseCommitish ?? (options.stdinDiff ? 'stdin' : undefined);
|
|
141
|
+
const targetCommitish = responseDiffData.targetCommitish ?? (options.stdinDiff ? 'stdin' : undefined);
|
|
142
|
+
const requestedBaseCommitish = responseDiffData.requestedBaseCommitish ??
|
|
143
|
+
(requestedSelection.baseCommitish || (options.stdinDiff ? 'stdin' : undefined));
|
|
144
|
+
const requestedTargetCommitish = responseDiffData.requestedTargetCommitish ??
|
|
145
|
+
(requestedSelection.targetCommitish || (options.stdinDiff ? 'stdin' : undefined));
|
|
146
|
+
const requestedBaseMode = responseDiffData.requestedBaseMode ?? requestedSelection.baseMode;
|
|
123
147
|
res.json({
|
|
124
|
-
...
|
|
148
|
+
...responseDiffData,
|
|
125
149
|
ignoreWhitespace,
|
|
126
150
|
mode: diffMode,
|
|
127
151
|
openInEditorAvailable: !options.stdinDiff,
|
|
128
|
-
baseCommitish
|
|
129
|
-
targetCommitish
|
|
152
|
+
baseCommitish,
|
|
153
|
+
targetCommitish,
|
|
130
154
|
requestedBaseCommitish,
|
|
131
155
|
requestedTargetCommitish,
|
|
156
|
+
requestedBaseMode,
|
|
132
157
|
clearComments: options.clearComments,
|
|
133
158
|
repositoryId,
|
|
134
159
|
commentImports: shouldIncludeCommentImports ? initialCommentImports : undefined,
|
|
@@ -147,7 +172,7 @@ export async function startServer(options) {
|
|
|
147
172
|
return;
|
|
148
173
|
}
|
|
149
174
|
const normalizedFilepath = filepathResult.path;
|
|
150
|
-
const ref = req.query.ref ||
|
|
175
|
+
const ref = req.query.ref || currentSelection.targetCommitish || 'HEAD';
|
|
151
176
|
const cacheKey = `${ref}:${normalizedFilepath}`;
|
|
152
177
|
const now = Date.now();
|
|
153
178
|
const cached = generatedStatusCache.get(cacheKey);
|
|
@@ -179,7 +204,7 @@ export async function startServer(options) {
|
|
|
179
204
|
return;
|
|
180
205
|
}
|
|
181
206
|
try {
|
|
182
|
-
const { branches, commits, originDefaultBranch, resolvedBase, resolvedTarget } = await parser.getRevisionOptions(
|
|
207
|
+
const { branches, commits, originDefaultBranch, resolvedBase, resolvedTarget } = await parser.getRevisionOptions(currentSelection.baseCommitish, currentSelection.targetCommitish);
|
|
183
208
|
const response = {
|
|
184
209
|
specialOptions: [
|
|
185
210
|
{ value: '.', label: 'All Uncommitted Changes' },
|
|
@@ -528,7 +553,7 @@ export async function startServer(options) {
|
|
|
528
553
|
}
|
|
529
554
|
}
|
|
530
555
|
// Check if diff is empty and skip browser opening
|
|
531
|
-
if (
|
|
556
|
+
if (initialDiffData.isEmpty) {
|
|
532
557
|
// Don't open browser if no differences found
|
|
533
558
|
}
|
|
534
559
|
else if (options.openBrowser) {
|
|
@@ -539,7 +564,7 @@ export async function startServer(options) {
|
|
|
539
564
|
console.warn('Failed to open browser automatically');
|
|
540
565
|
}
|
|
541
566
|
}
|
|
542
|
-
return { port, url, isEmpty:
|
|
567
|
+
return { port, url, isEmpty: initialDiffData.isEmpty || false, server };
|
|
543
568
|
}
|
|
544
569
|
async function startServerWithFallback(app, preferredPort, host) {
|
|
545
570
|
return new Promise((resolve, reject) => {
|