difit 2.2.1 → 2.2.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/LICENSE +2 -2
- package/README.ja.md +4 -1
- package/README.ko.md +4 -1
- package/README.md +4 -1
- package/README.zh.md +4 -1
- package/dist/cli/index.js +0 -0
- package/dist/client/assets/index-D4o04IuQ.css +1 -0
- package/dist/client/assets/{index-KydrgTN-.js → index-DdgLWfl6.js} +70 -70
- package/dist/client/assets/{prism-csharp-R5PE7dGT.js → prism-csharp-DNLu89K5.js} +1 -1
- package/dist/client/assets/{prism-java-BvQgUZlL.js → prism-java-DPmqUWjf.js} +1 -1
- package/dist/client/assets/{prism-php-sGBBrTD-.js → prism-php-BERkcwmm.js} +1 -1
- package/dist/client/assets/{prism-ruby-CBz5QFG3.js → prism-ruby-BWOjhenp.js} +1 -1
- package/dist/client/assets/{prism-solidity-Ck6Q6Nkr.js → prism-solidity-CD2S3KYq.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/git-diff.d.ts +4 -0
- package/dist/server/git-diff.js +131 -7
- package/dist/server/git-diff.test.js +318 -0
- package/dist/server/server.js +2 -1
- package/dist/types/diff.d.ts +2 -1
- package/package.json +4 -3
- package/dist/client/assets/index-Bz9yRRZ7.css +0 -1
- package/dist/server/schemas/commentSchema.d.ts +0 -22
- package/dist/server/schemas/commentSchema.js +0 -16
- package/dist/server/schemas/commentSchema.test.d.ts +0 -1
- package/dist/server/schemas/commentSchema.test.js +0 -229
- package/dist/utils/commentFormatter.d.ts +0 -26
- package/dist/utils/commentFormatter.js +0 -50
- package/dist/utils/gitUtils.d.ts +0 -4
- package/dist/utils/gitUtils.js +0 -29
- package/dist/utils/gitUtils.test.d.ts +0 -1
- package/dist/utils/gitUtils.test.js +0 -63
|
@@ -114,8 +114,10 @@ describe('GitDiffParser', () => {
|
|
|
114
114
|
'Binary files /dev/null and b/image.jpg differ',
|
|
115
115
|
];
|
|
116
116
|
const summary = {
|
|
117
|
+
file: 'image.jpg',
|
|
117
118
|
insertions: 0,
|
|
118
119
|
deletions: 0,
|
|
120
|
+
binary: true,
|
|
119
121
|
};
|
|
120
122
|
// Access private method for testing
|
|
121
123
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
@@ -138,8 +140,10 @@ describe('GitDiffParser', () => {
|
|
|
138
140
|
'Binary files a/old-image.png and /dev/null differ',
|
|
139
141
|
];
|
|
140
142
|
const summary = {
|
|
143
|
+
file: 'old-image.png',
|
|
141
144
|
insertions: 0,
|
|
142
145
|
deletions: 0,
|
|
146
|
+
binary: true,
|
|
143
147
|
};
|
|
144
148
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
145
149
|
expect(result).toEqual({
|
|
@@ -160,8 +164,10 @@ describe('GitDiffParser', () => {
|
|
|
160
164
|
'Binary files a/photo.jpg and b/photo.jpg differ',
|
|
161
165
|
];
|
|
162
166
|
const summary = {
|
|
167
|
+
file: 'photo.jpg',
|
|
163
168
|
insertions: 0,
|
|
164
169
|
deletions: 0,
|
|
170
|
+
binary: true,
|
|
165
171
|
};
|
|
166
172
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
167
173
|
expect(result).toEqual({
|
|
@@ -181,8 +187,11 @@ describe('GitDiffParser', () => {
|
|
|
181
187
|
'rename to new-name.gif',
|
|
182
188
|
];
|
|
183
189
|
const summary = {
|
|
190
|
+
file: 'new-name.gif',
|
|
191
|
+
from: 'old-name.gif',
|
|
184
192
|
insertions: 0,
|
|
185
193
|
deletions: 0,
|
|
194
|
+
binary: true,
|
|
186
195
|
};
|
|
187
196
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
188
197
|
expect(result).toEqual({
|
|
@@ -206,8 +215,10 @@ describe('GitDiffParser', () => {
|
|
|
206
215
|
' // end',
|
|
207
216
|
];
|
|
208
217
|
const summary = {
|
|
218
|
+
file: 'script.js',
|
|
209
219
|
insertions: 1,
|
|
210
220
|
deletions: 0,
|
|
221
|
+
binary: false,
|
|
211
222
|
};
|
|
212
223
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
213
224
|
expect(result).toEqual({
|
|
@@ -234,8 +245,10 @@ describe('GitDiffParser', () => {
|
|
|
234
245
|
' // end',
|
|
235
246
|
];
|
|
236
247
|
const summary = {
|
|
248
|
+
file: 'script.js',
|
|
237
249
|
insertions: 0,
|
|
238
250
|
deletions: 1,
|
|
251
|
+
binary: false,
|
|
239
252
|
};
|
|
240
253
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
241
254
|
expect(result).toEqual({
|
|
@@ -258,8 +271,10 @@ describe('GitDiffParser', () => {
|
|
|
258
271
|
'+line 2',
|
|
259
272
|
];
|
|
260
273
|
const summary = {
|
|
274
|
+
file: 'new-file.txt',
|
|
261
275
|
insertions: 2,
|
|
262
276
|
deletions: 0,
|
|
277
|
+
binary: false,
|
|
263
278
|
};
|
|
264
279
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
265
280
|
expect(result.status).toBe('added');
|
|
@@ -275,13 +290,312 @@ describe('GitDiffParser', () => {
|
|
|
275
290
|
'-line 2',
|
|
276
291
|
];
|
|
277
292
|
const summary = {
|
|
293
|
+
file: 'deleted-file.txt',
|
|
278
294
|
insertions: 0,
|
|
279
295
|
deletions: 2,
|
|
296
|
+
binary: false,
|
|
280
297
|
};
|
|
281
298
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
282
299
|
expect(result.status).toBe('deleted');
|
|
283
300
|
});
|
|
284
301
|
});
|
|
302
|
+
describe('parseFileBlock with quoted paths', () => {
|
|
303
|
+
it('parses file paths with spaces correctly', () => {
|
|
304
|
+
const diffLines = [
|
|
305
|
+
'diff --git "a/test with spaces/file name.txt" "b/test with spaces/file name.txt"',
|
|
306
|
+
'new file mode 100644',
|
|
307
|
+
'index 0000000..257cc56',
|
|
308
|
+
'--- /dev/null',
|
|
309
|
+
'+++ "b/test with spaces/file name.txt"',
|
|
310
|
+
'@@ -0,0 +1 @@',
|
|
311
|
+
'+foo',
|
|
312
|
+
];
|
|
313
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
314
|
+
expect(result).toBeDefined();
|
|
315
|
+
expect(result.path).toBe('test with spaces/file name.txt');
|
|
316
|
+
expect(result.status).toBe('added');
|
|
317
|
+
expect(result.additions).toBe(1);
|
|
318
|
+
expect(result.deletions).toBe(0);
|
|
319
|
+
});
|
|
320
|
+
it('parses summary-provided filenames with escaped spaces', () => {
|
|
321
|
+
const diffLines = [
|
|
322
|
+
'diff --git "a/templates/test file.py" "b/templates/test file.py"',
|
|
323
|
+
'index abc123..def456 100644',
|
|
324
|
+
'--- "a/templates/test file.py"',
|
|
325
|
+
'+++ "b/templates/test file.py"',
|
|
326
|
+
'@@ -1 +1 @@',
|
|
327
|
+
'-old',
|
|
328
|
+
'+new',
|
|
329
|
+
];
|
|
330
|
+
const summary = {
|
|
331
|
+
file: 'templates/test\\040file.py',
|
|
332
|
+
insertions: 1,
|
|
333
|
+
deletions: 1,
|
|
334
|
+
binary: false,
|
|
335
|
+
};
|
|
336
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
337
|
+
expect(result?.path).toBe('templates/test file.py');
|
|
338
|
+
expect(result?.oldPath).toBeUndefined();
|
|
339
|
+
});
|
|
340
|
+
it('parses file paths with Jinja template brackets correctly', () => {
|
|
341
|
+
const diffLines = [
|
|
342
|
+
'diff --git "a/templates/test_000_{{ package_name }}/__.py" "b/templates/test_000_{{ package_name }}/__.py"',
|
|
343
|
+
'new file mode 100644',
|
|
344
|
+
'index 0000000..257cc56',
|
|
345
|
+
'--- /dev/null',
|
|
346
|
+
'+++ "b/templates/test_000_{{ package_name }}/__.py"',
|
|
347
|
+
'@@ -0,0 +1 @@',
|
|
348
|
+
'+test',
|
|
349
|
+
];
|
|
350
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
351
|
+
expect(result).toBeDefined();
|
|
352
|
+
expect(result.path).toBe('templates/test_000_{{ package_name }}/__.py');
|
|
353
|
+
expect(result.status).toBe('added');
|
|
354
|
+
});
|
|
355
|
+
it('parses file paths with escaped characters correctly', () => {
|
|
356
|
+
const diffLines = [
|
|
357
|
+
'diff --git "a/file\\twith\\ttabs.txt" "b/file\\twith\\ttabs.txt"',
|
|
358
|
+
'new file mode 100644',
|
|
359
|
+
'index 0000000..257cc56',
|
|
360
|
+
'--- /dev/null',
|
|
361
|
+
'+++ "b/file\\twith\\ttabs.txt"',
|
|
362
|
+
'@@ -0,0 +1 @@',
|
|
363
|
+
'+content',
|
|
364
|
+
];
|
|
365
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
366
|
+
expect(result).toBeDefined();
|
|
367
|
+
expect(result.path).toBe('file\twith\ttabs.txt');
|
|
368
|
+
expect(result.status).toBe('added');
|
|
369
|
+
});
|
|
370
|
+
it('parses renamed files with spaces correctly', () => {
|
|
371
|
+
const diffLines = [
|
|
372
|
+
'diff --git "a/old folder/old name.txt" "b/new folder/new name.txt"',
|
|
373
|
+
'similarity index 100%',
|
|
374
|
+
'rename from old folder/old name.txt',
|
|
375
|
+
'rename to new folder/new name.txt',
|
|
376
|
+
];
|
|
377
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
378
|
+
expect(result).toBeDefined();
|
|
379
|
+
expect(result.path).toBe('new folder/new name.txt');
|
|
380
|
+
expect(result.oldPath).toBe('old folder/old name.txt');
|
|
381
|
+
expect(result.status).toBe('renamed');
|
|
382
|
+
});
|
|
383
|
+
it('still handles unquoted paths correctly', () => {
|
|
384
|
+
const diffLines = [
|
|
385
|
+
'diff --git a/src/file.js b/src/file.js',
|
|
386
|
+
'index 1234567..8901234 100644',
|
|
387
|
+
'--- a/src/file.js',
|
|
388
|
+
'+++ b/src/file.js',
|
|
389
|
+
'@@ -1,3 +1,3 @@',
|
|
390
|
+
' line1',
|
|
391
|
+
'-old',
|
|
392
|
+
'+new',
|
|
393
|
+
' line3',
|
|
394
|
+
];
|
|
395
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
396
|
+
expect(result).toBeDefined();
|
|
397
|
+
expect(result.path).toBe('src/file.js');
|
|
398
|
+
expect(result.status).toBe('modified');
|
|
399
|
+
expect(result.additions).toBe(1);
|
|
400
|
+
expect(result.deletions).toBe(1);
|
|
401
|
+
});
|
|
402
|
+
it('handles unquoted paths with spaces when core.quotePath=false', () => {
|
|
403
|
+
const diffLines = [
|
|
404
|
+
'diff --git a/path with spaces/file.txt b/path with spaces/file.txt',
|
|
405
|
+
'index 1234567..8901234 100644',
|
|
406
|
+
'--- a/path with spaces/file.txt',
|
|
407
|
+
'+++ b/path with spaces/file.txt',
|
|
408
|
+
'@@ -1 +1 @@',
|
|
409
|
+
'-old content',
|
|
410
|
+
'+new content',
|
|
411
|
+
];
|
|
412
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
413
|
+
expect(result).toBeDefined();
|
|
414
|
+
expect(result.path).toBe('path with spaces/file.txt');
|
|
415
|
+
expect(result.status).toBe('modified');
|
|
416
|
+
expect(result.additions).toBe(1);
|
|
417
|
+
expect(result.deletions).toBe(1);
|
|
418
|
+
});
|
|
419
|
+
it('decodes unquoted octal escapes in diff headers', () => {
|
|
420
|
+
const diffLines = [
|
|
421
|
+
'diff --git a/some\\040folder/file\\040name.ts b/some\\040folder/file\\040name.ts',
|
|
422
|
+
'index 3333333..4444444 100644',
|
|
423
|
+
'--- a/some\\040folder/file\\040name.ts',
|
|
424
|
+
'+++ b/some\\040folder/file\\040name.ts',
|
|
425
|
+
'@@ -1 +1 @@',
|
|
426
|
+
'-old',
|
|
427
|
+
'+new',
|
|
428
|
+
];
|
|
429
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
430
|
+
expect(result?.path).toBe('some folder/file name.ts');
|
|
431
|
+
expect(result?.oldPath).toBeUndefined();
|
|
432
|
+
});
|
|
433
|
+
it('handles unquoted paths containing "b/" in filename', () => {
|
|
434
|
+
const diffLines = [
|
|
435
|
+
'diff --git a/dir b/sub/file b/dir b/sub/file',
|
|
436
|
+
'index 1234567..8901234 100644',
|
|
437
|
+
'--- a/dir b/sub/file',
|
|
438
|
+
'+++ b/dir b/sub/file',
|
|
439
|
+
'@@ -1 +1 @@',
|
|
440
|
+
'-old',
|
|
441
|
+
'+new',
|
|
442
|
+
];
|
|
443
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
444
|
+
expect(result).toBeDefined();
|
|
445
|
+
expect(result.path).toBe('dir b/sub/file');
|
|
446
|
+
expect(result.oldPath).toBeUndefined();
|
|
447
|
+
expect(result.status).toBe('modified');
|
|
448
|
+
});
|
|
449
|
+
it('handles renamed files with "b/" in the path', () => {
|
|
450
|
+
const diffLines = [
|
|
451
|
+
'diff --git a/old b/path/file b/new b/path/file',
|
|
452
|
+
'similarity index 100%',
|
|
453
|
+
'rename from old b/path/file',
|
|
454
|
+
'rename to new b/path/file',
|
|
455
|
+
];
|
|
456
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
457
|
+
expect(result).toBeDefined();
|
|
458
|
+
expect(result.path).toBe('new b/path/file');
|
|
459
|
+
expect(result.oldPath).toBe('old b/path/file');
|
|
460
|
+
expect(result.status).toBe('renamed');
|
|
461
|
+
});
|
|
462
|
+
it('handles alternative git diff prefixes for working tree comparisons', () => {
|
|
463
|
+
const diffLines = [
|
|
464
|
+
'diff --git c/a/test.txt w/a/test.txt',
|
|
465
|
+
'index 1234567..8901234 100644',
|
|
466
|
+
'--- c/a/test.txt',
|
|
467
|
+
'+++ w/a/test.txt\t',
|
|
468
|
+
'@@ -1 +1 @@',
|
|
469
|
+
'-old',
|
|
470
|
+
'+new',
|
|
471
|
+
];
|
|
472
|
+
const summary = {
|
|
473
|
+
file: 'a/test.txt',
|
|
474
|
+
insertions: 1,
|
|
475
|
+
deletions: 1,
|
|
476
|
+
binary: false,
|
|
477
|
+
};
|
|
478
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
479
|
+
expect(result).toBeDefined();
|
|
480
|
+
expect(result.path).toBe('a/test.txt');
|
|
481
|
+
expect(result.oldPath).toBeUndefined();
|
|
482
|
+
expect(result.status).toBe('modified');
|
|
483
|
+
});
|
|
484
|
+
it('handles rename metadata with alternative git prefixes', () => {
|
|
485
|
+
const diffLines = [
|
|
486
|
+
'diff --git c/old/name.txt w/new/name.txt',
|
|
487
|
+
'similarity index 100%',
|
|
488
|
+
'rename from c/old/name.txt\t',
|
|
489
|
+
'rename to w/new/name.txt\t',
|
|
490
|
+
];
|
|
491
|
+
const summary = {
|
|
492
|
+
file: 'new/name.txt',
|
|
493
|
+
from: 'old/name.txt',
|
|
494
|
+
insertions: 0,
|
|
495
|
+
deletions: 0,
|
|
496
|
+
binary: false,
|
|
497
|
+
};
|
|
498
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
499
|
+
expect(result).toBeDefined();
|
|
500
|
+
expect(result.path).toBe('new/name.txt');
|
|
501
|
+
expect(result.oldPath).toBe('old/name.txt');
|
|
502
|
+
expect(result.status).toBe('renamed');
|
|
503
|
+
});
|
|
504
|
+
it('ignores trailing metadata separators in diff path lines', () => {
|
|
505
|
+
const diffLines = [
|
|
506
|
+
'diff --git c/foo bar.txt w/foo bar.txt',
|
|
507
|
+
'index 1234567..8901234 100644',
|
|
508
|
+
'--- c/foo bar.txt\t',
|
|
509
|
+
'+++ w/foo bar.txt\t',
|
|
510
|
+
'@@ -1 +1 @@',
|
|
511
|
+
'-old',
|
|
512
|
+
'+new',
|
|
513
|
+
];
|
|
514
|
+
const summary = {
|
|
515
|
+
file: 'foo bar.txt',
|
|
516
|
+
insertions: 1,
|
|
517
|
+
deletions: 1,
|
|
518
|
+
binary: false,
|
|
519
|
+
};
|
|
520
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
521
|
+
expect(result).toBeDefined();
|
|
522
|
+
expect(result.path).toBe('foo bar.txt');
|
|
523
|
+
expect(result.status).toBe('modified');
|
|
524
|
+
});
|
|
525
|
+
it('prefers header paths over summary paths when they differ', () => {
|
|
526
|
+
const diffLines = [
|
|
527
|
+
'diff --git a/a/test.txt b/a/test.txt',
|
|
528
|
+
'new file mode 100644',
|
|
529
|
+
'index 0000000..257cc56',
|
|
530
|
+
'--- /dev/null',
|
|
531
|
+
'+++ b/a/test.txt',
|
|
532
|
+
'@@ -0,0 +1 @@',
|
|
533
|
+
'+content',
|
|
534
|
+
];
|
|
535
|
+
const summary = {
|
|
536
|
+
file: 'a/test.txt',
|
|
537
|
+
insertions: 1,
|
|
538
|
+
deletions: 0,
|
|
539
|
+
binary: false,
|
|
540
|
+
};
|
|
541
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
542
|
+
expect(result).toBeDefined();
|
|
543
|
+
expect(result?.path).toBe('a/test.txt');
|
|
544
|
+
expect(result?.status).toBe('added');
|
|
545
|
+
});
|
|
546
|
+
it('does not treat added files as renamed even if summary includes from path', () => {
|
|
547
|
+
const diffLines = [
|
|
548
|
+
'diff --git a/test.js b/test.js',
|
|
549
|
+
'new file mode 100644',
|
|
550
|
+
'index 0000000..257cc56',
|
|
551
|
+
'--- /dev/null',
|
|
552
|
+
'+++ b/test.js',
|
|
553
|
+
'@@ -0,0 +1 @@',
|
|
554
|
+
'+console.log("test");',
|
|
555
|
+
];
|
|
556
|
+
const summary = {
|
|
557
|
+
file: 'test.js',
|
|
558
|
+
from: 'c/test.js',
|
|
559
|
+
insertions: 1,
|
|
560
|
+
deletions: 0,
|
|
561
|
+
binary: false,
|
|
562
|
+
};
|
|
563
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
564
|
+
expect(result).toBeDefined();
|
|
565
|
+
expect(result?.status).toBe('added');
|
|
566
|
+
expect(result?.oldPath).toBeUndefined();
|
|
567
|
+
});
|
|
568
|
+
it('parses file paths with octal escape sequences correctly', () => {
|
|
569
|
+
const diffLines = [
|
|
570
|
+
'diff --git "a/file\\303\\244.txt" "b/file\\303\\244.txt"',
|
|
571
|
+
'new file mode 100644',
|
|
572
|
+
'index 0000000..257cc56',
|
|
573
|
+
'--- /dev/null',
|
|
574
|
+
'+++ "b/file\\303\\244.txt"',
|
|
575
|
+
'@@ -0,0 +1 @@',
|
|
576
|
+
'+content',
|
|
577
|
+
];
|
|
578
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
579
|
+
expect(result).toBeDefined();
|
|
580
|
+
expect(result.path).toBe('fileä.txt');
|
|
581
|
+
expect(result.status).toBe('added');
|
|
582
|
+
});
|
|
583
|
+
it('parses file paths with mixed escape sequences correctly', () => {
|
|
584
|
+
const diffLines = [
|
|
585
|
+
'diff --git "a/dir\\303\\251/file\\twith\\nmixed.txt" "b/dir\\303\\251/file\\twith\\nmixed.txt"',
|
|
586
|
+
'new file mode 100644',
|
|
587
|
+
'index 0000000..257cc56',
|
|
588
|
+
'--- /dev/null',
|
|
589
|
+
'+++ "b/dir\\303\\251/file\\twith\\nmixed.txt"',
|
|
590
|
+
'@@ -0,0 +1 @@',
|
|
591
|
+
'+test',
|
|
592
|
+
];
|
|
593
|
+
const result = parser.parseFileBlock(diffLines.join('\n'), null);
|
|
594
|
+
expect(result).toBeDefined();
|
|
595
|
+
expect(result.path).toBe('diré/file\twith\nmixed.txt');
|
|
596
|
+
expect(result.status).toBe('added');
|
|
597
|
+
});
|
|
598
|
+
});
|
|
285
599
|
describe('File status detection improvements', () => {
|
|
286
600
|
it('prioritizes new file mode over other indicators', () => {
|
|
287
601
|
const diffLines = [
|
|
@@ -292,8 +606,10 @@ describe('GitDiffParser', () => {
|
|
|
292
606
|
'+++ b/test.txt',
|
|
293
607
|
];
|
|
294
608
|
const summary = {
|
|
609
|
+
file: 'test.txt',
|
|
295
610
|
insertions: 5,
|
|
296
611
|
deletions: 0,
|
|
612
|
+
binary: false,
|
|
297
613
|
};
|
|
298
614
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
299
615
|
expect(result.status).toBe('added');
|
|
@@ -307,8 +623,10 @@ describe('GitDiffParser', () => {
|
|
|
307
623
|
'+++ b/test.txt', // This might confuse simple parsers
|
|
308
624
|
];
|
|
309
625
|
const summary = {
|
|
626
|
+
file: 'test.txt',
|
|
310
627
|
insertions: 0,
|
|
311
628
|
deletions: 5,
|
|
629
|
+
binary: false,
|
|
312
630
|
};
|
|
313
631
|
const result = parser.parseFileBlock(diffLines.join('\n'), summary);
|
|
314
632
|
expect(result.status).toBe('deleted');
|
package/dist/server/server.js
CHANGED
|
@@ -14,7 +14,8 @@ export async function startServer(options) {
|
|
|
14
14
|
const fileWatcher = new FileWatcherService();
|
|
15
15
|
let diffDataCache = null;
|
|
16
16
|
let currentIgnoreWhitespace = options.ignoreWhitespace || false;
|
|
17
|
-
const
|
|
17
|
+
const normalizeDiffMode = (mode) => mode === 'inline' ? 'inline' : 'side-by-side';
|
|
18
|
+
const diffMode = normalizeDiffMode(options.mode);
|
|
18
19
|
app.use(express.json());
|
|
19
20
|
app.use(express.text()); // For sendBeacon text/plain requests
|
|
20
21
|
app.use((_req, res, next) => {
|
package/dist/types/diff.d.ts
CHANGED
|
@@ -30,12 +30,13 @@ export interface DiffLine {
|
|
|
30
30
|
export interface ParsedDiff {
|
|
31
31
|
chunks: DiffChunk[];
|
|
32
32
|
}
|
|
33
|
+
export type DiffViewMode = 'side-by-side' | 'inline';
|
|
33
34
|
export interface DiffResponse {
|
|
34
35
|
commit: string;
|
|
35
36
|
files: DiffFile[];
|
|
36
37
|
ignoreWhitespace?: boolean;
|
|
37
38
|
isEmpty?: boolean;
|
|
38
|
-
mode?:
|
|
39
|
+
mode?: DiffViewMode;
|
|
39
40
|
baseCommitish?: string;
|
|
40
41
|
targetCommitish?: string;
|
|
41
42
|
clearComments?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "difit",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "A lightweight command-line tool that spins up a local web server to display Git commit diffs in a GitHub-like Files changed view",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dracula-prism": "^2.1.16",
|
|
47
47
|
"express": "^5.1.0",
|
|
48
48
|
"ink": "^6.0.1",
|
|
49
|
-
"lucide-react": "^0.
|
|
49
|
+
"lucide-react": "^0.544.0",
|
|
50
50
|
"open": "^10.1.2",
|
|
51
51
|
"prism-react-renderer": "^2.4.1",
|
|
52
52
|
"prism-themes": "^1.9.0",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"globals": "^16.3.0",
|
|
85
85
|
"happy-dom": "^18.0.1",
|
|
86
86
|
"lefthook": "^1.11.14",
|
|
87
|
+
"mri": "^1.2.0",
|
|
87
88
|
"playwright": "^1.54.1",
|
|
88
89
|
"postcss": "^8.5.6",
|
|
89
90
|
"prettier": "^3.6.2",
|
|
@@ -113,5 +114,5 @@
|
|
|
113
114
|
"publishConfig": {
|
|
114
115
|
"access": "public"
|
|
115
116
|
},
|
|
116
|
-
"packageManager": "pnpm@10.
|
|
117
|
+
"packageManager": "pnpm@10.18.1"
|
|
117
118
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-100:oklch(93.6% .032 17.717);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-600:oklch(68.1% .162 75.834);--color-green-100:oklch(96.2% .044 156.743);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-semibold:600;--radius-md:.375rem;--radius-lg:.5rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-github-bg-primary:#0d1117;--color-github-bg-secondary:#161b22;--color-github-bg-tertiary:#21262d;--color-github-border:#30363d;--color-github-text-primary:#f0f6fc;--color-github-text-secondary:#8b949e;--color-github-text-muted:#6e7681;--color-github-accent:#238636;--color-github-danger:#da3633;--color-github-warning:#d29922;--color-diff-addition-bg:#0d4429;--color-diff-addition-border:#1b7c3d;--color-diff-deletion-bg:#67060c;--color-diff-deletion-border:#da3633;--color-diff-neutral-bg:#21262d;--color-diff-selected-bg:#ae7c1426;--color-diff-selected-border:#ae7c1466;--color-comment-bg:#1c2128;--color-comment-border:#373e47;--color-comment-text:#e6edf3}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.-right-2{right:calc(var(--spacing)*-2)}.right-0{right:calc(var(--spacing)*0)}.left-0{left:calc(var(--spacing)*0)}.left-3{left:calc(var(--spacing)*3)}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing)*0)}.m-2{margin:calc(var(--spacing)*2)}.mx-3{margin-inline:calc(var(--spacing)*3)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-2{height:calc(var(--spacing)*2)}.h-4{height:calc(var(--spacing)*4)}.h-7{height:calc(var(--spacing)*7)}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:calc(var(--spacing)*96)}.max-h-\[80vh\]{max-height:80vh}.max-h-\[calc\(80vh-120px\)\]{max-height:calc(80vh - 120px)}.min-h-\[16px\]{min-height:16px}.min-h-\[20px\]{min-height:20px}.min-h-\[60px\]{min-height:60px}.w-1\/2{width:50%}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-7{width:calc(var(--spacing)*7)}.w-8{width:calc(var(--spacing)*8)}.w-\[50px\]{width:50px}.w-\[60px\]{width:60px}.w-full{width:100%}.max-w-4xl{max-width:var(--container-4xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:calc(var(--spacing)*0)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-none{--tw-border-style:none;border-style:none}.border-github-accent{border-color:var(--color-github-accent)}.border-github-border{border-color:var(--color-github-border)}.border-github-text-muted{border-color:var(--color-github-text-muted)}.border-github-text-primary{border-color:var(--color-github-text-primary)}.border-yellow-600\/50{border-color:#cd890080}@supports (color:color-mix(in lab,red,red)){.border-yellow-600\/50{border-color:color-mix(in oklab,var(--color-yellow-600)50%,transparent)}}.border-t-github-accent{border-top-color:var(--color-github-accent)}.border-l-yellow-400{border-left-color:var(--color-yellow-400)}.bg-\[var\(--bg-secondary\)\]{background-color:var(--bg-secondary)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-diff-addition-bg{background-color:var(--color-diff-addition-bg)}.bg-diff-deletion-bg{background-color:var(--color-diff-deletion-bg)}.bg-github-accent{background-color:var(--color-github-accent)}.bg-github-bg-primary{background-color:var(--color-github-bg-primary)}.bg-github-bg-secondary{background-color:var(--color-github-bg-secondary)}.bg-github-bg-tertiary{background-color:var(--color-github-bg-tertiary)}.bg-github-border{background-color:var(--color-github-border)}.bg-github-text-primary{background-color:var(--color-github-text-primary)}.bg-green-100\/10{background-color:#dcfce71a}@supports (color:color-mix(in lab,red,red)){.bg-green-100\/10{background-color:color-mix(in oklab,var(--color-green-100)10%,transparent)}}.bg-red-100\/10{background-color:#ffe2e21a}@supports (color:color-mix(in lab,red,red)){.bg-red-100\/10{background-color:color-mix(in oklab,var(--color-red-100)10%,transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-5{padding-inline:calc(var(--spacing)*5)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-3{padding-right:calc(var(--spacing)*3)}.pr-5{padding-right:calc(var(--spacing)*5)}.pb-px{padding-bottom:1px}.pl-9{padding-left:calc(var(--spacing)*9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-6{--tw-leading:calc(var(--spacing)*6);line-height:calc(var(--spacing)*6)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-all{word-break:break-all}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-github-accent{color:var(--color-github-accent)}.text-github-bg-primary{color:var(--color-github-bg-primary)}.text-github-danger{color:var(--color-github-danger)}.text-github-text-muted{color:var(--color-github-text-muted)}.text-github-text-primary{color:var(--color-github-text-primary)}.text-github-text-secondary{color:var(--color-github-text-secondary)}.text-github-warning{color:var(--color-github-warning)}.text-green-600{color:var(--color-green-600)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.placeholder-github-text-muted::-moz-placeholder{color:var(--color-github-text-muted)}.placeholder-github-text-muted::placeholder{color:var(--color-github-text-muted)}.accent-github-accent{accent-color:var(--color-github-accent)}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-blue-500{--tw-ring-color:var(--color-blue-500)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.\!transition-all{transition-property:all!important;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function))!important;transition-duration:var(--tw-duration,var(--default-transition-duration))!important}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.\!duration-300{--tw-duration:.3s!important;transition-duration:.3s!important}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.\!ease-in-out{--tw-ease:var(--ease-in-out)!important;transition-timing-function:var(--ease-in-out)!important}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-text{-webkit-user-select:text;-moz-user-select:text;user-select:text}.after\:pointer-events-none:after{content:var(--tw-content);pointer-events:none}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-0:after{content:var(--tw-content);inset:calc(var(--spacing)*0)}.after\:border-t-2:after{content:var(--tw-content);border-top-style:var(--tw-border-style);border-top-width:2px}.after\:border-b-2:after{content:var(--tw-content);border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.after\:border-l-4:after{content:var(--tw-content);border-left-style:var(--tw-border-style);border-left-width:4px}.after\:border-l-5:after{content:var(--tw-content);border-left-style:var(--tw-border-style);border-left-width:5px}.after\:border-blue-500:after{content:var(--tw-content);border-color:var(--color-blue-500)}.after\:border-l-diff-selected-border:after{content:var(--tw-content);border-left-color:var(--color-diff-selected-border)}.after\:bg-blue-100:after{content:var(--tw-content);background-color:var(--color-blue-100)}.after\:bg-diff-selected-bg:after{content:var(--tw-content);background-color:var(--color-diff-selected-bg)}.after\:opacity-30:after{content:var(--tw-content);opacity:.3}@media (hover:hover){.hover\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-y)}.hover\:border-github-accent\/50:hover{border-color:#23863680}@supports (color:color-mix(in lab,red,red)){.hover\:border-github-accent\/50:hover{border-color:color-mix(in oklab,var(--color-github-accent)50%,transparent)}}.hover\:border-github-text-muted:hover{border-color:var(--color-github-text-muted)}.hover\:border-green-600:hover{border-color:var(--color-green-600)}.hover\:bg-github-bg-primary:hover{background-color:var(--color-github-bg-primary)}.hover\:bg-github-bg-tertiary:hover{background-color:var(--color-github-bg-tertiary)}.hover\:bg-github-text-muted:hover{background-color:var(--color-github-text-muted)}.hover\:bg-green-500\/10:hover{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-green-500\/10:hover{background-color:color-mix(in oklab,var(--color-green-500)10%,transparent)}}.hover\:bg-green-600:hover{background-color:var(--color-green-600)}.hover\:text-github-text-primary:hover{color:var(--color-github-text-primary)}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:min-h-\[80px\]:focus{min-height:80px}.focus\:border-blue-600:focus{border-color:var(--color-blue-600)}.focus\:border-github-accent:focus{border-color:var(--color-github-accent)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-blue-600\/30:focus{--tw-ring-color:#155dfc4d}@supports (color:color-mix(in lab,red,red)){.focus\:ring-blue-600\/30:focus{--tw-ring-color:color-mix(in oklab,var(--color-blue-600)30%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (prefers-color-scheme:dark){.dark\:border-slate-500{border-color:var(--color-slate-500)}.dark\:bg-slate-600{background-color:var(--color-slate-600)}.dark\:text-white{color:var(--color-white)}@media (hover:hover){.dark\:hover\:border-slate-400:hover{border-color:var(--color-slate-400)}.dark\:hover\:bg-slate-500:hover{background-color:var(--color-slate-500)}}}.\[\&_code\]\:\!bg-transparent code{background-color:#0000!important}.\[\&_code\]\:text-inherit code{color:inherit}.\[\&_pre\]\:m-0 pre{margin:calc(var(--spacing)*0)}.\[\&_pre\]\:\!bg-transparent pre{background-color:#0000!important}.\[\&_pre\]\:p-0 pre{padding:calc(var(--spacing)*0)}.\[\&_pre\]\:text-inherit pre{color:inherit}}:root{--app-font-size:14px;--app-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif}html,body{background-color:var(--color-github-bg-primary);color:var(--color-github-text-primary);font-family:var(--app-font-family);line-height:1.5;font-size:var(--app-font-size)}:root{interpolate-size:allow-keywords}button{cursor:pointer}@keyframes sparkle-rise{0%{opacity:0;transform:translateY(20px)scale(.5)}20%{opacity:1;transform:translateY(10px)scale(1)}80%{opacity:1;transform:translateY(-30px)scale(1)}to{opacity:0;transform:translateY(-40px)scale(.8)}}.animate-sparkle-rise{animation:.8s ease-out both sparkle-rise}html,body,.bg-github-bg-primary,.bg-github-bg-secondary,.bg-github-bg-tertiary,[class*=bg-github],[class*=text-github],[class*=border-github],[class*=bg-diff],[class*=border-diff]{transition:background-color .3s,color .3s,border-color .3s}tr.keyboard-cursor td{position:relative}tr.keyboard-cursor td:before{content:"";pointer-events:none;z-index:1;background-color:#fffd5433;position:absolute;inset:0}tr.keyboard-cursor td:first-child:before{box-shadow:inset 1px 0 #fffd5466,inset 0 1px #fffd5466,inset 0 -1px #fffd5466}tr.keyboard-cursor td:last-child:before{box-shadow:inset -1px 0 #fffd5466,inset 0 1px #fffd5466,inset 0 -1px #fffd5466}tr.keyboard-cursor td:not(:first-child):not(:last-child):before{box-shadow:inset 0 1px #fffd5466,inset 0 -1px #fffd5466}td.keyboard-cursor{position:relative}td.keyboard-cursor:before{content:"";pointer-events:none;z-index:1;background-color:#fffd5433;position:absolute;inset:0;box-shadow:inset 0 0 0 1px #fffd5466}.word-token{cursor:pointer;transition:background-color .15s;position:relative}.word-highlight{background-color:var(--word-highlight-color,#fffd54);border-radius:2px}[data-theme=dark]{--word-highlight-color:#fffd544d}[data-theme=light]{--word-highlight-color:#fffd54}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare const LineNumberSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
3
|
-
export declare const CommentSchema: z.ZodObject<{
|
|
4
|
-
id: z.ZodString;
|
|
5
|
-
file: z.ZodString;
|
|
6
|
-
line: z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
7
|
-
body: z.ZodString;
|
|
8
|
-
timestamp: z.ZodString;
|
|
9
|
-
codeContent: z.ZodOptional<z.ZodString>;
|
|
10
|
-
}, z.core.$strip>;
|
|
11
|
-
export declare const CommentsPayloadSchema: z.ZodObject<{
|
|
12
|
-
comments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
13
|
-
id: z.ZodString;
|
|
14
|
-
file: z.ZodString;
|
|
15
|
-
line: z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
16
|
-
body: z.ZodString;
|
|
17
|
-
timestamp: z.ZodString;
|
|
18
|
-
codeContent: z.ZodOptional<z.ZodString>;
|
|
19
|
-
}, z.core.$strip>>>;
|
|
20
|
-
}, z.core.$strip>;
|
|
21
|
-
export type ValidatedComment = z.infer<typeof CommentSchema>;
|
|
22
|
-
export type ValidatedCommentsPayload = z.infer<typeof CommentsPayloadSchema>;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
// Schema for line number: either a single number or a tuple of two numbers
|
|
3
|
-
export const LineNumberSchema = z.union([z.number(), z.tuple([z.number(), z.number()])]);
|
|
4
|
-
// Schema for a single comment
|
|
5
|
-
export const CommentSchema = z.object({
|
|
6
|
-
id: z.string(),
|
|
7
|
-
file: z.string(),
|
|
8
|
-
line: LineNumberSchema,
|
|
9
|
-
body: z.string(),
|
|
10
|
-
timestamp: z.string(),
|
|
11
|
-
codeContent: z.string().optional(),
|
|
12
|
-
});
|
|
13
|
-
// Schema for the comments payload sent from client
|
|
14
|
-
export const CommentsPayloadSchema = z.object({
|
|
15
|
-
comments: z.array(CommentSchema).optional(),
|
|
16
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|