prettier-plugin-multiline-arrays-2 1.0.0 → 5.0.0

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 (62) hide show
  1. package/README.md +5 -19
  2. package/dist/augments/array.d.ts +8 -2
  3. package/dist/augments/array.js +11 -5
  4. package/dist/augments/doc.d.ts +2 -2
  5. package/dist/augments/doc.js +12 -9
  6. package/dist/augments/string.js +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +42 -20
  9. package/dist/options.d.ts +6 -9
  10. package/dist/options.js +20 -25
  11. package/dist/plugin-marker.js +1 -1
  12. package/dist/preprocessing.d.ts +1 -1
  13. package/dist/preprocessing.js +60 -30
  14. package/dist/printer/child-docs.d.ts +9 -7
  15. package/dist/printer/child-docs.js +89 -63
  16. package/dist/printer/comment-triggers.d.ts +5 -7
  17. package/dist/printer/comment-triggers.js +104 -134
  18. package/dist/printer/comments.d.ts +1 -1
  19. package/dist/printer/comments.js +15 -16
  20. package/dist/printer/insert-new-lines.d.ts +10 -6
  21. package/dist/printer/insert-new-lines.js +260 -277
  22. package/dist/printer/leading-new-line.d.ts +2 -2
  23. package/dist/printer/leading-new-line.js +2 -1
  24. package/dist/printer/multiline-array-printer.js +4 -2
  25. package/dist/printer/original-printer.js +6 -4
  26. package/dist/printer/supported-node-types.d.ts +1 -1
  27. package/dist/printer/supported-node-types.js +6 -5
  28. package/dist/printer/trailing-comma.d.ts +1 -1
  29. package/dist/printer/trailing-comma.js +1 -1
  30. package/package.json +56 -29
  31. package/dist/augments/array.test.d.ts +0 -1
  32. package/dist/augments/array.test.js +0 -34
  33. package/dist/options.test.d.ts +0 -1
  34. package/dist/options.test.js +0 -48
  35. package/dist/printer/insert-new-lines.test.d.ts +0 -1
  36. package/dist/printer/insert-new-lines.test.js +0 -36
  37. package/dist/readme-examples/formatted-with-comments.example.d.ts +0 -3
  38. package/dist/readme-examples/formatted-with-comments.example.js +0 -16
  39. package/dist/readme-examples/formatted.example.d.ts +0 -2
  40. package/dist/readme-examples/formatted.example.js +0 -12
  41. package/dist/readme-examples/not-formatted.example.d.ts +0 -2
  42. package/dist/readme-examples/not-formatted.example.js +0 -6
  43. package/dist/readme-examples/prettier-options.example.d.ts +0 -4
  44. package/dist/readme-examples/prettier-options.example.js +0 -5
  45. package/dist/test/babel-ts.test.d.ts +0 -1
  46. package/dist/test/babel-ts.test.js +0 -10
  47. package/dist/test/javascript.test.d.ts +0 -1
  48. package/dist/test/javascript.test.js +0 -702
  49. package/dist/test/json.test.d.ts +0 -1
  50. package/dist/test/json.test.js +0 -403
  51. package/dist/test/json5.test.d.ts +0 -1
  52. package/dist/test/json5.test.js +0 -210
  53. package/dist/test/prettier-config.d.ts +0 -2
  54. package/dist/test/prettier-config.js +0 -12
  55. package/dist/test/prettier-versions.mock.script.d.ts +0 -1
  56. package/dist/test/prettier-versions.mock.script.js +0 -123
  57. package/dist/test/run-tests.mock.d.ts +0 -17
  58. package/dist/test/run-tests.mock.js +0 -95
  59. package/dist/test/typescript-tests.mock.d.ts +0 -2
  60. package/dist/test/typescript-tests.mock.js +0 -1575
  61. package/dist/test/typescript.test.d.ts +0 -1
  62. package/dist/test/typescript.test.js +0 -10
@@ -1,88 +1,114 @@
1
+ import { arrayFirst, objectHasIn } from "ts-extras";
2
+ function hasDocChildProperty(input, key) {
3
+ return objectHasIn(input, key);
4
+ }
5
+ function logWalkVisit({ startDoc, parents, index, }) {
6
+ const parent = arrayFirst(parents);
7
+ const parentDoc = parent?.parent;
8
+ console.info({
9
+ firingCallbackFor: startDoc,
10
+ status: "Calling callback",
11
+ parent: parent
12
+ ? {
13
+ isArray: Array.isArray(parentDoc),
14
+ type: parentDoc && objectHasIn(parentDoc, "type")
15
+ ? parentDoc.type
16
+ : typeof parentDoc,
17
+ }
18
+ : undefined,
19
+ index,
20
+ });
21
+ }
22
+ function walkArrayChildren({ arrayDoc, debug, visitDoc, parents, }) {
23
+ if (debug) {
24
+ console.info("walking array children");
25
+ }
26
+ // Once a child returns false, abort walking this array.
27
+ arrayDoc.every((innerDoc, childIndex) => walkDoc({
28
+ startDoc: innerDoc,
29
+ debug,
30
+ callback: visitDoc,
31
+ parents: [
32
+ {
33
+ parent: arrayDoc,
34
+ childIndexInThisParent: childIndex,
35
+ },
36
+ ...parents,
37
+ ],
38
+ index: childIndex,
39
+ }));
40
+ }
41
+ function walkDocChildProperty({ startDoc, property, debug, visitDoc, parents, }) {
42
+ const childDoc = startDoc[property];
43
+ if (childDoc == undefined) {
44
+ return true;
45
+ }
46
+ if (debug) {
47
+ console.info(`walking ${property} property`);
48
+ }
49
+ return walkDoc({
50
+ startDoc: childDoc,
51
+ debug,
52
+ callback: visitDoc,
53
+ parents: [
54
+ {
55
+ parent: startDoc,
56
+ childIndexInThisParent: undefined,
57
+ },
58
+ ...parents,
59
+ ],
60
+ index: undefined,
61
+ });
62
+ }
1
63
  /**
64
+ * Walk a Prettier doc tree from the given starting node.
65
+ *
2
66
  * @returns Boolean true means keep walking children and siblings, false means
3
67
  * stop walking children and siblings. Returning false does not stop walking
4
68
  * of aunts/uncles or ancestors.
5
69
  */
6
- export function walkDoc({ startDoc, debug, callback, parents = [], index, }) {
70
+ export function walkDoc({ startDoc, debug, callback: visitDoc, parents = [], index, }) {
7
71
  if (!startDoc) {
8
72
  return true;
9
73
  }
10
74
  if (debug) {
11
- const parent = parents[0];
12
- console.info({
13
- firingCallbackFor: startDoc,
14
- status: "Calling callback",
15
- parent: parent
16
- ? {
17
- isArray: Array.isArray(parent),
18
- type: parent?.type ?? typeof parent,
19
- }
20
- : undefined,
75
+ logWalkVisit({
76
+ startDoc,
77
+ parents,
21
78
  index,
22
79
  });
23
80
  }
24
- if (!callback(startDoc, parents, index)) {
25
- // if the callback returns something falsy, don't try to walk its children
81
+ if (!visitDoc(startDoc, parents, index)) {
82
+ // If the callback returns something falsy, don't try to walk its children
26
83
  return false;
27
84
  }
28
- else if (typeof startDoc === "string") {
85
+ if (typeof startDoc === "string") {
29
86
  return true;
30
87
  }
31
- else if (Array.isArray(startDoc)) {
32
- if (debug) {
33
- console.info("walking array children");
34
- }
35
- // one a child returns false, abort walking this array
36
- startDoc.every((innerDoc, index) => {
37
- return walkDoc({
38
- startDoc: innerDoc,
39
- debug,
40
- callback,
41
- parents: [
42
- {
43
- parent: startDoc,
44
- childIndexInThisParent: index,
45
- },
46
- ...parents,
47
- ],
48
- index,
49
- });
88
+ if (Array.isArray(startDoc)) {
89
+ walkArrayChildren({
90
+ arrayDoc: startDoc,
91
+ debug,
92
+ visitDoc,
93
+ parents,
50
94
  });
51
95
  }
52
- else if ("contents" in startDoc) {
53
- if (debug) {
54
- console.info("walking contents property");
55
- }
56
- return walkDoc({
57
- startDoc: startDoc.contents,
96
+ if (hasDocChildProperty(startDoc, "contents")) {
97
+ return walkDocChildProperty({
98
+ startDoc,
99
+ property: "contents",
58
100
  debug,
59
- callback,
60
- parents: [
61
- {
62
- parent: startDoc,
63
- childIndexInThisParent: undefined,
64
- },
65
- ...parents,
66
- ],
67
- index: undefined,
101
+ parents,
102
+ visitDoc,
68
103
  });
69
104
  }
70
- else if ("parts" in startDoc) {
71
- if (debug) {
72
- console.info("walking parts property");
73
- }
74
- return walkDoc({
75
- startDoc: startDoc.parts,
105
+ if (hasDocChildProperty(startDoc, "parts")) {
106
+ return walkDocChildProperty({
107
+ startDoc,
108
+ property: "parts",
76
109
  debug,
77
- callback,
78
- parents: [
79
- {
80
- parent: startDoc,
81
- childIndexInThisParent: undefined,
82
- },
83
- ...parents,
84
- ],
85
- index: undefined,
110
+ parents,
111
+ visitDoc,
86
112
  });
87
113
  }
88
114
  return true;
@@ -1,7 +1,5 @@
1
1
  import type { Node } from "estree";
2
- type LineNumberDetails<T> = {
3
- [lineNumber: string]: T;
4
- };
2
+ type LineNumberDetails<T> = Record<string, T>;
5
3
  export type LineCounts = LineNumberDetails<number[]>;
6
4
  export type WrapThresholds = LineNumberDetails<number>;
7
5
  export type CommentTriggerWithEnding<T> = {
@@ -10,16 +8,16 @@ export type CommentTriggerWithEnding<T> = {
10
8
  lineEnd: number;
11
9
  };
12
10
  };
13
- export type CommentTriggers = {
11
+ export interface CommentTriggers {
14
12
  nextLineCounts: LineCounts;
15
- setLineCounts: CommentTriggerWithEnding<LineCounts>;
16
13
  nextWrapThresholds: WrapThresholds;
14
+ setLineCounts: CommentTriggerWithEnding<LineCounts>;
17
15
  setWrapThresholds: CommentTriggerWithEnding<WrapThresholds>;
18
- };
16
+ }
19
17
  export declare function getCommentTriggers(key: Node, debug: boolean): CommentTriggers;
20
18
  export declare function parseNextLineCounts({ input, nextOnly, debug, }: Readonly<{
19
+ debug: boolean;
21
20
  input: string;
22
21
  nextOnly: boolean;
23
- debug: boolean;
24
22
  }>): number[];
25
23
  export {};
@@ -1,10 +1,11 @@
1
1
  import { check } from "@augment-vir/assert";
2
2
  import { getObjectTypedKeys } from "@augment-vir/common";
3
- import { nextLinePatternComment, nextWrapThresholdComment, resetComment, setLinePatternComment, setWrapThresholdComment, untilNextLinePatternCommentRegExp, untilNextWrapThresholdCommentRegExp, untilSetLinePatternCommentRegExp, untilSetWrapThresholdCommentRegExp, } from "../options.js";
3
+ import { arrayFirst, arrayJoin, isEmpty, safeCastTo, setHas, stringSplit, } from "ts-extras";
4
+ import { nextLinePatternComment, nextWrapThresholdComment, resetComment, setLinePatternComment, setWrapThresholdComment, stripTextUntilCommentTrigger, } from "../options.js";
4
5
  import { extractComments } from "./comments.js";
5
6
  import { isArrayLikeNode } from "./supported-node-types.js";
6
7
  const mappedCommentTriggers = new WeakMap();
7
- const ignoredAstChildKeys = [
8
+ const ignoredAstChildKeys = new Set([
8
9
  "comments",
9
10
  "leadingComments",
10
11
  "loc",
@@ -13,14 +14,14 @@ const ignoredAstChildKeys = [
13
14
  "tokens",
14
15
  "trailingComments",
15
16
  "value",
16
- ];
17
- const descendantBoundaryTypes = [
17
+ ]);
18
+ const descendantBoundaryTypes = new Set([
18
19
  "ArrowFunctionExpression",
19
20
  "ClassDeclaration",
20
21
  "ClassExpression",
21
22
  "FunctionDeclaration",
22
23
  "FunctionExpression",
23
- ];
24
+ ]);
24
25
  export function getCommentTriggers(key, debug) {
25
26
  const alreadyExisting = mappedCommentTriggers.get(key);
26
27
  if (!alreadyExisting) {
@@ -29,7 +30,7 @@ export function getCommentTriggers(key, debug) {
29
30
  return alreadyExisting;
30
31
  }
31
32
  function setCommentTriggers(rootNode, debug) {
32
- // parse comments only on the root node so it only happens once
33
+ // Parse comments only on the root node so it only happens once
33
34
  const comments = extractComments(rootNode);
34
35
  if (debug) {
35
36
  console.info({
@@ -43,8 +44,9 @@ function setCommentTriggers(rootNode, debug) {
43
44
  setWrapThresholds: {},
44
45
  resets: [],
45
46
  };
46
- const internalCommentTriggers = comments.reduce((accum, currentComment) => {
47
- const commentText = currentComment.value?.replace(/\n/g, " ");
47
+ const internalCommentTriggers = starterTriggers;
48
+ for (const currentComment of comments) {
49
+ const commentText = safeCastTo(currentComment.value)?.replaceAll("\n", " ");
48
50
  if (!currentComment.loc) {
49
51
  throw new Error(`Cannot read line location for comment ${currentComment.value}`);
50
52
  }
@@ -53,40 +55,38 @@ function setCommentTriggers(rootNode, debug) {
53
55
  nextOnly: true,
54
56
  debug,
55
57
  });
56
- if (nextLineCounts.length) {
57
- accum.nextLineCounts[currentComment.loc.end.line] =
58
- nextLineCounts;
58
+ if (nextLineCounts.length > 0) {
59
+ internalCommentTriggers.nextLineCounts[currentComment.loc.end.line] = nextLineCounts;
59
60
  }
60
61
  const nextWrapThreshold = getWrapThreshold(commentText, true);
61
62
  if (nextWrapThreshold != undefined) {
62
- accum.nextWrapThresholds[currentComment.loc.end.line] =
63
- nextWrapThreshold;
63
+ internalCommentTriggers.nextWrapThresholds[currentComment.loc.end.line] = nextWrapThreshold;
64
64
  }
65
65
  const setLineCounts = getLineCounts({
66
66
  commentText,
67
67
  nextOnly: false,
68
68
  debug,
69
69
  });
70
- if (setLineCounts.length) {
71
- accum.setLineCounts[currentComment.loc.end.line] = {
72
- data: setLineCounts,
73
- lineEnd: Infinity,
74
- };
70
+ if (setLineCounts.length > 0) {
71
+ internalCommentTriggers.setLineCounts[currentComment.loc.end.line] =
72
+ {
73
+ data: setLineCounts,
74
+ lineEnd: Infinity,
75
+ };
75
76
  }
76
77
  const setWrapThreshold = getWrapThreshold(commentText, false);
77
78
  if (setWrapThreshold != undefined) {
78
- accum.setWrapThresholds[currentComment.loc.end.line] = {
79
+ internalCommentTriggers.setWrapThresholds[currentComment.loc.end.line] = {
79
80
  data: setWrapThreshold,
80
81
  lineEnd: Infinity,
81
82
  };
82
83
  }
83
- const resetComment = isResetComment(commentText);
84
- if (resetComment) {
85
- accum.resets.push(currentComment.loc.end.line);
84
+ const shouldReset = isResetComment(commentText);
85
+ if (shouldReset) {
86
+ internalCommentTriggers.resets.push(currentComment.loc.end.line);
86
87
  }
87
- return accum;
88
- }, starterTriggers);
89
- internalCommentTriggers.resets.sort();
88
+ }
89
+ internalCommentTriggers.resets.sort((firstLine, secondLine) => firstLine - secondLine);
90
90
  setResets(internalCommentTriggers);
91
91
  mapNextCommentTriggers({
92
92
  internalCommentTriggers,
@@ -95,8 +95,8 @@ function setCommentTriggers(rootNode, debug) {
95
95
  const commentTriggers = {
96
96
  ...internalCommentTriggers,
97
97
  };
98
- delete commentTriggers.resets;
99
- // save to a map so we don't have to recalculate these every time
98
+ delete safeCastTo(commentTriggers).resets;
99
+ // Save to a map so we don't have to recalculate these every time
100
100
  mappedCommentTriggers.set(rootNode, commentTriggers);
101
101
  return commentTriggers;
102
102
  }
@@ -111,52 +111,41 @@ function mapNextCommentTriggers({ internalCommentTriggers, rootNode, }) {
111
111
  });
112
112
  }
113
113
  function mapNextLineTriggers({ rootNode, triggers, }) {
114
- return getObjectTypedKeys(triggers).reduce((mappedTriggers, triggerLineNumber) => {
114
+ const mappedTriggers = {};
115
+ for (const triggerLineNumber of getObjectTypedKeys(triggers)) {
115
116
  const trigger = triggers[triggerLineNumber];
116
117
  const targetLineNumber = findArrayLikeTargetLine({
117
118
  nextLineNumber: Number(triggerLineNumber) + 1,
118
119
  rootNode,
119
120
  });
120
- if (targetLineNumber == undefined || trigger == undefined) {
121
- return mappedTriggers;
121
+ if (targetLineNumber != undefined && trigger != undefined) {
122
+ mappedTriggers[targetLineNumber] = trigger;
122
123
  }
123
- return {
124
- ...mappedTriggers,
125
- [targetLineNumber]: trigger,
126
- };
127
- }, {});
124
+ }
125
+ return mappedTriggers;
128
126
  }
129
127
  function findArrayLikeTargetLine({ rootNode, nextLineNumber, }) {
130
- return findAstNodesStartingOnLine({
128
+ const descendantLines = findAstNodesStartingOnLine({
131
129
  lineNumber: nextLineNumber,
132
130
  rootNode,
133
- })
134
- .flatMap((node) => {
135
- return findArrayLikeDescendantLines({
136
- rootNode: node,
137
- });
138
- })
139
- .toSorted((firstLine, secondLine) => {
140
- return firstLine - secondLine;
141
- })[0];
131
+ }).flatMap((node) => findArrayLikeDescendantLines({
132
+ rootNode: node,
133
+ }));
134
+ return descendantLines.length > 0
135
+ ? Math.min(...descendantLines)
136
+ : undefined;
142
137
  }
143
138
  function findAstNodesStartingOnLine({ rootNode, lineNumber, }) {
144
139
  return collectAstNodes({
145
140
  input: rootNode,
146
- shouldInclude: (node) => {
147
- return node.loc?.start.line === lineNumber;
148
- },
141
+ shouldInclude: (node) => node.loc?.start.line === lineNumber,
149
142
  });
150
143
  }
151
144
  function findArrayLikeDescendantLines({ rootNode, }) {
152
145
  return collectAstNodes({
153
146
  input: rootNode,
154
- shouldInclude: (node) => {
155
- return isArrayLikeNode(node) && !!node.loc;
156
- },
157
- shouldWalkChildren: (node, isRootNode) => {
158
- return isRootNode || !descendantBoundaryTypes.includes(node.type);
159
- },
147
+ shouldInclude: (node) => isArrayLikeNode(node) && Boolean(node.loc),
148
+ shouldWalkChildren: (node, isRootNode) => isRootNode || !setHas(descendantBoundaryTypes, node.type),
160
149
  }).flatMap((node) => {
161
150
  if (!node.loc) {
162
151
  return [];
@@ -166,20 +155,15 @@ function findArrayLikeDescendantLines({ rootNode, }) {
166
155
  }
167
156
  function collectAstNodes({ input, shouldInclude, shouldWalkChildren = () => true, seenInputs = new WeakSet(), isRootNode = true, }) {
168
157
  if (check.isArray(input)) {
169
- return input.flatMap((child) => {
170
- return collectAstNodes({
171
- input: child,
172
- isRootNode: false,
173
- seenInputs,
174
- shouldInclude,
175
- shouldWalkChildren,
176
- });
177
- });
178
- }
179
- else if (!check.isObject(input)) {
180
- return [];
158
+ return input.flatMap((child) => collectAstNodes({
159
+ input: child,
160
+ isRootNode: false,
161
+ seenInputs,
162
+ shouldInclude,
163
+ shouldWalkChildren,
164
+ }));
181
165
  }
182
- else if (seenInputs.has(input)) {
166
+ if (!check.isObject(input) || seenInputs.has(input)) {
183
167
  return [];
184
168
  }
185
169
  seenInputs.add(input);
@@ -189,7 +173,7 @@ function collectAstNodes({ input, shouldInclude, shouldWalkChildren = () => true
189
173
  const matchingNode = shouldInclude(input, isRootNode) ? [input] : [];
190
174
  const childNodes = shouldWalkChildren(input, isRootNode)
191
175
  ? getObjectTypedKeys(input).flatMap((nodeKey) => {
192
- if (ignoredAstChildKeys.includes(String(nodeKey))) {
176
+ if (setHas(ignoredAstChildKeys, String(nodeKey))) {
193
177
  return [];
194
178
  }
195
179
  return collectAstNodes({
@@ -206,109 +190,97 @@ function collectAstNodes({ input, shouldInclude, shouldWalkChildren = () => true
206
190
  function isAstNode(input) {
207
191
  return check.isObject(input) && check.isString(input.type);
208
192
  }
193
+ function isIntegerString(entry) {
194
+ if (entry.length === 0) {
195
+ return false;
196
+ }
197
+ for (const character of entry) {
198
+ if (character < "0" || character > "9") {
199
+ return false;
200
+ }
201
+ }
202
+ return true;
203
+ }
209
204
  function setResets(internalCommentTriggers) {
210
- if (!internalCommentTriggers.resets.length) {
205
+ if (isEmpty(internalCommentTriggers.resets)) {
211
206
  return;
212
207
  }
213
208
  const setLineCountLineNumbers = getObjectTypedKeys(internalCommentTriggers.setLineCounts);
214
- if (setLineCountLineNumbers.length) {
215
- setLineCountLineNumbers.forEach((lineNumber) => {
209
+ if (setLineCountLineNumbers.length > 0) {
210
+ for (const lineNumber of setLineCountLineNumbers) {
216
211
  const currentLineNumberStats = internalCommentTriggers.setLineCounts[lineNumber];
217
212
  if (!currentLineNumberStats) {
218
213
  throw new Error(`Line number stats were undefined for "${lineNumber}" in "${JSON.stringify(internalCommentTriggers.setLineCounts)}"`);
219
214
  }
220
- const endLineNumber = internalCommentTriggers.resets.find((resetLineNumber) => {
221
- return Number(lineNumber) < resetLineNumber;
222
- }) ?? currentLineNumberStats.lineEnd;
215
+ const endLineNumber = internalCommentTriggers.resets.find((resetLineNumber) => Number(lineNumber) < resetLineNumber) ?? currentLineNumberStats.lineEnd;
223
216
  currentLineNumberStats.lineEnd = endLineNumber;
224
- });
217
+ }
225
218
  }
226
219
  }
227
220
  function getWrapThreshold(commentText, nextOnly) {
228
221
  const searchText = nextOnly
229
222
  ? nextWrapThresholdComment
230
223
  : setWrapThresholdComment;
231
- const searchRegExp = nextOnly
232
- ? untilNextWrapThresholdCommentRegExp
233
- : untilSetWrapThresholdCommentRegExp;
234
224
  if (commentText?.toLowerCase().includes(searchText)) {
235
- const thresholdValue = Number(commentText.toLowerCase().replace(searchRegExp, "").trim());
236
- if (isNaN(thresholdValue)) {
225
+ const thresholdValue = Number(stripTextUntilCommentTrigger(commentText.toLowerCase(), searchText).trim());
226
+ if (Number.isNaN(thresholdValue)) {
237
227
  return undefined;
238
228
  }
239
- else {
240
- return thresholdValue;
241
- }
242
- }
243
- else {
244
- return undefined;
229
+ return thresholdValue;
245
230
  }
231
+ return undefined;
246
232
  }
247
233
  export function parseNextLineCounts({ input, nextOnly, debug, }) {
248
234
  if (!input) {
249
235
  return [];
250
236
  }
251
- const searchRegExp = nextOnly
252
- ? untilNextLinePatternCommentRegExp
253
- : untilSetLinePatternCommentRegExp;
254
- const split = input
255
- .toLowerCase()
256
- .replace(searchRegExp, "")
257
- .replace(/,/g, "")
258
- .split(" ")
259
- .filter((entry) => !!entry);
260
- const firstSplit = split[0];
237
+ const searchText = nextOnly
238
+ ? nextLinePatternComment
239
+ : setLinePatternComment;
240
+ let split = stringSplit(stripTextUntilCommentTrigger(input.toLowerCase(), searchText).replaceAll(",", ""), " ").filter(Boolean);
241
+ const firstSplit = arrayFirst(split);
261
242
  if (firstSplit === "[") {
262
- split.splice(0, 1);
243
+ split = split.slice(1);
263
244
  }
264
245
  else if (firstSplit?.startsWith("[")) {
265
- split[0] = firstSplit.replace(/^\[/, "");
246
+ split[0] = firstSplit.slice(1);
266
247
  }
267
- const lastSplitIndex = split.length - 1;
268
- const lastSplit = split[lastSplitIndex];
248
+ const [lastSplit] = split.toReversed();
269
249
  if (lastSplit === "]") {
270
- split.splice(split.length - 1, 1);
250
+ split = split.slice(0, -1);
271
251
  }
272
252
  else if (lastSplit?.endsWith("]")) {
273
- split[lastSplitIndex] = lastSplit.replace(/\]$/, "");
253
+ const lastSplitIndex = split.length - 1;
254
+ split[lastSplitIndex] = lastSplit.slice(0, -1);
274
255
  }
275
- const numbers = split.map((entry) => entry && !!entry.trim().match(/^\d+$/) ? Number(entry.trim()) : NaN);
256
+ const numbers = split.map((entry) => isIntegerString(entry.trim()) ? Number(entry.trim()) : Number.NaN);
276
257
  const invalidNumbers = numbers
277
- .map((entry, index) => {
278
- return {
279
- index,
280
- entry,
281
- original: split[index],
282
- };
283
- })
284
- .filter((entry) => {
285
- return isNaN(entry.entry);
286
- });
287
- if (invalidNumbers.length) {
258
+ .map((entry, index) => ({
259
+ index,
260
+ entry,
261
+ original: split[index],
262
+ }))
263
+ .filter((entry) => Number.isNaN(entry.entry));
264
+ if (invalidNumbers.length > 0) {
288
265
  if (debug) {
289
- console.error(invalidNumbers.map((entry) => {
290
- return {
291
- index: entry.index,
292
- original: entry.original,
293
- parsed: entry,
294
- split,
295
- input,
296
- numbers,
297
- trim: entry.original?.trim(),
298
- match: entry.original?.trim().match(/^\d+$/),
299
- matched: !!entry.original?.trim().match(/^\d+$/),
300
- };
301
- }));
266
+ console.error(invalidNumbers.map((entry) => ({
267
+ index: entry.index,
268
+ original: entry.original,
269
+ parsed: entry,
270
+ split,
271
+ input,
272
+ numbers,
273
+ trim: entry.original?.trim(),
274
+ matched: isIntegerString(entry.original?.trim() ?? ""),
275
+ })));
302
276
  }
303
- console.error(`Invalid number(s) for elements per line option/comment: ${invalidNumbers
304
- .map((entry) => entry.original)
305
- .join()}`);
277
+ console.error(`Invalid number(s) for elements per line option/comment: ${arrayJoin(invalidNumbers.map((entry) => entry.original), ",")}`);
306
278
  return [];
307
279
  }
308
280
  return numbers;
309
281
  }
310
282
  function isResetComment(commentText) {
311
- return !!commentText?.toLowerCase().includes(resetComment);
283
+ return Boolean(commentText?.toLowerCase().includes(resetComment));
312
284
  }
313
285
  function getLineCounts({ commentText, nextOnly, debug, }) {
314
286
  const searchText = nextOnly
@@ -321,7 +293,5 @@ function getLineCounts({ commentText, nextOnly, debug, }) {
321
293
  debug,
322
294
  });
323
295
  }
324
- else {
325
- return [];
326
- }
296
+ return [];
327
297
  }
@@ -1,2 +1,2 @@
1
1
  import type { Comment } from "estree";
2
- export declare function extractComments(node: any): Comment[];
2
+ export declare function extractComments(node: unknown): Comment[];
@@ -1,17 +1,16 @@
1
- const ignoreTheseKeys = ["tokens"];
2
- const ignoreTheseChildTypes = ["string", "number"];
1
+ import { arrayIncludes, objectEntries, objectHasIn } from "ts-extras";
3
2
  const commentTypes = [
4
- "Line",
5
3
  "Block",
6
4
  "CommentBlock",
7
5
  "CommentLine",
6
+ "Line",
8
7
  ];
9
8
  function isMaybeComment(input) {
10
- return !(!input ||
11
- typeof input !== "object" ||
12
- !("type" in input) ||
13
- !commentTypes.includes(input.type) ||
14
- !("value" in input));
9
+ return Boolean(input &&
10
+ typeof input === "object" &&
11
+ objectHasIn(input, "type") &&
12
+ arrayIncludes(commentTypes, input.type) &&
13
+ objectHasIn(input, "value"));
15
14
  }
16
15
  export function extractComments(node) {
17
16
  if (!node || typeof node !== "object") {
@@ -21,14 +20,14 @@ export function extractComments(node) {
21
20
  if (Array.isArray(node)) {
22
21
  comments.push(...node.filter(isMaybeComment));
23
22
  }
24
- Object.keys(node).forEach((nodeKey) => {
25
- if (!ignoreTheseKeys.includes(nodeKey)) {
26
- const nodeChild = node[nodeKey];
27
- if (!ignoreTheseChildTypes.includes(typeof nodeChild)) {
28
- comments.push(...extractComments(nodeChild));
29
- }
23
+ for (const [nodeKey, nodeChild] of objectEntries(node)) {
24
+ if (nodeKey === "tokens") {
25
+ continue;
30
26
  }
31
- });
32
- // this might duplicate comments but our later code doesn't care
27
+ if (typeof nodeChild !== "number" && typeof nodeChild !== "string") {
28
+ comments.push(...extractComments(nodeChild));
29
+ }
30
+ }
31
+ // This might duplicate comments but our later code doesn't care
33
32
  return comments;
34
33
  }