@naturalcycles/dev-lib 20.12.2 → 20.12.4

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,67 @@ 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 baseNode = nextNode.declaration || nextNode
58
+ const targetStart = decoratorTarget?.range?.[0] ?? baseNode?.range?.[0] ?? nextNode.range[0]
59
+ const docCommentTarget = findDocCommentBeforeIndex(sourceCode, prevNode, targetStart)
60
+ if (docCommentTarget) return docCommentTarget
61
+
62
+ const commentTarget = findLeadingComment(sourceCode, prevNode, nextNode)
63
+
64
+ let target = decoratorTarget || nextNode
65
+
66
+ if (commentTarget && (!target.range || commentTarget.range[0] < target.range[0])) {
67
+ target = commentTarget
68
+ }
69
+
70
+ return target
71
+ }
72
+
73
+ function findLeadingComment(sourceCode, prevNode, nextNode) {
74
+ const comments = sourceCode.getCommentsBefore(nextNode) || []
75
+ return comments
76
+ .filter(comment => {
77
+ if (!comment.range || comment.range[0] < prevNode.range[1]) return false
78
+ const prevLine = prevNode.loc?.end?.line
79
+ const commentLine = comment.loc?.start?.line
80
+ return prevLine === undefined || commentLine === undefined || commentLine > prevLine
81
+ })
82
+ .sort((a, b) => a.range[0] - b.range[0])[0]
83
+ }
84
+
85
+ function findDecoratorTarget(sourceCode, prevNode, nextNode) {
86
+ const segment = sourceCode.text.slice(prevNode.range[1], nextNode.range[0])
87
+ const decoratorRegex = /(?:^|\n)([ \t]*@)/
88
+ const match = decoratorRegex.exec(segment)
89
+ if (!match || match.index === undefined) return null
90
+
91
+ const relative = match.index + match[0].length - match[1].length
92
+ const absolute = prevNode.range[1] + relative
93
+ return { range: [absolute, absolute], loc: null }
94
+ }
95
+
96
+ function findDocCommentBeforeIndex(sourceCode, prevNode, targetStart) {
97
+ if (targetStart === undefined || targetStart <= prevNode.range[1]) return null
98
+
99
+ const slice = sourceCode.text.slice(prevNode.range[1], targetStart)
100
+ const docMatch = slice.match(/(\/\*\*[\s\S]*?\*\/)([ \t]*\r?\n[ \t]*)?$/)
101
+ if (!docMatch || docMatch.index === undefined) return null
102
+
103
+ const commentStart = prevNode.range[1] + docMatch.index
104
+ return { range: [commentStart, commentStart], loc: null }
105
+ }
106
+
55
107
  function hasBlankLineBetween(sourceCode, prevNode, nextNode) {
56
108
  if (!prevNode || !nextNode) return false
57
109
  if (!prevNode.range || !nextNode.range) return false
58
110
  if (prevNode.range[1] >= nextNode.range[0]) return false
59
111
 
60
- const between = sourceCode.text.slice(prevNode.range[1], nextNode.range[0])
112
+ const target = getInsertionTarget(sourceCode, prevNode, nextNode)
113
+ if (!target.range) return false
114
+
115
+ const between = sourceCode.text.slice(prevNode.range[1], target.range[0])
61
116
  return BLANK_LINE_PATTERN.test(between)
62
117
  }
63
118
 
@@ -66,12 +121,9 @@ function insertBlankLineBeforeNext(fixer, sourceCode, prevNode, nextNode) {
66
121
  if (!prevNode.range || !nextNode.range) return null
67
122
  if (prevNode.range[1] >= nextNode.range[0]) return null
68
123
 
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]
124
+ const target = getInsertionTarget(sourceCode, prevNode, nextNode)
125
+ if (!target.range) return null
126
+ const insertionTarget = target.range[0]
75
127
 
76
128
  const between = sourceCode.text.slice(prevNode.range[1], insertionTarget)
77
129
  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.4",
5
5
  "dependencies": {
6
6
  "@biomejs/biome": "^2",
7
7
  "@commitlint/cli": "^20",