@naturalcycles/dev-lib 20.12.2 → 20.12.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.
@@ -52,12 +52,51 @@ function isMethodOverload(node) {
52
52
  return node.value && node.value.type === 'TSEmptyBodyFunctionExpression'
53
53
  }
54
54
 
55
+ function getInsertionTarget(sourceCode, prevNode, nextNode) {
56
+ const decoratorTarget = findDecoratorTarget(sourceCode, prevNode, nextNode)
57
+ const commentTarget = findLeadingComment(sourceCode, prevNode, nextNode)
58
+
59
+ let target = decoratorTarget || nextNode
60
+
61
+ if (commentTarget && (!target.range || commentTarget.range[0] < target.range[0])) {
62
+ target = commentTarget
63
+ }
64
+
65
+ return target
66
+ }
67
+
68
+ function findLeadingComment(sourceCode, prevNode, nextNode) {
69
+ const comments = sourceCode.getCommentsBefore(nextNode) || []
70
+ return comments
71
+ .filter(comment => {
72
+ if (!comment.range || comment.range[0] < prevNode.range[1]) return false
73
+ const prevLine = prevNode.loc?.end?.line
74
+ const commentLine = comment.loc?.start?.line
75
+ return prevLine === undefined || commentLine === undefined || commentLine > prevLine
76
+ })
77
+ .sort((a, b) => a.range[0] - b.range[0])[0]
78
+ }
79
+
80
+ function findDecoratorTarget(sourceCode, prevNode, nextNode) {
81
+ const segment = sourceCode.text.slice(prevNode.range[1], nextNode.range[0])
82
+ const decoratorRegex = /(?:^|\n)([ \t]*@)/
83
+ const match = decoratorRegex.exec(segment)
84
+ if (!match || match.index === undefined) return null
85
+
86
+ const relative = match.index + match[0].length - match[1].length
87
+ const absolute = prevNode.range[1] + relative
88
+ return { range: [absolute, absolute], loc: null }
89
+ }
90
+
55
91
  function hasBlankLineBetween(sourceCode, prevNode, nextNode) {
56
92
  if (!prevNode || !nextNode) return false
57
93
  if (!prevNode.range || !nextNode.range) return false
58
94
  if (prevNode.range[1] >= nextNode.range[0]) return false
59
95
 
60
- const between = sourceCode.text.slice(prevNode.range[1], nextNode.range[0])
96
+ const target = getInsertionTarget(sourceCode, prevNode, nextNode)
97
+ if (!target.range) return false
98
+
99
+ const between = sourceCode.text.slice(prevNode.range[1], target.range[0])
61
100
  return BLANK_LINE_PATTERN.test(between)
62
101
  }
63
102
 
@@ -66,12 +105,9 @@ function insertBlankLineBeforeNext(fixer, sourceCode, prevNode, nextNode) {
66
105
  if (!prevNode.range || !nextNode.range) return null
67
106
  if (prevNode.range[1] >= nextNode.range[0]) return null
68
107
 
69
- const commentsBetween = sourceCode
70
- .getCommentsBefore(nextNode)
71
- ?.filter(comment => comment.range && comment.range[0] >= prevNode.range[1])
72
- ?.sort((a, b) => a.range[0] - b.range[0])
73
- const insertionTarget =
74
- commentsBetween && commentsBetween.length > 0 ? commentsBetween[0].range[0] : nextNode.range[0]
108
+ const target = getInsertionTarget(sourceCode, prevNode, nextNode)
109
+ if (!target.range) return null
110
+ const insertionTarget = target.range[0]
75
111
 
76
112
  const between = sourceCode.text.slice(prevNode.range[1], insertionTarget)
77
113
  const hasLinebreak = /\r?\n/.test(between)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/dev-lib",
3
3
  "type": "module",
4
- "version": "20.12.2",
4
+ "version": "20.12.3",
5
5
  "dependencies": {
6
6
  "@biomejs/biome": "^2",
7
7
  "@commitlint/cli": "^20",