@preventive/compare 1.0.1 → 1.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/pretty.js +23 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preventive/compare",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Two file trees compared as git diff compares them, with their line change sets and the patch git writes; and minified JavaScript compared with its layout and its renamed names set aside, each step checked to hide no change",
5
5
  "type": "module",
6
6
  "main": "./compare.js",
package/src/pretty.js CHANGED
@@ -89,6 +89,27 @@ export function sameCode(text, formatted, extension = 'js', csstree = null) {
89
89
  return before !== null && after !== null && sameList(comments(before), comments(after)) && sameTree(before.program, after.program)
90
90
  }
91
91
 
92
+ // A script's block comments over more than one line, a license's say, each end their line: what oxfmt
93
+ // leaves after one on its last line (`*/ class A {`) goes to the next, indented as the comment's first
94
+ // line is. A comment holding a line break ends a line to the parser already (`return /*\n*/ 1` returns),
95
+ // so the break changes nothing it reads; the check after says so.
96
+ function breakAfterComments(code, extension) {
97
+ if (!SCRIPTS.has(extension) || !/\*\/[\t ]*\S/u.test(code)) return code
98
+ const result = parsed(code, extension)
99
+ if (!result) return code
100
+ let from = 0, out = ''
101
+ for (const { type, value, start, end } of result.comments) {
102
+ const lineEnd = code.indexOf('\n', end)
103
+ const rest = code.slice(end, lineEnd === -1 ? code.length : lineEnd)
104
+ if (type !== 'Block' || !value.includes('\n') || rest.trim() === '') continue
105
+ out += code.slice(from, end)
106
+ const line = out.slice(out.lastIndexOf('\n', out.length - (end - start)) + 1)
107
+ out += `\n${/^[\t ]*/u.exec(line)[0]}`
108
+ from = end + rest.length - rest.trimStart().length
109
+ }
110
+ return out + code.slice(from)
111
+ }
112
+
92
113
  // Only what can be checked is formatted: scripts, JSON, and CSS where css-tree is there to read it.
93
114
  // oxfmt is loaded outside the try: one missing is thrown, not taken for a file that won't format.
94
115
  export async function format(text, extension) {
@@ -99,7 +120,8 @@ export async function format(text, extension) {
99
120
  if (result === null || result.errors.length > 0) return { error: 'unformattable' }
100
121
  // A check that fails in itself, its stack say, refuses the copy as one that finds it changed would.
101
122
  try {
102
- return sameCode(text, result.code, extension, csstree) ? { code: result.code } : { error: 'pretty-mismatch' }
123
+ const code = breakAfterComments(result.code, extension)
124
+ return sameCode(text, code, extension, csstree) ? { code } : { error: 'pretty-mismatch' }
103
125
  } catch {
104
126
  return { error: 'pretty-mismatch' }
105
127
  }