@node-cli/comments 0.1.0 → 0.2.1

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/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\n\nexport const logger = new Logger({ boring: process.env.NODE_ENV === \"test\" });\n\nexport interface ProcessOptions {\n\twidth: number;\n\twrapLineComments: boolean;\n\tmergeLineComments: boolean;\n}\n\nexport interface FileResult {\n\toriginal: string;\n\ttransformed: string;\n\tchanged: boolean;\n}\n\ninterface JsDocMatch {\n\tindent: string;\n\tbody: string;\n\tstart: number;\n\tend: number;\n}\n\n// Safety guards / limits (defense-in-depth vs pathological or malicious input)\n// Large indentation sequences (e.g. thousands of tabs) aren't meaningful for real\n// source formatting and could be used to inflate processing time if a regex\n// exhibited super-linear behavior. Our pattern is already linear (tempered), but\n// we still cap accepted indentation length to keep work bounded.\nconst MAX_JSDOC_INDENT = 256; // characters (tabs + spaces)\n\n// JSDoc block extraction:\n// Previous pattern used a lazy dot-all: ([\\s\\S]*?) which could, under\n// pathological inputs, produce excessive backtracking. We replaced it with a\n// tempered pattern that advances linearly by never letting the inner part\n// consume a closing '*/'. This avoids catastrophic behavior while keeping\n// correctness.\n//\n// Reviewer (PR) concern: potential ReDoS on crafted inputs containing many\n// leading tabs then '/**'. Analysis: The inner quantified group\n// (?:[^*]|\\*(?!/))*\n// is unambiguous: on each iteration it consumes exactly one character and can\n// never match the closing sentinel '*/' because of the negative lookahead. This\n// means the engine proceeds in O(n) time relative to the block body size.\n// There is no nested ambiguous quantifier (e.g. (a+)*, (.*)+, etc.). The only\n// other quantified part ^[\\t ]* is a simple character class that is consumed\n// once per line start with no backtracking explosion potential.\n//\n// Defense-in-depth: we still (1) cap processed body length (see below) and\n// (2) cap accepted indentation length (MAX_JSDOC_INDENT) after match to ensure\n// we skip absurdly indented constructs.\n//\n// Pattern explanation:\n// (^ [\\t ]* ) -> capture indentation at start of line (multiline mode)\n// /\\*\\* -> opening delimiter\n// ( -> capture group 2 body\n// (?:[^*] -> any non-* char\n// |\\*(?!/) -> or a * not followed by /\n// )* -> repeated greedily (cannot cross closing */)\n// )\n// \\n?[\\t ]*\\*/ -> optional newline + trailing indent + closing */\n// Complexity: linear in length of the matched block.\nconst JSDOC_REGEX = /(^[\\t ]*)\\/\\*\\*((?:[^*]|\\*(?!\\/))*)\\n?[\\t ]*\\*\\//gm;\n\nexport function diffLines(a: string, b: string): string {\n\tif (a === b) {\n\t\treturn \"\";\n\t}\n\tconst A = a.split(/\\n/);\n\tconst B = b.split(/\\n/);\n\tconst out: string[] = [];\n\tconst m = Math.max(A.length, B.length);\n\tfor (let i = 0; i < m; i++) {\n\t\tif (A[i] === B[i]) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (A[i] !== undefined) {\n\t\t\tout.push(`- ${A[i]}`);\n\t\t}\n\t\tif (B[i] !== undefined) {\n\t\t\tout.push(`+ ${B[i]}`);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n}\n\nfunction endsSentence(line: string): boolean {\n\treturn /[.!?](?:['\")\\]]*)$/.test(line.trim());\n}\n\nfunction needsTerminalPunctuation(line: string): boolean {\n\treturn /[A-Za-z0-9\")\\]']$/.test(line) && !endsSentence(line);\n}\n\nfunction maybeAddPeriod(line: string): string {\n\treturn needsTerminalPunctuation(line) ? line + \".\" : line;\n}\n\nfunction normalizeNote(line: string): string {\n\treturn line.replace(/^note:/i, \"NOTE:\");\n}\n\nfunction isListLike(line: string): boolean {\n\treturn /^(?:[-*+] |\\d+\\. )/.test(line.trim());\n}\n\nfunction isTagLine(line: string): boolean {\n\treturn /^@/.test(line.trim());\n}\n\nfunction isHeadingLike(line: string): boolean {\n\tconst t = line.trim();\n\treturn /:$/.test(t) && !isTagLine(t);\n}\n\nfunction isCodeFence(line: string): boolean {\n\treturn /^```/.test(line.trim());\n}\n\nfunction isVisuallyIndentedCode(line: string): boolean {\n\treturn /^\\s{2,}\\S/.test(line);\n}\n\nfunction wrapWords(text: string, width: number): string[] {\n\tconst words = text.split(/\\s+/).filter(Boolean);\n\tconst lines: string[] = [];\n\tlet cur = \"\";\n\tfor (const w of words) {\n\t\tif (!cur.length) {\n\t\t\tcur = w;\n\t\t\tcontinue;\n\t\t}\n\t\tif (cur.length + 1 + w.length <= width) {\n\t\t\tcur += \" \" + w;\n\t\t} else {\n\t\t\tlines.push(cur);\n\t\t\tcur = w;\n\t\t}\n\t}\n\tif (cur) {\n\t\tlines.push(cur);\n\t}\n\treturn lines.length ? lines : [\"\"];\n}\n\nfunction buildJsDoc(indent: string, rawBody: string, width: number): string {\n\tconst lines = rawBody.split(/\\n/).map((l) => l.replace(/^\\s*\\*? ?/, \"\"));\n\tconst out: string[] = [];\n\tlet para: string[] = [];\n\tlet inFence = false;\n\tconst prefix = indent + \" * \";\n\tconst avail = Math.max(10, width - prefix.length);\n\n\tfunction flush(): void {\n\t\tif (!para.length) {\n\t\t\treturn;\n\t\t}\n\t\tlet text = para.join(\" \").replace(/\\s+/g, \" \").trim();\n\t\ttext = normalizeNote(text);\n\t\ttext = maybeAddPeriod(text);\n\t\tfor (const l of wrapWords(text, avail)) {\n\t\t\tout.push(prefix + l);\n\t\t}\n\t\tpara = [];\n\t}\n\n\tfor (const raw of lines) {\n\t\tconst trimmed = raw.trimEnd();\n\t\tif (isCodeFence(trimmed)) {\n\t\t\tflush();\n\t\t\tinFence = !inFence;\n\t\t\tout.push(prefix + trimmed);\n\t\t\tcontinue;\n\t\t}\n\t\tif (inFence) {\n\t\t\tout.push(prefix + trimmed);\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\ttrimmed === \"\" ||\n\t\t\tisListLike(trimmed) ||\n\t\t\tisTagLine(trimmed) ||\n\t\t\tisHeadingLike(trimmed) ||\n\t\t\tisVisuallyIndentedCode(raw)\n\t\t) {\n\t\t\tflush();\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (\n\t\t\t\t\tout.length === 0 ||\n\t\t\t\t\t/^(?:\\s*\\*\\s*)$/.test(out[out.length - 1]) === false\n\t\t\t\t) {\n\t\t\t\t\tout.push(prefix.trimEnd());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tout.push(prefix + normalizeNote(trimmed));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tpara.push(trimmed);\n\t}\n\tflush();\n\treturn `${indent}/**\\n${out.join(\"\\n\")}\\n${indent}*/`;\n}\n\nfunction reflowJsDocBlocks(\n\tcontent: string,\n\twidth: number,\n): { content: string; blocks: number } {\n\tJSDOC_REGEX.lastIndex = 0;\n\tconst blocks: JsDocMatch[] = [];\n\tlet m: RegExpExecArray | null = JSDOC_REGEX.exec(content);\n\twhile (m) {\n\t\tconst indent = m[1] || \"\";\n\t\tconst body = m[2] || \"\";\n\t\t// Body length guard protects against extremely large comment blocks.\n\t\tif (body.length <= 500_000 && indent.length <= MAX_JSDOC_INDENT) {\n\t\t\tblocks.push({\n\t\t\t\tindent,\n\t\t\t\tbody,\n\t\t\t\tstart: m.index,\n\t\t\t\tend: m.index + m[0].length,\n\t\t\t});\n\t\t}\n\t\tm = JSDOC_REGEX.exec(content);\n\t}\n\tif (!blocks.length) {\n\t\treturn { content, blocks: 0 };\n\t}\n\tlet delta = 0;\n\tlet out = content;\n\tfor (const b of blocks) {\n\t\tconst original = out.slice(b.start + delta, b.end + delta);\n\t\tconst built = buildJsDoc(b.indent, b.body, width);\n\t\tif (original !== built) {\n\t\t\tout = out.slice(0, b.start + delta) + built + out.slice(b.end + delta);\n\t\t\tdelta += built.length - original.length;\n\t\t}\n\t}\n\treturn { content: out, blocks: blocks.length };\n}\n\nfunction wrapLineComments(\n\tcontent: string,\n\twidth: number,\n): { content: string; applied: boolean } {\n\tconst lines = content.split(/\\n/);\n\tlet changed = false;\n\tconst out: string[] = [];\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tconst line = lines[i];\n\t\tconst m = /^(\\s*)\\/\\/( ?)(.*)$/.exec(line);\n\t\tif (!m || /^\\/\\/\\//.test(line)) {\n\t\t\tout.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst indent = m[1];\n\t\tconst body = m[3];\n\t\tif (/^(@|eslint|ts-ignore)/.test(body) || /https?:\\/\\//.test(body)) {\n\t\t\tout.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\tconst prefix = indent + \"// \";\n\t\tconst avail = Math.max(10, width - prefix.length);\n\t\tlet text = body.replace(/\\s+/g, \" \").trim();\n\t\ttext = normalizeNote(text);\n\t\ttext = maybeAddPeriod(text);\n\t\tconst wrapped = wrapWords(text, avail).map((w) => prefix + w);\n\t\tif (wrapped.join(\"\\n\") !== line) {\n\t\t\tchanged = true;\n\t\t}\n\t\tout.push(...wrapped);\n\t}\n\treturn { content: out.join(\"\\n\"), applied: changed };\n}\n\nfunction mergeLineCommentGroups(content: string): {\n\tcontent: string;\n\tmerged: boolean;\n} {\n\tconst lines = content.split(/\\n/);\n\tconst out: string[] = [];\n\tlet i = 0;\n\tlet merged = false;\n\twhile (i < lines.length) {\n\t\tif (/^\\s*\\/\\//.test(lines[i]) && !/^\\s*\\/\\/\\//.test(lines[i])) {\n\t\t\tconst prev = i > 0 ? lines[i - 1] : \"\";\n\t\t\tconst prevTrim = prev.trim();\n\t\t\tconst contextEligible = prevTrim === \"\" || /[{}]$/.test(prevTrim);\n\t\t\tif (!contextEligible) {\n\t\t\t\tout.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst group: { indent: string; text: string }[] = [];\n\t\t\tlet j = i;\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst lm = /^(\\s*)\\/\\/ ?(.*)$/.exec(lines[j]);\n\t\t\t\tif (!lm || /^\\s*\\/\\/\\//.test(lines[j])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst txt = lm[2];\n\t\t\t\tif (\n\t\t\t\t\t/license|copyright/i.test(txt) ||\n\t\t\t\t\t/https?:\\/\\//.test(txt) ||\n\t\t\t\t\t/eslint|ts-ignore/.test(txt)\n\t\t\t\t) {\n\t\t\t\t\tbreak; // do not merge directive / license groups\n\t\t\t\t}\n\t\t\t\tgroup.push({ indent: lm[1], text: txt });\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tif (group.length >= 2) {\n\t\t\t\t// Structured explanatory blocks: now we CONVERT them into a multi-line JSDoc block\n\t\t\t\t// while preserving each original line (instead of merging into a single paragraph).\n\t\t\t\t// We must escape any raw '*/' inside the body to avoid premature termination.\n\t\t\t\t// Definition of structured: presence of arrows (->), regex tokens (?:, */), or the phrase 'Pattern explanation:'.\n\t\t\t\tconst structured = group.some(\n\t\t\t\t\t(g) =>\n\t\t\t\t\t\t/->/.test(g.text) ||\n\t\t\t\t\t\t/(\\(\\?:|\\*\\/)/.test(g.text) ||\n\t\t\t\t\t\t/Pattern explanation:/i.test(g.text),\n\t\t\t\t);\n\t\t\t\tif (structured) {\n\t\t\t\t\tconst indent = group[0].indent;\n\t\t\t\t\tout.push(`${indent}/**`);\n\t\t\t\t\tfor (const ln of group) {\n\t\t\t\t\t\t// Escape closing sentinel inside content\n\t\t\t\t\t\tconst safe = ln.text.replace(/\\*\\//g, \"*\\\\/\");\n\t\t\t\t\t\tout.push(`${indent} * ${safe}`);\n\t\t\t\t\t}\n\t\t\t\t\tout.push(`${indent} */`);\n\t\t\t\t\tmerged = true;\n\t\t\t\t\ti = j;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst indent = group[0].indent;\n\t\t\t\tmerged = true;\n\t\t\t\tconst para = group\n\t\t\t\t\t.map((g) => normalizeNote(g.text.trim()))\n\t\t\t\t\t.map((g) => maybeAddPeriod(g))\n\t\t\t\t\t.join(\" \");\n\t\t\t\tout.push(`${indent}/**`);\n\t\t\t\tout.push(`${indent} * ${para}`);\n\t\t\t\tout.push(`${indent} */`);\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tout.push(lines[i]);\n\t\ti++;\n\t}\n\treturn { content: out.join(\"\\n\"), merged };\n}\n\nexport function parseAndTransformComments(\n\tinput: string,\n\toptions: ProcessOptions,\n): FileResult {\n\tlet working = input;\n\tif (options.mergeLineComments) {\n\t\tconst m = mergeLineCommentGroups(working);\n\t\tworking = m.content;\n\t}\n\tconst js = reflowJsDocBlocks(working, options.width);\n\tworking = js.content;\n\tif (options.wrapLineComments) {\n\t\tconst w = wrapLineComments(working, options.width);\n\t\tworking = w.content;\n\t}\n\treturn { original: input, transformed: working, changed: working !== input };\n}\n"],"names":["Logger","logger","boring","process","env","NODE_ENV","MAX_JSDOC_INDENT","JSDOC_REGEX","diffLines","a","b","A","split","B","out","m","Math","max","length","i","undefined","push","join","endsSentence","line","test","trim","needsTerminalPunctuation","maybeAddPeriod","normalizeNote","replace","isListLike","isTagLine","isHeadingLike","t","isCodeFence","isVisuallyIndentedCode","wrapWords","text","width","words","filter","Boolean","lines","cur","w","buildJsDoc","indent","rawBody","map","l","para","inFence","prefix","avail","flush","raw","trimmed","trimEnd","reflowJsDocBlocks","content","lastIndex","blocks","exec","body","start","index","end","delta","original","slice","built","wrapLineComments","wrapped","changed","applied","mergeLineCommentGroups","merged","prev","prevTrim","contextEligible","group","j","lm","txt","structured","some","g","ln","safe","parseAndTransformComments","input","options","working","mergeLineComments","js","transformed"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/lib.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\n\nexport const logger = new Logger({ boring: process.env.NODE_ENV === \"test\" });\n\nexport interface ProcessOptions {\n\twidth: number;\n\twrapLineComments: boolean;\n\tmergeLineComments: boolean;\n}\n\nexport interface FileResult {\n\toriginal: string;\n\ttransformed: string;\n\tchanged: boolean;\n}\n\ninterface JsDocMatch {\n\tindent: string;\n\tbody: string;\n\tstart: number;\n\tend: number;\n}\n\n/**\n * Safety guards / limits (defense-in-depth vs pathological or malicious input)\n * Large indentation sequences (e.g. thousands of tabs) aren't meaningful for\n * real source formatting and could be used to inflate processing time if a\n * regex exhibited super-linear behavior. Our pattern is already linear\n * (tempered), but we still cap accepted indentation length to keep work\n * bounded.\n */\nconst MAX_JSDOC_INDENT = 256; // characters (tabs + spaces)\n\n/**\n * JSDoc block extraction:\n * Previous pattern used a lazy dot-all: ([\\s\\S]*?) which could, under\n * pathological inputs, produce excessive backtracking. We replaced it with a\n * tempered pattern that advances linearly by never letting the inner part\n * consume a closing '*\\/'. This avoids catastrophic behavior while keeping\n * correctness.\n *\n * Reviewer (PR) concern: potential ReDoS on crafted inputs containing many\n * leading tabs then '/**'. Analysis: The inner quantified group\n * (?:[^*]|\\*(?!/))*\n * is unambiguous: on each iteration it consumes exactly one character and can\n * never match the closing sentinel '*\\/' because of the negative lookahead. This\n * means the engine proceeds in O(n) time relative to the block body size.\n * There is no nested ambiguous quantifier (e.g. (a+)*, (.*)+, etc.). The only\n * other quantified part ^[\\t ]* is a simple character class that is consumed\n * once per line start with no backtracking explosion potential.\n *\n * Defense-in-depth: we still (1) cap processed body length (see below) and\n * (2) cap accepted indentation length (MAX_JSDOC_INDENT) after match to ensure\n * we skip absurdly indented constructs.\n *\n * Pattern explanation:\n * (^ [\\t ]* ) -> capture indentation at start of line (multiline mode)\n * /\\*\\* -> opening delimiter\n * ( -> capture group 2 body\n * (?:[^*] -> any non-* char\n * |\\*(?!/) -> or a * not followed by /\n * )* -> repeated greedily (cannot cross closing *\\/)\n * )\n * \\n?[\\t ]*\\*\\/ -> optional newline + trailing indent + closing *\\/\n * Complexity: linear in length of the matched block.\n *\n */\nconst JSDOC_REGEX = /(^[\\t ]*)\\/\\*\\*((?:[^*]|\\*(?!\\/))*)\\n?[\\t ]*\\*\\//gm;\n\nexport function diffLines(a: string, b: string): string {\n\tif (a === b) {\n\t\treturn \"\";\n\t}\n\tconst A = a.split(/\\n/);\n\tconst B = b.split(/\\n/);\n\tconst out: string[] = [];\n\tconst m = Math.max(A.length, B.length);\n\tfor (let i = 0; i < m; i++) {\n\t\tif (A[i] === B[i]) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (A[i] !== undefined) {\n\t\t\tout.push(`- ${A[i]}`);\n\t\t}\n\t\tif (B[i] !== undefined) {\n\t\t\tout.push(`+ ${B[i]}`);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n}\n\nfunction endsSentence(line: string): boolean {\n\treturn /[.!?](?:['\")\\]]*)$/.test(line.trim());\n}\n\nfunction needsTerminalPunctuation(line: string): boolean {\n\treturn /[A-Za-z0-9\")\\]']$/.test(line) && !endsSentence(line);\n}\n\nfunction maybeAddPeriod(line: string): string {\n\treturn needsTerminalPunctuation(line) ? line + \".\" : line;\n}\n\nfunction normalizeNote(line: string): string {\n\treturn line.replace(/^note:/i, \"NOTE:\");\n}\n\nfunction isListLike(line: string): boolean {\n\treturn /^(?:[-*+] |\\d+\\. )/.test(line.trim());\n}\n\nfunction isTagLine(line: string): boolean {\n\treturn /^@/.test(line.trim());\n}\n\nfunction isHeadingLike(line: string): boolean {\n\tconst t = line.trim();\n\tif (!/:$/.test(t) || isTagLine(t)) {\n\t\treturn false;\n\t}\n\t/**\n\t * New heuristic: treat as heading only if composed of one or more words that\n\t * each start with an uppercase letter (allows Internal IDs with\n\t * dashes/underscores too). Examples considered headings: \"Overview:\",\n\t * \"Performance Notes:\", \"API Surface:\". Non-headings (treated as sentence\n\t * continuation): \"tested a little bit differently:\", \"differently:\".\n\t */\n\treturn /^[A-Z][A-Za-z0-9_-]*(?: [A-Z][A-Za-z0-9_-]*)*:$/.test(t);\n}\n\nfunction isCodeFence(line: string): boolean {\n\treturn /^```/.test(line.trim());\n}\n\nfunction isVisuallyIndentedCode(line: string): boolean {\n\treturn /^\\s{2,}\\S/.test(line);\n}\n\nfunction wrapWords(text: string, width: number): string[] {\n\tconst words = text.split(/\\s+/).filter(Boolean);\n\tconst lines: string[] = [];\n\tlet cur = \"\";\n\tfor (const w of words) {\n\t\tif (!cur.length) {\n\t\t\tcur = w;\n\t\t\tcontinue;\n\t\t}\n\t\tif (cur.length + 1 + w.length <= width) {\n\t\t\tcur += \" \" + w;\n\t\t} else {\n\t\t\tlines.push(cur);\n\t\t\tcur = w;\n\t\t}\n\t}\n\tif (cur) {\n\t\tlines.push(cur);\n\t}\n\treturn lines.length ? lines : [\"\"];\n}\n\nfunction buildJsDoc(indent: string, rawBody: string, width: number): string {\n\tlet lines = rawBody.split(/\\n/).map((l) => l.replace(/^\\s*\\*? ?/, \"\"));\n\t// Remove a single leading blank line (artifact of regex capture starting after\n\t// /**) if content follows.\n\twhile (\n\t\tlines.length > 1 &&\n\t\tlines[0].trim() === \"\" &&\n\t\tlines.some((l) => l.trim() !== \"\")\n\t) {\n\t\tlines = lines.slice(1);\n\t}\n\t/**\n\t * Trailing blank handling: keep a single trailing blank only if there are\n\t * multiple paragraphs (i.e., an internal blank separator exists). If the doc\n\t * is a single paragraph, drop the trailing blank to avoid an extra standalone\n\t * '*' line before the closing delimiter.\n\t */\n\tif (lines.length > 1 && lines[lines.length - 1].trim() === \"\") {\n\t\tconst internalBlank = lines.slice(0, -1).some((l) => l.trim() === \"\");\n\t\tif (!internalBlank) {\n\t\t\tlines = lines.slice(0, -1);\n\t\t}\n\t}\n\tconst out: string[] = [];\n\tlet para: string[] = [];\n\tlet inFence = false;\n\tconst prefix = indent + \" * \";\n\tconst avail = Math.max(10, width - prefix.length);\n\n\t/**\n\t * Detect structured explanatory / regex description blocks where we want to\n\t * preserve each original line verbatim (no paragraph joining or sentence\n\t * period insertion) to avoid altering carefully aligned or enumerated lines.\n\t */\n\tconst structured = lines.some(\n\t\t(l) =>\n\t\t\t/->/.test(l) || /(\\(\\?:|\\*\\/)/.test(l) || /Pattern explanation:/i.test(l),\n\t);\n\tif (structured) {\n\t\tfor (const raw of lines) {\n\t\t\tconst trimmed = raw.trimEnd();\n\t\t\tif (trimmed === \"\") {\n\t\t\t\t// ensure a blank line represented by a lone '*'.\n\t\t\t\tif (\n\t\t\t\t\tout.length === 0 ||\n\t\t\t\t\t/^(?:\\s*\\*\\s*)$/.test(out[out.length - 1]) === false\n\t\t\t\t) {\n\t\t\t\t\tout.push(prefix.trimEnd());\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tout.push(prefix + normalizeNote(trimmed));\n\t\t}\n\t\treturn `${indent}/**\\n${out.join(\"\\n\")}\\n${indent}*/`;\n\t}\n\n\tfunction flush(): void {\n\t\tif (!para.length) {\n\t\t\treturn;\n\t\t}\n\t\tlet text = para.join(\" \").replace(/\\s+/g, \" \").trim();\n\t\ttext = normalizeNote(text);\n\t\ttext = maybeAddPeriod(text);\n\t\tfor (const l of wrapWords(text, avail)) {\n\t\t\tout.push(prefix + l);\n\t\t}\n\t\tpara = [];\n\t}\n\n\tfor (const raw of lines) {\n\t\tconst trimmed = raw.trimEnd();\n\t\tif (isCodeFence(trimmed)) {\n\t\t\tflush();\n\t\t\tinFence = !inFence;\n\t\t\tout.push(prefix + trimmed);\n\t\t\tcontinue;\n\t\t}\n\t\tif (inFence) {\n\t\t\tout.push(prefix + trimmed);\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\ttrimmed === \"\" ||\n\t\t\tisListLike(trimmed) ||\n\t\t\tisTagLine(trimmed) ||\n\t\t\tisHeadingLike(trimmed) ||\n\t\t\tisVisuallyIndentedCode(raw)\n\t\t) {\n\t\t\tflush();\n\t\t\tif (trimmed === \"\") {\n\t\t\t\tif (\n\t\t\t\t\tout.length === 0 ||\n\t\t\t\t\t/^(?:\\s*\\*\\s*)$/.test(out[out.length - 1]) === false\n\t\t\t\t) {\n\t\t\t\t\tout.push(prefix.trimEnd());\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tout.push(prefix + normalizeNote(trimmed));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tpara.push(trimmed);\n\t}\n\tflush();\n\t// Style: ensure a space precedes the closing */ for consistency with blocks\n\t// generated elsewhere in this tool (merged line comment groups). Previously\n\t// we emitted `${indent}*/` which produced an off-by-one visual alignment.\n\treturn `${indent}/**\\n${out.join(\"\\n\")}\\n${indent} */`;\n}\n\nfunction reflowJsDocBlocks(\n\tcontent: string,\n\twidth: number,\n): { content: string; blocks: number } {\n\tJSDOC_REGEX.lastIndex = 0;\n\tconst blocks: JsDocMatch[] = [];\n\tlet m: RegExpExecArray | null = JSDOC_REGEX.exec(content);\n\twhile (m) {\n\t\tconst indent = m[1] || \"\";\n\t\tconst body = m[2] || \"\";\n\t\t// Body length guard protects against extremely large comment blocks.\n\t\tif (body.length <= 500_000 && indent.length <= MAX_JSDOC_INDENT) {\n\t\t\tblocks.push({\n\t\t\t\tindent,\n\t\t\t\tbody,\n\t\t\t\tstart: m.index,\n\t\t\t\tend: m.index + m[0].length,\n\t\t\t});\n\t\t}\n\t\tm = JSDOC_REGEX.exec(content);\n\t}\n\tif (!blocks.length) {\n\t\treturn { content, blocks: 0 };\n\t}\n\tlet delta = 0;\n\tlet out = content;\n\tfor (const b of blocks) {\n\t\tconst original = out.slice(b.start + delta, b.end + delta);\n\t\tconst built = buildJsDoc(b.indent, b.body, width);\n\t\tif (original !== built) {\n\t\t\tout = out.slice(0, b.start + delta) + built + out.slice(b.end + delta);\n\t\t\tdelta += built.length - original.length;\n\t\t}\n\t}\n\treturn { content: out, blocks: blocks.length };\n}\n\nfunction wrapLineComments(\n\tcontent: string,\n\twidth: number,\n): { content: string; applied: boolean } {\n\tconst lines = content.split(/\\n/);\n\tlet changed = false;\n\tconst out: string[] = [];\n\tlet i = 0;\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\t\tconst m = /^(\\s*)\\/\\/( ?)(.*)$/.exec(line);\n\t\tif (!m || /^\\/\\/\\//.test(line)) {\n\t\t\tout.push(line);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\t/**\n\t\t * Collect a group of consecutive simple // lines (not triple slash) that are\n\t\t * eligible.\n\t\t */\n\t\tconst group: { raw: string; indent: string; body: string }[] = [];\n\t\tlet j = i;\n\t\twhile (j < lines.length) {\n\t\t\tconst gm = /^(\\s*)\\/\\/ ?(.*)$/.exec(lines[j]);\n\t\t\tif (!gm || /^\\/\\/\\//.test(lines[j])) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst body = gm[2];\n\t\t\tif (/^(@|eslint|ts-ignore)/.test(body) || /https?:\\/\\//.test(body)) {\n\t\t\t\tbreak; // stop group before directives/URLs; process current line normally\n\t\t\t}\n\t\t\tgroup.push({ raw: lines[j], indent: gm[1], body });\n\t\t\tj++;\n\t\t}\n\t\tif (group.length <= 1) {\n\t\t\t// Single line: existing logic (add period if needed).\n\t\t\tconst indent = m[1];\n\t\t\tconst body = m[3];\n\t\t\tif (/^(@|eslint|ts-ignore)/.test(body) || /https?:\\/\\//.test(body)) {\n\t\t\t\tout.push(line);\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst prefix = indent + \"// \";\n\t\t\tconst avail = Math.max(10, width - prefix.length);\n\t\t\tlet text = body.replace(/\\s+/g, \" \").trim();\n\t\t\ttext = normalizeNote(text);\n\t\t\ttext = maybeAddPeriod(text);\n\t\t\tconst wrapped = wrapWords(text, avail).map((w) => prefix + w);\n\t\t\tif (wrapped.join(\"\\n\") !== line) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t\tout.push(...wrapped);\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\t/**\n\t\t * Multi-line group: only add terminal punctuation (period) to final line if\n\t\t * needed. Other lines are normalized for NOTE but left without forced\n\t\t * punctuation.\n\t\t */\n\t\tfor (let k = 0; k < group.length; k++) {\n\t\t\tconst { indent, body } = group[k];\n\t\t\tconst prefix = indent + \"// \";\n\t\t\tconst avail = Math.max(10, width - prefix.length);\n\t\t\tlet text = body.replace(/\\s+/g, \" \").trim();\n\t\t\ttext = normalizeNote(text);\n\t\t\tif (k === group.length - 1 && !/:$/.test(text.trim())) {\n\t\t\t\ttext = maybeAddPeriod(text);\n\t\t\t}\n\t\t\tconst wrapped = wrapWords(text, avail).map((w) => prefix + w);\n\t\t\tif (wrapped.join(\"\\n\") !== group[k].raw) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t\tout.push(...wrapped);\n\t\t}\n\t\ti = j;\n\t}\n\treturn { content: out.join(\"\\n\"), applied: changed };\n}\n\nfunction mergeLineCommentGroups(content: string): {\n\tcontent: string;\n\tmerged: boolean;\n} {\n\tconst lines = content.split(/\\n/);\n\tconst out: string[] = [];\n\tlet i = 0;\n\tlet merged = false;\n\n\tfunction qualifiesExplanatoryAfterStatement(start: number): boolean {\n\t\t// Peek ahead to collect consecutive // lines (excluding triple slash).\n\t\tconst collected: string[] = [];\n\t\tfor (let k = start; k < lines.length; k++) {\n\t\t\tconst lm = /^(\\s*)\\/\\/( ?)(.*)$/.exec(lines[k]);\n\t\t\tif (!lm || /^\\/\\/\\//.test(lines[k])) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tconst body = lm[3];\n\t\t\tif (/^(@|eslint|ts-ignore)/.test(body) || /https?:\\/\\//.test(body)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcollected.push(body.trim());\n\t\t}\n\t\tif (collected.length < 4) {\n\t\t\treturn false; // require minimum size\n\t\t}\n\t\tif (!/^[A-Z]/.test(collected[0])) {\n\t\t\treturn false; // start with capitalized sentence\n\t\t}\n\t\t/**\n\t\t * Avoid matching directive-like or list-lists: require at least one line with\n\t\t * a space (a sentence).\n\t\t */\n\t\treturn collected.some((c) => /\\s/.test(c));\n\t}\n\twhile (i < lines.length) {\n\t\tif (/^\\s*\\/\\//.test(lines[i]) && !/^\\s*\\/\\/\\//.test(lines[i])) {\n\t\t\tconst prev = i > 0 ? lines[i - 1] : \"\";\n\t\t\tconst prevTrim = prev.trim();\n\t\t\tlet contextEligible = prevTrim === \"\" || /[{}]$/.test(prevTrim);\n\t\t\t/**\n\t\t\t * Additional heuristic: allow large explanatory group after a statement\n\t\t\t * ending with ';' (but not inline trailing comment scenario) when it\n\t\t\t * qualifies as explanatory.\n\t\t\t */\n\t\t\tif (\n\t\t\t\t!contextEligible &&\n\t\t\t\t/;\\s*$/.test(prevTrim) &&\n\t\t\t\tqualifiesExplanatoryAfterStatement(i)\n\t\t\t) {\n\t\t\t\tcontextEligible = true;\n\t\t\t}\n\t\t\tif (!contextEligible) {\n\t\t\t\tout.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst group: { indent: string; text: string }[] = [];\n\t\t\tlet j = i;\n\t\t\twhile (j < lines.length) {\n\t\t\t\tconst lm = /^(\\s*)\\/\\/ ?(.*)$/.exec(lines[j]);\n\t\t\t\tif (!lm || /^\\s*\\/\\/\\//.test(lines[j])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tconst txt = lm[2];\n\t\t\t\tif (\n\t\t\t\t\t/license|copyright/i.test(txt) ||\n\t\t\t\t\t/https?:\\/\\//.test(txt) ||\n\t\t\t\t\t/eslint|ts-ignore/.test(txt)\n\t\t\t\t) {\n\t\t\t\t\tbreak; // do not merge directive / license groups\n\t\t\t\t}\n\t\t\t\tgroup.push({ indent: lm[1], text: txt });\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tif (group.length >= 2) {\n\t\t\t\t/**\n\t\t\t\t * Structured explanatory blocks: now we CONVERT them into a multi-line JSDoc block\n\t\t\t\t * while preserving each original line (instead of merging into a single paragraph).\n\t\t\t\t * We must escape any raw '*\\/' inside the body to avoid premature termination.\n\t\t\t\t * Definition of structured:\n\t\t\t\t * presence of arrows (->), regex tokens (?:, *\\/), or the phrase 'Pattern explanation:'.\n\t\t\t\t */\n\t\t\t\tconst structured = group.some(\n\t\t\t\t\t(g) =>\n\t\t\t\t\t\t/->/.test(g.text) ||\n\t\t\t\t\t\t/(\\(\\?:|\\*\\/)/.test(g.text) ||\n\t\t\t\t\t\t/Pattern explanation:/i.test(g.text),\n\t\t\t\t);\n\t\t\t\tif (structured) {\n\t\t\t\t\tconst indent = group[0].indent;\n\t\t\t\t\tout.push(`${indent}/**`);\n\t\t\t\t\tfor (const ln of group) {\n\t\t\t\t\t\t// Escape closing sentinel inside content.\n\t\t\t\t\t\tconst safe = ln.text.replace(/\\*\\//g, \"*\\\\/\");\n\t\t\t\t\t\tout.push(`${indent} * ${safe}`);\n\t\t\t\t\t}\n\t\t\t\t\tout.push(`${indent} */`);\n\t\t\t\t\tmerged = true;\n\t\t\t\t\ti = j;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst indent = group[0].indent;\n\t\t\t\tmerged = true;\n\t\t\t\t/**\n\t\t\t\t * We only want to add terminal punctuation once at the end of the merged\n\t\t\t\t * paragraph, not after every original line (which can create spurious\n\t\t\t\t * periods mid-sentence when lines were simple wraps). We also avoid\n\t\t\t\t * appending a period if the final line ends with a colon introducing a\n\t\t\t\t * list.\n\t\t\t\t */\n\t\t\t\tconst norm = group.map((g) => normalizeNote(g.text.trim()));\n\t\t\t\t// Determine index of last non-empty line.\n\t\t\t\tlet lastIdx = norm.length - 1;\n\t\t\t\twhile (lastIdx > 0 && norm[lastIdx].trim() === \"\") {\n\t\t\t\t\tlastIdx--;\n\t\t\t\t}\n\t\t\t\tfor (let k = 0; k < norm.length; k++) {\n\t\t\t\t\tif (k === lastIdx) {\n\t\t\t\t\t\tconst ln = norm[k];\n\t\t\t\t\t\tif (!/:$/.test(ln.trim())) {\n\t\t\t\t\t\t\tnorm[k] = maybeAddPeriod(ln);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst para = norm.join(\" \").replace(/\\s+/g, \" \").trim();\n\t\t\t\tout.push(`${indent}/**`);\n\t\t\t\tout.push(`${indent} * ${para}`);\n\t\t\t\tout.push(`${indent} */`);\n\t\t\t\ti = j;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tout.push(lines[i]);\n\t\ti++;\n\t}\n\treturn { content: out.join(\"\\n\"), merged };\n}\n\nexport function parseAndTransformComments(\n\tinput: string,\n\toptions: ProcessOptions,\n): FileResult {\n\tlet working = input;\n\tif (options.mergeLineComments) {\n\t\tconst m = mergeLineCommentGroups(working);\n\t\tworking = m.content;\n\t}\n\tconst js = reflowJsDocBlocks(working, options.width);\n\tworking = js.content;\n\tif (options.wrapLineComments) {\n\t\tconst w = wrapLineComments(working, options.width);\n\t\tworking = w.content;\n\t}\n\treturn { original: input, transformed: working, changed: working !== input };\n}\n"],"names":["Logger","logger","boring","process","env","NODE_ENV","MAX_JSDOC_INDENT","JSDOC_REGEX","diffLines","a","b","A","split","B","out","m","Math","max","length","i","undefined","push","join","endsSentence","line","test","trim","needsTerminalPunctuation","maybeAddPeriod","normalizeNote","replace","isListLike","isTagLine","isHeadingLike","t","isCodeFence","isVisuallyIndentedCode","wrapWords","text","width","words","filter","Boolean","lines","cur","w","buildJsDoc","indent","rawBody","map","l","some","slice","internalBlank","para","inFence","prefix","avail","structured","raw","trimmed","trimEnd","flush","reflowJsDocBlocks","content","lastIndex","blocks","exec","body","start","index","end","delta","original","built","wrapLineComments","group","k","wrapped","changed","j","gm","applied","mergeLineCommentGroups","merged","qualifiesExplanatoryAfterStatement","collected","lm","c","prev","prevTrim","contextEligible","txt","g","ln","safe","norm","lastIdx","parseAndTransformComments","input","options","working","mergeLineComments","js","transformed"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAE1C,OAAO,IAAMC,SAAS,IAAID,OAAO;IAAEE,QAAQC,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAAO,GAAG;AAqB9E;;;;;;;CAOC,GACD,IAAMC,mBAAmB,KAAK,6BAA6B;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCC,GACD,IAAMC,cAAc;AAEpB,OAAO,SAASC,UAAUC,CAAS,EAAEC,CAAS;IAC7C,IAAID,MAAMC,GAAG;QACZ,OAAO;IACR;IACA,IAAMC,IAAIF,EAAEG,KAAK,CAAC;IAClB,IAAMC,IAAIH,EAAEE,KAAK,CAAC;IAClB,IAAME,MAAgB,EAAE;IACxB,IAAMC,IAAIC,KAAKC,GAAG,CAACN,EAAEO,MAAM,EAAEL,EAAEK,MAAM;IACrC,IAAK,IAAIC,IAAI,GAAGA,IAAIJ,GAAGI,IAAK;QAC3B,IAAIR,CAAC,CAACQ,EAAE,KAAKN,CAAC,CAACM,EAAE,EAAE;YAClB;QACD;QACA,IAAIR,CAAC,CAACQ,EAAE,KAAKC,WAAW;YACvBN,IAAIO,IAAI,CAAC,AAAC,KAAS,OAALV,CAAC,CAACQ,EAAE;QACnB;QACA,IAAIN,CAAC,CAACM,EAAE,KAAKC,WAAW;YACvBN,IAAIO,IAAI,CAAC,AAAC,KAAS,OAALR,CAAC,CAACM,EAAE;QACnB;IACD;IACA,OAAOL,IAAIQ,IAAI,CAAC;AACjB;AAEA,SAASC,aAAaC,IAAY;IACjC,OAAO,qBAAqBC,IAAI,CAACD,KAAKE,IAAI;AAC3C;AAEA,SAASC,yBAAyBH,IAAY;IAC7C,OAAO,oBAAoBC,IAAI,CAACD,SAAS,CAACD,aAAaC;AACxD;AAEA,SAASI,eAAeJ,IAAY;IACnC,OAAOG,yBAAyBH,QAAQA,OAAO,MAAMA;AACtD;AAEA,SAASK,cAAcL,IAAY;IAClC,OAAOA,KAAKM,OAAO,CAAC,WAAW;AAChC;AAEA,SAASC,WAAWP,IAAY;IAC/B,OAAO,qBAAqBC,IAAI,CAACD,KAAKE,IAAI;AAC3C;AAEA,SAASM,UAAUR,IAAY;IAC9B,OAAO,KAAKC,IAAI,CAACD,KAAKE,IAAI;AAC3B;AAEA,SAASO,cAAcT,IAAY;IAClC,IAAMU,IAAIV,KAAKE,IAAI;IACnB,IAAI,CAAC,KAAKD,IAAI,CAACS,MAAMF,UAAUE,IAAI;QAClC,OAAO;IACR;IACA;;;;;;EAMC,GACD,OAAO,kDAAkDT,IAAI,CAACS;AAC/D;AAEA,SAASC,YAAYX,IAAY;IAChC,OAAO,OAAOC,IAAI,CAACD,KAAKE,IAAI;AAC7B;AAEA,SAASU,uBAAuBZ,IAAY;IAC3C,OAAO,YAAYC,IAAI,CAACD;AACzB;AAEA,SAASa,UAAUC,IAAY,EAAEC,KAAa;IAC7C,IAAMC,QAAQF,KAAK1B,KAAK,CAAC,OAAO6B,MAAM,CAACC;IACvC,IAAMC,QAAkB,EAAE;IAC1B,IAAIC,MAAM;QACL,kCAAA,2BAAA;;QAAL,QAAK,YAAWJ,0BAAX,SAAA,6BAAA,QAAA,yBAAA,iCAAkB;YAAlB,IAAMK,IAAN;YACJ,IAAI,CAACD,IAAI1B,MAAM,EAAE;gBAChB0B,MAAMC;gBACN;YACD;YACA,IAAID,IAAI1B,MAAM,GAAG,IAAI2B,EAAE3B,MAAM,IAAIqB,OAAO;gBACvCK,OAAO,MAAMC;YACd,OAAO;gBACNF,MAAMtB,IAAI,CAACuB;gBACXA,MAAMC;YACP;QACD;;QAXK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAYL,IAAID,KAAK;QACRD,MAAMtB,IAAI,CAACuB;IACZ;IACA,OAAOD,MAAMzB,MAAM,GAAGyB,QAAQ;QAAC;KAAG;AACnC;AAEA,SAASG,WAAWC,MAAc,EAAEC,OAAe,EAAET,KAAa;IACjE,IAAII,QAAQK,QAAQpC,KAAK,CAAC,MAAMqC,GAAG,CAAC,SAACC;eAAMA,EAAEpB,OAAO,CAAC,aAAa;;IAClE,+EAA+E;IAC/E,2BAA2B;IAC3B,MACCa,MAAMzB,MAAM,GAAG,KACfyB,KAAK,CAAC,EAAE,CAACjB,IAAI,OAAO,MACpBiB,MAAMQ,IAAI,CAAC,SAACD;eAAMA,EAAExB,IAAI,OAAO;OAC9B;QACDiB,QAAQA,MAAMS,KAAK,CAAC;IACrB;IACA;;;;;EAKC,GACD,IAAIT,MAAMzB,MAAM,GAAG,KAAKyB,KAAK,CAACA,MAAMzB,MAAM,GAAG,EAAE,CAACQ,IAAI,OAAO,IAAI;QAC9D,IAAM2B,gBAAgBV,MAAMS,KAAK,CAAC,GAAG,CAAC,GAAGD,IAAI,CAAC,SAACD;mBAAMA,EAAExB,IAAI,OAAO;;QAClE,IAAI,CAAC2B,eAAe;YACnBV,QAAQA,MAAMS,KAAK,CAAC,GAAG,CAAC;QACzB;IACD;IACA,IAAMtC,MAAgB,EAAE;IACxB,IAAIwC,OAAiB,EAAE;IACvB,IAAIC,UAAU;IACd,IAAMC,SAAST,SAAS;IACxB,IAAMU,QAAQzC,KAAKC,GAAG,CAAC,IAAIsB,QAAQiB,OAAOtC,MAAM;IAEhD;;;;EAIC,GACD,IAAMwC,aAAaf,MAAMQ,IAAI,CAC5B,SAACD;eACA,KAAKzB,IAAI,CAACyB,MAAM,eAAezB,IAAI,CAACyB,MAAM,wBAAwBzB,IAAI,CAACyB;;IAEzE,IAAIQ,YAAY;YACV,kCAAA,2BAAA;;YAAL,QAAK,YAAaf,0BAAb,SAAA,6BAAA,QAAA,yBAAA,iCAAoB;gBAApB,IAAMgB,MAAN;gBACJ,IAAMC,UAAUD,IAAIE,OAAO;gBAC3B,IAAID,YAAY,IAAI;oBACnB,iDAAiD;oBACjD,IACC9C,IAAII,MAAM,KAAK,KACf,iBAAiBO,IAAI,CAACX,GAAG,CAACA,IAAII,MAAM,GAAG,EAAE,MAAM,OAC9C;wBACDJ,IAAIO,IAAI,CAACmC,OAAOK,OAAO;oBACxB;oBACA;gBACD;gBACA/C,IAAIO,IAAI,CAACmC,SAAS3B,cAAc+B;YACjC;;YAbK;YAAA;;;qBAAA,6BAAA;oBAAA;;;oBAAA;0BAAA;;;;QAcL,OAAO,AAAC,GAAgB9C,OAAdiC,QAAO,SAA0BA,OAAnBjC,IAAIQ,IAAI,CAAC,OAAM,MAAW,OAAPyB,QAAO;IACnD;IAEA,SAASe;QACR,IAAI,CAACR,KAAKpC,MAAM,EAAE;YACjB;QACD;QACA,IAAIoB,OAAOgB,KAAKhC,IAAI,CAAC,KAAKQ,OAAO,CAAC,QAAQ,KAAKJ,IAAI;QACnDY,OAAOT,cAAcS;QACrBA,OAAOV,eAAeU;YACjB,kCAAA,2BAAA;;YAAL,QAAK,YAAWD,UAAUC,MAAMmB,2BAA3B,SAAA,6BAAA,QAAA,yBAAA,iCAAmC;gBAAnC,IAAMP,IAAN;gBACJpC,IAAIO,IAAI,CAACmC,SAASN;YACnB;;YAFK;YAAA;;;qBAAA,6BAAA;oBAAA;;;oBAAA;0BAAA;;;;QAGLI,OAAO,EAAE;IACV;QAEK,mCAAA,4BAAA;;QAAL,QAAK,aAAaX,0BAAb,UAAA,8BAAA,SAAA,0BAAA,kCAAoB;YAApB,IAAMgB,OAAN;YACJ,IAAMC,WAAUD,KAAIE,OAAO;YAC3B,IAAI1B,YAAYyB,WAAU;gBACzBE;gBACAP,UAAU,CAACA;gBACXzC,IAAIO,IAAI,CAACmC,SAASI;gBAClB;YACD;YACA,IAAIL,SAAS;gBACZzC,IAAIO,IAAI,CAACmC,SAASI;gBAClB;YACD;YACA,IACCA,aAAY,MACZ7B,WAAW6B,aACX5B,UAAU4B,aACV3B,cAAc2B,aACdxB,uBAAuBuB,OACtB;gBACDG;gBACA,IAAIF,aAAY,IAAI;oBACnB,IACC9C,IAAII,MAAM,KAAK,KACf,iBAAiBO,IAAI,CAACX,GAAG,CAACA,IAAII,MAAM,GAAG,EAAE,MAAM,OAC9C;wBACDJ,IAAIO,IAAI,CAACmC,OAAOK,OAAO;oBACxB;gBACD,OAAO;oBACN/C,IAAIO,IAAI,CAACmC,SAAS3B,cAAc+B;gBACjC;gBACA;YACD;YACAN,KAAKjC,IAAI,CAACuC;QACX;;QAjCK;QAAA;;;iBAAA,8BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAkCLE;IACA,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,OAAO,AAAC,GAAgBhD,OAAdiC,QAAO,SAA0BA,OAAnBjC,IAAIQ,IAAI,CAAC,OAAM,MAAW,OAAPyB,QAAO;AACnD;AAEA,SAASgB,kBACRC,OAAe,EACfzB,KAAa;IAEbhC,YAAY0D,SAAS,GAAG;IACxB,IAAMC,SAAuB,EAAE;IAC/B,IAAInD,IAA4BR,YAAY4D,IAAI,CAACH;IACjD,MAAOjD,EAAG;QACT,IAAMgC,SAAShC,CAAC,CAAC,EAAE,IAAI;QACvB,IAAMqD,OAAOrD,CAAC,CAAC,EAAE,IAAI;QACrB,qEAAqE;QACrE,IAAIqD,KAAKlD,MAAM,IAAI,UAAW6B,OAAO7B,MAAM,IAAIZ,kBAAkB;YAChE4D,OAAO7C,IAAI,CAAC;gBACX0B,QAAAA;gBACAqB,MAAAA;gBACAC,OAAOtD,EAAEuD,KAAK;gBACdC,KAAKxD,EAAEuD,KAAK,GAAGvD,CAAC,CAAC,EAAE,CAACG,MAAM;YAC3B;QACD;QACAH,IAAIR,YAAY4D,IAAI,CAACH;IACtB;IACA,IAAI,CAACE,OAAOhD,MAAM,EAAE;QACnB,OAAO;YAAE8C,SAAAA;YAASE,QAAQ;QAAE;IAC7B;IACA,IAAIM,QAAQ;IACZ,IAAI1D,MAAMkD;QACL,kCAAA,2BAAA;;QAAL,QAAK,YAAWE,2BAAX,SAAA,6BAAA,QAAA,yBAAA,iCAAmB;YAAnB,IAAMxD,IAAN;YACJ,IAAM+D,WAAW3D,IAAIsC,KAAK,CAAC1C,EAAE2D,KAAK,GAAGG,OAAO9D,EAAE6D,GAAG,GAAGC;YACpD,IAAME,QAAQ5B,WAAWpC,EAAEqC,MAAM,EAAErC,EAAE0D,IAAI,EAAE7B;YAC3C,IAAIkC,aAAaC,OAAO;gBACvB5D,MAAMA,IAAIsC,KAAK,CAAC,GAAG1C,EAAE2D,KAAK,GAAGG,SAASE,QAAQ5D,IAAIsC,KAAK,CAAC1C,EAAE6D,GAAG,GAAGC;gBAChEA,SAASE,MAAMxD,MAAM,GAAGuD,SAASvD,MAAM;YACxC;QACD;;QAPK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAQL,OAAO;QAAE8C,SAASlD;QAAKoD,QAAQA,OAAOhD,MAAM;IAAC;AAC9C;AAEA,SAASyD,iBACRX,OAAe,EACfzB,KAAa;;;gBAwEXzB;YAZA,IAAyB8D,WAAAA,KAAK,CAACC,EAAE,EAAzB9B,SAAiB6B,SAAjB7B,QAAQqB,OAASQ,SAATR;YAChB,IAAMZ,SAAST,SAAS;YACxB,IAAMU,QAAQzC,KAAKC,GAAG,CAAC,IAAIsB,QAAQiB,OAAOtC,MAAM;YAChD,IAAIoB,OAAO8B,KAAKtC,OAAO,CAAC,QAAQ,KAAKJ,IAAI;YACzCY,OAAOT,cAAcS;YACrB,IAAIuC,MAAMD,MAAM1D,MAAM,GAAG,KAAK,CAAC,KAAKO,IAAI,CAACa,KAAKZ,IAAI,KAAK;gBACtDY,OAAOV,eAAeU;YACvB;YACA,IAAMwC,UAAUzC,UAAUC,MAAMmB,OAAOR,GAAG,CAAC,SAACJ;uBAAMW,SAASX;;YAC3D,IAAIiC,QAAQxD,IAAI,CAAC,UAAUsD,KAAK,CAACC,EAAE,CAAClB,GAAG,EAAE;gBACxCoB,UAAU;YACX;YACAjE,CAAAA,OAAAA,KAAIO,IAAI,OAARP,MAAS,qBAAGgE;QACb;QAlEA,IAAMtD,OAAOmB,KAAK,CAACxB,EAAE;QACrB,IAAMJ,IAAI,sBAAsBoD,IAAI,CAAC3C;QACrC,IAAI,CAACT,KAAK,UAAUU,IAAI,CAACD,OAAO;YAC/BV,IAAIO,IAAI,CAACG;YACTL;YACA,OAAA;QACD;QACA;;;GAGC,GACD,IAAMyD,QAAyD,EAAE;QACjE,IAAII,IAAI7D;QACR,MAAO6D,IAAIrC,MAAMzB,MAAM,CAAE;YACxB,IAAM+D,KAAK,oBAAoBd,IAAI,CAACxB,KAAK,CAACqC,EAAE;YAC5C,IAAI,CAACC,MAAM,UAAUxD,IAAI,CAACkB,KAAK,CAACqC,EAAE,GAAG;gBACpC;YACD;YACA,IAAMZ,OAAOa,EAAE,CAAC,EAAE;YAClB,IAAI,wBAAwBxD,IAAI,CAAC2C,SAAS,cAAc3C,IAAI,CAAC2C,OAAO;gBACnE,OAAO,mEAAmE;YAC3E;YACAQ,MAAMvD,IAAI,CAAC;gBAAEsC,KAAKhB,KAAK,CAACqC,EAAE;gBAAEjC,QAAQkC,EAAE,CAAC,EAAE;gBAAEb,MAAAA;YAAK;YAChDY;QACD;QACA,IAAIJ,MAAM1D,MAAM,IAAI,GAAG;gBAkBtBJ;YAjBA,sDAAsD;YACtD,IAAMiC,SAAShC,CAAC,CAAC,EAAE;YACnB,IAAMqD,QAAOrD,CAAC,CAAC,EAAE;YACjB,IAAI,wBAAwBU,IAAI,CAAC2C,UAAS,cAAc3C,IAAI,CAAC2C,QAAO;gBACnEtD,IAAIO,IAAI,CAACG;gBACTL;gBACA,OAAA;YACD;YACA,IAAMqC,SAAST,SAAS;YACxB,IAAMU,QAAQzC,KAAKC,GAAG,CAAC,IAAIsB,QAAQiB,OAAOtC,MAAM;YAChD,IAAIoB,OAAO8B,MAAKtC,OAAO,CAAC,QAAQ,KAAKJ,IAAI;YACzCY,OAAOT,cAAcS;YACrBA,OAAOV,eAAeU;YACtB,IAAMwC,UAAUzC,UAAUC,MAAMmB,OAAOR,GAAG,CAAC,SAACJ;uBAAMW,SAASX;;YAC3D,IAAIiC,QAAQxD,IAAI,CAAC,UAAUE,MAAM;gBAChCuD,UAAU;YACX;YACAjE,CAAAA,OAAAA,KAAIO,IAAI,OAARP,MAAS,qBAAGgE;YACZ3D;YACA,OAAA;QACD;QACA;;;;GAIC,GACD,IAAK,IAAI0D,IAAI,GAAGA,IAAID,MAAM1D,MAAM,EAAE2D;QAelC1D,IAAI6D;IACL;IAzEA,IAAMrC,QAAQqB,QAAQpD,KAAK,CAAC;IAC5B,IAAImE,UAAU;IACd,IAAMjE,MAAgB,EAAE;IACxB,IAAIK,IAAI;IACR,MAAOA,IAAIwB,MAAMzB,MAAM;IAsEvB,OAAO;QAAE8C,SAASlD,IAAIQ,IAAI,CAAC;QAAO4D,SAASH;IAAQ;AACpD;AAEA,SAASI,uBAAuBnB,OAAe;IAI9C,IAAMrB,QAAQqB,QAAQpD,KAAK,CAAC;IAC5B,IAAME,MAAgB,EAAE;IACxB,IAAIK,IAAI;IACR,IAAIiE,SAAS;IAEb,SAASC,mCAAmChB,KAAa;QACxD,uEAAuE;QACvE,IAAMiB,YAAsB,EAAE;QAC9B,IAAK,IAAIT,IAAIR,OAAOQ,IAAIlC,MAAMzB,MAAM,EAAE2D,IAAK;YAC1C,IAAMU,KAAK,sBAAsBpB,IAAI,CAACxB,KAAK,CAACkC,EAAE;YAC9C,IAAI,CAACU,MAAM,UAAU9D,IAAI,CAACkB,KAAK,CAACkC,EAAE,GAAG;gBACpC;YACD;YACA,IAAMT,OAAOmB,EAAE,CAAC,EAAE;YAClB,IAAI,wBAAwB9D,IAAI,CAAC2C,SAAS,cAAc3C,IAAI,CAAC2C,OAAO;gBACnE;YACD;YACAkB,UAAUjE,IAAI,CAAC+C,KAAK1C,IAAI;QACzB;QACA,IAAI4D,UAAUpE,MAAM,GAAG,GAAG;YACzB,OAAO,OAAO,uBAAuB;QACtC;QACA,IAAI,CAAC,SAASO,IAAI,CAAC6D,SAAS,CAAC,EAAE,GAAG;YACjC,OAAO,OAAO,kCAAkC;QACjD;QACA;;;GAGC,GACD,OAAOA,UAAUnC,IAAI,CAAC,SAACqC;mBAAM,KAAK/D,IAAI,CAAC+D;;IACxC;IACA,MAAOrE,IAAIwB,MAAMzB,MAAM,CAAE;QACxB,IAAI,WAAWO,IAAI,CAACkB,KAAK,CAACxB,EAAE,KAAK,CAAC,aAAaM,IAAI,CAACkB,KAAK,CAACxB,EAAE,GAAG;YAC9D,IAAMsE,OAAOtE,IAAI,IAAIwB,KAAK,CAACxB,IAAI,EAAE,GAAG;YACpC,IAAMuE,WAAWD,KAAK/D,IAAI;YAC1B,IAAIiE,kBAAkBD,aAAa,MAAM,QAAQjE,IAAI,CAACiE;YACtD;;;;IAIC,GACD,IACC,CAACC,mBACD,QAAQlE,IAAI,CAACiE,aACbL,mCAAmClE,IAClC;gBACDwE,kBAAkB;YACnB;YACA,IAAI,CAACA,iBAAiB;gBACrB7E,IAAIO,IAAI,CAACsB,KAAK,CAACxB,EAAE;gBACjBA;gBACA;YACD;YACA,IAAMyD,QAA4C,EAAE;YACpD,IAAII,IAAI7D;YACR,MAAO6D,IAAIrC,MAAMzB,MAAM,CAAE;gBACxB,IAAMqE,KAAK,oBAAoBpB,IAAI,CAACxB,KAAK,CAACqC,EAAE;gBAC5C,IAAI,CAACO,MAAM,aAAa9D,IAAI,CAACkB,KAAK,CAACqC,EAAE,GAAG;oBACvC;gBACD;gBACA,IAAMY,MAAML,EAAE,CAAC,EAAE;gBACjB,IACC,qBAAqB9D,IAAI,CAACmE,QAC1B,cAAcnE,IAAI,CAACmE,QACnB,mBAAmBnE,IAAI,CAACmE,MACvB;oBACD,OAAO,0CAA0C;gBAClD;gBACAhB,MAAMvD,IAAI,CAAC;oBAAE0B,QAAQwC,EAAE,CAAC,EAAE;oBAAEjD,MAAMsD;gBAAI;gBACtCZ;YACD;YACA,IAAIJ,MAAM1D,MAAM,IAAI,GAAG;gBACtB;;;;;;KAMC,GACD,IAAMwC,aAAakB,MAAMzB,IAAI,CAC5B,SAAC0C;2BACA,KAAKpE,IAAI,CAACoE,EAAEvD,IAAI,KAChB,eAAeb,IAAI,CAACoE,EAAEvD,IAAI,KAC1B,wBAAwBb,IAAI,CAACoE,EAAEvD,IAAI;;gBAErC,IAAIoB,YAAY;oBACf,IAAMX,SAAS6B,KAAK,CAAC,EAAE,CAAC7B,MAAM;oBAC9BjC,IAAIO,IAAI,CAAC,AAAC,GAAS,OAAP0B,QAAO;wBACd,kCAAA,2BAAA;;wBAAL,QAAK,YAAY6B,0BAAZ,SAAA,6BAAA,QAAA,yBAAA,iCAAmB;4BAAnB,IAAMkB,KAAN;4BACJ,0CAA0C;4BAC1C,IAAMC,OAAOD,GAAGxD,IAAI,CAACR,OAAO,CAAC,SAAS;4BACtChB,IAAIO,IAAI,CAAC,AAAC,GAAc0E,OAAZhD,QAAO,OAAU,OAALgD;wBACzB;;wBAJK;wBAAA;;;iCAAA,6BAAA;gCAAA;;;gCAAA;sCAAA;;;;oBAKLjF,IAAIO,IAAI,CAAC,AAAC,GAAS,OAAP0B,QAAO;oBACnBqC,SAAS;oBACTjE,IAAI6D;oBACJ;gBACD;gBACA,IAAMjC,UAAS6B,KAAK,CAAC,EAAE,CAAC7B,MAAM;gBAC9BqC,SAAS;gBACT;;;;;;KAMC,GACD,IAAMY,OAAOpB,MAAM3B,GAAG,CAAC,SAAC4C;2BAAMhE,cAAcgE,EAAEvD,IAAI,CAACZ,IAAI;;gBACvD,0CAA0C;gBAC1C,IAAIuE,UAAUD,KAAK9E,MAAM,GAAG;gBAC5B,MAAO+E,UAAU,KAAKD,IAAI,CAACC,QAAQ,CAACvE,IAAI,OAAO,GAAI;oBAClDuE;gBACD;gBACA,IAAK,IAAIpB,IAAI,GAAGA,IAAImB,KAAK9E,MAAM,EAAE2D,IAAK;oBACrC,IAAIA,MAAMoB,SAAS;wBAClB,IAAMH,MAAKE,IAAI,CAACnB,EAAE;wBAClB,IAAI,CAAC,KAAKpD,IAAI,CAACqE,IAAGpE,IAAI,KAAK;4BAC1BsE,IAAI,CAACnB,EAAE,GAAGjD,eAAekE;wBAC1B;oBACD;gBACD;gBACA,IAAMxC,OAAO0C,KAAK1E,IAAI,CAAC,KAAKQ,OAAO,CAAC,QAAQ,KAAKJ,IAAI;gBACrDZ,IAAIO,IAAI,CAAC,AAAC,GAAS,OAAP0B,SAAO;gBACnBjC,IAAIO,IAAI,CAAC,AAAC,GAAciC,OAAZP,SAAO,OAAU,OAALO;gBACxBxC,IAAIO,IAAI,CAAC,AAAC,GAAS,OAAP0B,SAAO;gBACnB5B,IAAI6D;gBACJ;YACD;QACD;QACAlE,IAAIO,IAAI,CAACsB,KAAK,CAACxB,EAAE;QACjBA;IACD;IACA,OAAO;QAAE6C,SAASlD,IAAIQ,IAAI,CAAC;QAAO8D,QAAAA;IAAO;AAC1C;AAEA,OAAO,SAASc,0BACfC,KAAa,EACbC,OAAuB;IAEvB,IAAIC,UAAUF;IACd,IAAIC,QAAQE,iBAAiB,EAAE;QAC9B,IAAMvF,IAAIoE,uBAAuBkB;QACjCA,UAAUtF,EAAEiD,OAAO;IACpB;IACA,IAAMuC,KAAKxC,kBAAkBsC,SAASD,QAAQ7D,KAAK;IACnD8D,UAAUE,GAAGvC,OAAO;IACpB,IAAIoC,QAAQzB,gBAAgB,EAAE;QAC7B,IAAM9B,IAAI8B,iBAAiB0B,SAASD,QAAQ7D,KAAK;QACjD8D,UAAUxD,EAAEmB,OAAO;IACpB;IACA,OAAO;QAAES,UAAU0B;QAAOK,aAAaH;QAAStB,SAASsB,YAAYF;IAAM;AAC5E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-cli/comments",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "description": "CLI tool to reflow and normalize JSDoc and line comments in source files",
@@ -19,7 +19,9 @@
19
19
  "build:js": "swc --strip-leading-paths --source-maps --out-dir dist src",
20
20
  "build:types": "tsc",
21
21
  "clean": "rimraf dist types coverage",
22
+ "comments:fix": "comments --merge-line-comments 'src/**/*.ts'",
22
23
  "lint": "biome lint src",
24
+ "lint:fix": "biome check src --write --no-errors-on-unmatched",
23
25
  "test": "vitest run --globals",
24
26
  "test:coverage": "vitest run --coverage --globals",
25
27
  "test:watch": "vitest --globals",
@@ -28,7 +30,8 @@
28
30
  "dependencies": {
29
31
  "@node-cli/logger": "../logger",
30
32
  "@node-cli/parser": "../parser",
31
- "@node-cli/utilities": "../utilities"
33
+ "@node-cli/utilities": "../utilities",
34
+ "micromatch": "4.0.8"
32
35
  },
33
36
  "publishConfig": {
34
37
  "access": "public"
@@ -37,5 +40,5 @@
37
40
  "@vitest/coverage-v8": "3.2.4",
38
41
  "vitest": "3.2.4"
39
42
  },
40
- "gitHead": "8fa2b0048fd24b0278b446a9291fb78506041c05"
43
+ "gitHead": "59f5469150f5448e0fd88f855d7a2435065ffab6"
41
44
  }