reviw 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.cjs +51 -1
- package/package.json +1 -1
package/cli.cjs
CHANGED
|
@@ -116,7 +116,7 @@ function runGitDiff() {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
// Validate all files exist (if files specified)
|
|
119
|
+
// Validate all files exist and are not directories (if files specified)
|
|
120
120
|
const resolvedPaths = [];
|
|
121
121
|
for (const fp of filePaths) {
|
|
122
122
|
const resolved = path.resolve(fp);
|
|
@@ -124,6 +124,13 @@ for (const fp of filePaths) {
|
|
|
124
124
|
console.error(`File not found: ${resolved}`);
|
|
125
125
|
process.exit(1);
|
|
126
126
|
}
|
|
127
|
+
const stat = fs.statSync(resolved);
|
|
128
|
+
if (stat.isDirectory()) {
|
|
129
|
+
console.error(`Cannot open directory: ${resolved}`);
|
|
130
|
+
console.error(`Usage: reviw <file> [file2...]`);
|
|
131
|
+
console.error(`Please specify a file, not a directory.`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
127
134
|
resolvedPaths.push(resolved);
|
|
128
135
|
}
|
|
129
136
|
|
|
@@ -477,6 +484,19 @@ function escapeHtmlChars(str) {
|
|
|
477
484
|
}
|
|
478
485
|
|
|
479
486
|
function loadData(filePath) {
|
|
487
|
+
// Check if path exists
|
|
488
|
+
if (!fs.existsSync(filePath)) {
|
|
489
|
+
throw new Error(`File not found: ${filePath}`);
|
|
490
|
+
}
|
|
491
|
+
// Check if path is a directory
|
|
492
|
+
const stat = fs.statSync(filePath);
|
|
493
|
+
if (stat.isDirectory()) {
|
|
494
|
+
throw new Error(
|
|
495
|
+
`Cannot open directory: ${filePath}\n` +
|
|
496
|
+
`Usage: reviw <file> [file2...]\n` +
|
|
497
|
+
`Please specify a file, not a directory.`
|
|
498
|
+
);
|
|
499
|
+
}
|
|
480
500
|
const ext = path.extname(filePath).toLowerCase();
|
|
481
501
|
if (ext === ".csv" || ext === ".tsv") {
|
|
482
502
|
const data = loadCsv(filePath);
|
|
@@ -3827,6 +3847,20 @@ function htmlTemplate(dataRows, cols, title, mode, previewHtml) {
|
|
|
3827
3847
|
\`;
|
|
3828
3848
|
document.head.appendChild(style);
|
|
3829
3849
|
|
|
3850
|
+
// Helper: strip markdown formatting from text
|
|
3851
|
+
function stripMarkdown(text) {
|
|
3852
|
+
return text
|
|
3853
|
+
.replace(/^[-*+]\\s+/, '') // List markers: - * +
|
|
3854
|
+
.replace(/^\\d+\\.\\s+/, '') // Numbered list: 1. 2.
|
|
3855
|
+
.replace(/\\*\\*([^*]+)\\*\\*/g, '$1') // Bold: **text**
|
|
3856
|
+
.replace(/\\*([^*]+)\\*/g, '$1') // Italic: *text*
|
|
3857
|
+
.replace(/__([^_]+)__/g, '$1') // Bold: __text__
|
|
3858
|
+
.replace(/_([^_]+)_/g, '$1') // Italic: _text_
|
|
3859
|
+
.replace(/\`([^\`]+)\`/g, '$1') // Inline code: \`code\`
|
|
3860
|
+
.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1') // Links: [text](url)
|
|
3861
|
+
.trim();
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3830
3864
|
// Helper: find matching source line for text
|
|
3831
3865
|
function findSourceLine(text) {
|
|
3832
3866
|
if (!text) return -1;
|
|
@@ -3849,6 +3883,14 @@ function htmlTemplate(dataRows, cols, title, mode, previewHtml) {
|
|
|
3849
3883
|
return i + 1;
|
|
3850
3884
|
}
|
|
3851
3885
|
}
|
|
3886
|
+
|
|
3887
|
+
// Check for markdown list items: strip list markers and formatting
|
|
3888
|
+
if (lineText.match(/^[-*+]\\s|^\\d+\\.\\s/)) {
|
|
3889
|
+
const strippedLine = stripMarkdown(lineText).replace(/\\s+/g, ' ').slice(0, 100);
|
|
3890
|
+
if (strippedLine === normalized) return i + 1;
|
|
3891
|
+
if (strippedLine.includes(normalized.slice(0, 30)) && normalized.length > 5) return i + 1;
|
|
3892
|
+
if (normalized.includes(strippedLine.slice(0, 30)) && strippedLine.length > 5) return i + 1;
|
|
3893
|
+
}
|
|
3852
3894
|
}
|
|
3853
3895
|
return -1;
|
|
3854
3896
|
}
|
|
@@ -4286,6 +4328,10 @@ function createFileServer(filePath) {
|
|
|
4286
4328
|
|
|
4287
4329
|
function tryListen(attemptPort, attempts = 0) {
|
|
4288
4330
|
if (serverStarted) return; // Prevent double-start race condition
|
|
4331
|
+
// Clear previous listeners from failed attempts to avoid duplicate
|
|
4332
|
+
// "listening" callbacks firing after a later successful bind.
|
|
4333
|
+
ctx.server.removeAllListeners("error");
|
|
4334
|
+
ctx.server.removeAllListeners("listening");
|
|
4289
4335
|
if (attempts >= MAX_PORT_ATTEMPTS) {
|
|
4290
4336
|
console.error(
|
|
4291
4337
|
`Could not find an available port for ${baseName} after ${MAX_PORT_ATTEMPTS} attempts.`,
|
|
@@ -4450,6 +4496,10 @@ function createDiffServer(diffContent) {
|
|
|
4450
4496
|
|
|
4451
4497
|
function tryListen(attemptPort, attempts = 0) {
|
|
4452
4498
|
if (serverStarted) return; // Prevent double-start race condition
|
|
4499
|
+
// Clear listeners from previous failed attempts to prevent stale
|
|
4500
|
+
// "listening" handlers from firing on the successful bind.
|
|
4501
|
+
ctx.server.removeAllListeners("error");
|
|
4502
|
+
ctx.server.removeAllListeners("listening");
|
|
4453
4503
|
if (attempts >= MAX_PORT_ATTEMPTS) {
|
|
4454
4504
|
console.error(
|
|
4455
4505
|
`Could not find an available port for diff viewer after ${MAX_PORT_ATTEMPTS} attempts.`,
|