pickier 0.1.33 → 0.1.35

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/bin/cli.js CHANGED
@@ -48,6 +48,37 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
48
48
  var __require = import.meta.require;
49
49
 
50
50
  // src/format.ts
51
+ function isHangingControlLine(code) {
52
+ const m = RE_CONTROL_OPEN.exec(code);
53
+ if (!m)
54
+ return /^(?:else|do)\s*$/.test(code);
55
+ let depth = 0;
56
+ let inStr = null;
57
+ for (let i = m[0].length - 1;i < code.length; i++) {
58
+ const ch = code[i];
59
+ if (inStr) {
60
+ if (ch === "\\") {
61
+ i++;
62
+ continue;
63
+ }
64
+ if (ch === inStr)
65
+ inStr = null;
66
+ continue;
67
+ }
68
+ if (ch === "'" || ch === '"' || ch === "`") {
69
+ inStr = ch;
70
+ continue;
71
+ }
72
+ if (ch === "(") {
73
+ depth++;
74
+ } else if (ch === ")") {
75
+ depth--;
76
+ if (depth === 0)
77
+ return code.slice(i + 1).trim().length === 0;
78
+ }
79
+ }
80
+ return false;
81
+ }
51
82
  function getFileExt(filePath) {
52
83
  const idx = filePath.lastIndexOf(".");
53
84
  return idx >= 0 ? filePath.slice(idx) : "";
@@ -198,6 +229,25 @@ function fixQuotesLine(line, preferred) {
198
229
  while (i < line.length) {
199
230
  const ch = line[i];
200
231
  if (inString === 0) {
232
+ if (ch === "/") {
233
+ const nxt = line[i + 1];
234
+ if (nxt === "/")
235
+ break;
236
+ if (nxt === "*") {
237
+ const end = line.indexOf("*/", i + 2);
238
+ i = end === -1 ? line.length : end + 2;
239
+ continue;
240
+ }
241
+ if (isRegexStart(line, i)) {
242
+ const end = scanRegexEnd(line, i);
243
+ if (end !== -1) {
244
+ i = end;
245
+ continue;
246
+ }
247
+ }
248
+ i++;
249
+ continue;
250
+ }
201
251
  if (ch === '"') {
202
252
  inString = 2;
203
253
  stringStart = i;
@@ -265,6 +315,8 @@ function normalizeSpacingLine(line) {
265
315
  const c = line[firstNonSpace];
266
316
  if (c === "/" && (line[firstNonSpace + 1] === "/" || line[firstNonSpace + 1] === "*"))
267
317
  return line;
318
+ if (c === "*")
319
+ return line;
268
320
  }
269
321
  let hasSpacingChar = false;
270
322
  for (let j = firstNonSpace;j < line.length; j++) {
@@ -377,6 +429,49 @@ function advanceTemplateState(line, stack) {
377
429
  }
378
430
  return -1;
379
431
  }
432
+ function blockCommentStateAfter(line, startsIn) {
433
+ let inBlock = startsIn;
434
+ let inStr = null;
435
+ let i = 0;
436
+ while (i < line.length) {
437
+ const ch = line[i];
438
+ if (inBlock) {
439
+ if (ch === "*" && line[i + 1] === "/") {
440
+ inBlock = false;
441
+ i += 2;
442
+ continue;
443
+ }
444
+ i++;
445
+ continue;
446
+ }
447
+ if (inStr) {
448
+ if (ch === "\\") {
449
+ i += 2;
450
+ continue;
451
+ }
452
+ if (ch === inStr)
453
+ inStr = null;
454
+ i++;
455
+ continue;
456
+ }
457
+ if (ch === "'" || ch === '"' || ch === "`") {
458
+ inStr = ch;
459
+ i++;
460
+ continue;
461
+ }
462
+ if (ch === "/") {
463
+ if (line[i + 1] === "/")
464
+ break;
465
+ if (line[i + 1] === "*") {
466
+ inBlock = true;
467
+ i += 2;
468
+ continue;
469
+ }
470
+ }
471
+ i++;
472
+ }
473
+ return inBlock;
474
+ }
380
475
  function processCodeLinesFused(content, cfg) {
381
476
  const lines = content.split(`
382
477
  `);
@@ -385,9 +480,16 @@ function processCodeLinesFused(content, cfg) {
385
480
  const preferred = cfg.format.quotes;
386
481
  const doSemiRemoval = cfg.format.semi === true;
387
482
  let indentLevel = 0;
483
+ let hangDepth = 0;
484
+ let inBlockComment = false;
388
485
  const tmplStack = [];
389
486
  for (let idx = 0;idx < len; idx++) {
390
487
  let line = lines[idx];
488
+ if (inBlockComment) {
489
+ inBlockComment = blockCommentStateAfter(line, true);
490
+ result[idx] = line;
491
+ continue;
492
+ }
391
493
  const protectedLine = inTemplateText(tmplStack);
392
494
  let splitIdx = -1;
393
495
  if (tmplStack.length > 0 || line.indexOf("`") !== -1)
@@ -396,6 +498,8 @@ function processCodeLinesFused(content, cfg) {
396
498
  result[idx] = line;
397
499
  continue;
398
500
  }
501
+ if (splitIdx < 0 && tmplStack.length === 0)
502
+ inBlockComment = blockCommentStateAfter(line, false);
399
503
  let tmplTail = "";
400
504
  let prefixEndedWithSpace = false;
401
505
  if (splitIdx >= 0) {
@@ -419,9 +523,15 @@ function processCodeLinesFused(content, cfg) {
419
523
  const trimmed = line.slice(wsEnd).trimEnd();
420
524
  if (RE_CLOSING_BRACE.test(trimmed))
421
525
  indentLevel = Math.max(0, indentLevel - 1);
422
- line = makeIndent(indentLevel, cfg) + trimmed;
423
- if (RE_OPENING_BRACE.test(trimmed))
526
+ const continuationBump = RE_CONTINUATION_LINE.test(trimmed) ? 1 : 0;
527
+ line = makeIndent(indentLevel + hangDepth + continuationBump, cfg) + trimmed;
528
+ if (RE_OPENING_BRACE.test(trimmed)) {
424
529
  indentLevel += 1;
530
+ hangDepth = 0;
531
+ } else if (!trimmed.startsWith("//") && !trimmed.startsWith("*") && !trimmed.startsWith("/*")) {
532
+ const code = trimmed.replace(RE_TRAILING_LINE_COMMENT, "");
533
+ hangDepth = isHangingControlLine(code) ? hangDepth + 1 : 0;
534
+ }
425
535
  line = normalizeSpacingLine(line);
426
536
  if (doSemiRemoval) {
427
537
  if (!RE_FOR_LOOP.test(line)) {
@@ -614,8 +724,87 @@ function hasIndentIssue(leading, indentSize, indentStyle = "spaces", lineContent
614
724
  }
615
725
  return spaces % indentSize !== 0;
616
726
  }
727
+ function skipTemplate(input, start) {
728
+ let i = start + 1;
729
+ while (i < input.length) {
730
+ const c = input[i];
731
+ if (c === "\\") {
732
+ i += 2;
733
+ continue;
734
+ }
735
+ if (c === "`")
736
+ return i + 1;
737
+ if (c === "$" && input[i + 1] === "{") {
738
+ i += 2;
739
+ let depth = 1;
740
+ while (i < input.length && depth > 0) {
741
+ const d = input[i];
742
+ if (d === "\\") {
743
+ i += 2;
744
+ continue;
745
+ }
746
+ if (d === "`") {
747
+ i = skipTemplate(input, i);
748
+ continue;
749
+ }
750
+ if (d === "'" || d === '"') {
751
+ i = skipQuoted(input, i, d);
752
+ continue;
753
+ }
754
+ if (d === "{")
755
+ depth++;
756
+ else if (d === "}")
757
+ depth--;
758
+ i++;
759
+ }
760
+ continue;
761
+ }
762
+ i++;
763
+ }
764
+ return i;
765
+ }
766
+ function isRegexStart(input, slashIdx) {
767
+ let j = slashIdx - 1;
768
+ while (j >= 0 && (input[j] === " " || input[j] === "\t"))
769
+ j--;
770
+ if (j < 0)
771
+ return true;
772
+ const prev = input[j];
773
+ if ("(,=:[!&|?;{}<>+-*%^~".includes(prev))
774
+ return true;
775
+ if (/[\w$]/.test(prev)) {
776
+ let k = j;
777
+ while (k >= 0 && /[\w$]/.test(input[k]))
778
+ k--;
779
+ return REGEX_PRECEDING_KEYWORDS.has(input.slice(k + 1, j + 1));
780
+ }
781
+ return false;
782
+ }
783
+ function scanRegexEnd(input, start) {
784
+ let i = start + 1;
785
+ let inClass = false;
786
+ while (i < input.length) {
787
+ const c = input[i];
788
+ if (c === "\\") {
789
+ i += 2;
790
+ continue;
791
+ }
792
+ if (c === "[") {
793
+ inClass = true;
794
+ } else if (c === "]") {
795
+ inClass = false;
796
+ } else if (c === "/" && !inClass) {
797
+ i++;
798
+ while (i < input.length && /[a-z]/i.test(input[i]))
799
+ i++;
800
+ return i;
801
+ }
802
+ i++;
803
+ }
804
+ return -1;
805
+ }
617
806
  function maskStrings(input) {
618
- if (!input.includes("'") && !input.includes('"') && !input.includes("`"))
807
+ if (!input.includes("'") && !input.includes('"') && !input.includes("`") && !input.includes("/"))
619
808
  return { text: input, strings: [] };
620
809
  const strings = [];
621
810
  const parts = [];
@@ -623,22 +812,62 @@ function maskStrings(input) {
623
812
  let segStart = 0;
624
813
  while (i < input.length) {
625
814
  const ch = input[i];
815
+ if (ch === "/") {
816
+ const next = input[i + 1];
817
+ if (next === "/") {
818
+ if (i > segStart)
819
+ parts.push(input.slice(segStart, i));
820
+ strings.push(input.slice(i));
821
+ parts.push(`@@S${strings.length - 1}@@`);
822
+ segStart = input.length;
823
+ break;
824
+ }
825
+ if (next === "*") {
826
+ const end = input.indexOf("*/", i + 2);
827
+ const stop = end === -1 ? input.length : end + 2;
828
+ if (i > segStart)
829
+ parts.push(input.slice(segStart, i));
830
+ strings.push(input.slice(i, stop));
831
+ parts.push(`@@S${strings.length - 1}@@`);
832
+ i = stop;
833
+ segStart = i;
834
+ continue;
835
+ }
836
+ if (isRegexStart(input, i)) {
837
+ const end = scanRegexEnd(input, i);
838
+ if (end !== -1) {
839
+ if (i > segStart)
840
+ parts.push(input.slice(segStart, i));
841
+ strings.push(input.slice(i, end));
842
+ parts.push(`@@S${strings.length - 1}@@`);
843
+ i = end;
844
+ segStart = i;
845
+ continue;
846
+ }
847
+ }
848
+ i++;
849
+ continue;
850
+ }
626
851
  if (ch === "'" || ch === '"' || ch === "`") {
627
852
  if (i > segStart)
628
853
  parts.push(input.slice(segStart, i));
629
854
  const start = i;
630
- const close = ch;
631
- i++;
632
- while (i < input.length) {
633
- if (input[i] === "\\") {
634
- i += 2;
635
- continue;
636
- }
637
- if (input[i] === close) {
855
+ if (ch === "`") {
856
+ i = skipTemplate(input, i);
857
+ } else {
858
+ const close = ch;
859
+ i++;
860
+ while (i < input.length) {
861
+ if (input[i] === "\\") {
862
+ i += 2;
863
+ continue;
864
+ }
865
+ if (input[i] === close) {
866
+ i++;
867
+ break;
868
+ }
638
869
  i++;
639
- break;
640
870
  }
641
- i++;
642
871
  }
643
872
  strings.push(input.slice(start, i));
644
873
  parts.push(`@@S${strings.length - 1}@@`);
@@ -674,24 +903,65 @@ function formatImports(source) {
674
903
  const lines = source.split(`
675
904
  `);
676
905
  const imports = [];
906
+ const preamble = [];
907
+ const interleaved = [];
677
908
  let idx = 0;
909
+ let lastEnd = 0;
910
+ let pendingStart = -1;
911
+ let sawImport = false;
678
912
  while (idx < lines.length) {
679
913
  const line = lines[idx];
680
- if (RE_BLANK_LINE.test(line) || RE_LINE_COMMENT.test(line) || RE_BLOCK_COMMENT.test(line)) {
914
+ if (RE_BLANK_LINE.test(line)) {
681
915
  idx++;
682
916
  continue;
683
917
  }
918
+ if (RE_LINE_COMMENT.test(line) || RE_BLOCK_COMMENT.test(line)) {
919
+ const start = idx;
920
+ if (RE_BLOCK_COMMENT.test(line)) {
921
+ while (idx < lines.length && !lines[idx].includes("*/"))
922
+ idx++;
923
+ idx++;
924
+ } else {
925
+ idx++;
926
+ }
927
+ if (!sawImport) {
928
+ for (let k = start;k < idx && k < lines.length; k++)
929
+ preamble.push(lines[k]);
930
+ lastEnd = idx;
931
+ } else if (pendingStart < 0) {
932
+ pendingStart = start;
933
+ }
934
+ continue;
935
+ }
684
936
  if (!RE_IMPORT_STMT.test(line))
685
937
  break;
686
- const stmt = line.trim();
938
+ let stmt = line.trim();
939
+ let stmtEnd = idx + 1;
940
+ while (!RE_IMPORT_COMPLETE.test(stmt) && stmtEnd < lines.length && stmtEnd - idx < 50) {
941
+ stmt += ` ${lines[stmtEnd].trim()}`;
942
+ stmtEnd++;
943
+ }
944
+ if (!RE_IMPORT_COMPLETE.test(stmt))
945
+ return source;
687
946
  const parsed = parseImportStatement(stmt);
688
- if (parsed)
689
- imports.push(parsed);
690
- idx++;
947
+ if (!parsed)
948
+ return source;
949
+ if (pendingStart >= 0) {
950
+ for (let k = pendingStart;k < idx; k++) {
951
+ if (!RE_BLANK_LINE.test(lines[k]))
952
+ interleaved.push(lines[k]);
953
+ }
954
+ pendingStart = -1;
955
+ }
956
+ imports.push(parsed);
957
+ idx = stmtEnd;
958
+ lastEnd = idx;
959
+ sawImport = true;
691
960
  }
692
961
  if (imports.length === 0)
693
962
  return source;
694
- const rest = lines.slice(idx).join(`
963
+ const restStart = pendingStart >= 0 ? pendingStart : lastEnd;
964
+ const rest = lines.slice(restStart).join(`
695
965
  `);
696
966
  const usedIdentifiers = collectIdentifierSet(rest);
697
967
  const used = (name) => usedIdentifiers.has(name);
@@ -812,17 +1082,29 @@ function formatImports(source) {
812
1082
  }
813
1083
  return a.source.localeCompare(b.source);
814
1084
  });
1085
+ const head = preamble.length > 0 ? `${preamble.join(`
1086
+ `)}
1087
+ ` : "";
815
1088
  if (entries.length === 0) {
816
- return rest.replace(/^\n+/, "");
1089
+ const restClean2 = rest.replace(/^\n+/, "");
1090
+ const kept = [...interleaved];
1091
+ if (head || kept.length > 0)
1092
+ return `${head}${kept.length > 0 ? `${kept.join(`
1093
+ `)}
1094
+ ` : ""}${restClean2}`;
1095
+ return restClean2;
817
1096
  }
818
1097
  const rendered = entries.map(renderImport).join(`
819
1098
  `);
820
- const sep = rest.length > 0 && !rest.startsWith(`
821
- `) ? `
1099
+ const mid = interleaved.length > 0 ? `
1100
+ ${interleaved.join(`
1101
+ `)}` : "";
1102
+ const restClean = rest.replace(/^\n+/, "");
1103
+ const sep = restClean.length > 0 ? `
822
1104
 
823
1105
  ` : `
824
1106
  `;
825
- return `${rendered}${sep}${rest.replace(/^\n+/, "")}`;
1107
+ return `${head}${rendered}${mid}${sep}${restClean}`;
826
1108
  }
827
1109
  function renderImport(imp) {
828
1110
  if (imp.kind === "side-effect")
@@ -1125,39 +1407,44 @@ function sortTsconfigContent(text) {
1125
1407
  }
1126
1408
  return JSON.stringify(outTop, null, 2);
1127
1409
  }
1128
- var CODE_EXTS, JSON_EXTS, YAML_EXTS, SHELL_EXTS, SHELL_SHEBANG_RE, RE_CLOSING_BRACE, RE_OPENING_BRACE, RE_FOR_LOOP, RE_EMPTY_SEMI, RE_DUP_SEMI, RE_SPACE_BEFORE_BRACE, RE_SPACE_AFTER_BRACE_KW, RE_COMMA_SPACE, RE_EQUALS_SPACE, RE_PLUS_OP, RE_MINUS_OP, RE_STAR_OP, RE_SLASH_OP, RE_SEMI_SPACE, RE_LT_OP, RE_GT_OP, RE_MULTI_SPACE, RE_BLANK_LINE, RE_LINE_COMMENT, RE_BLOCK_COMMENT, RE_IMPORT_STMT, RE_PACKAGE_JSON, RE_TSCONFIG_JSON, RE_TRAILING_WS, RE_LEADING_BLANKS, SPACING_CHARS;
1410
+ var CODE_EXTS, JSON_EXTS, YAML_EXTS, SHELL_EXTS, SHELL_SHEBANG_RE, RE_CLOSING_BRACE, RE_OPENING_BRACE, RE_TRAILING_LINE_COMMENT, RE_CONTROL_OPEN, RE_CONTINUATION_LINE, RE_FOR_LOOP, RE_EMPTY_SEMI, RE_DUP_SEMI, RE_SPACE_BEFORE_BRACE, RE_SPACE_AFTER_BRACE_KW, RE_COMMA_SPACE, RE_EQUALS_SPACE, RE_PLUS_OP, RE_MINUS_OP, RE_STAR_OP, RE_SLASH_OP, RE_SEMI_SPACE, RE_LT_OP, RE_GT_OP, RE_MULTI_SPACE, RE_BLANK_LINE, RE_LINE_COMMENT, RE_BLOCK_COMMENT, RE_IMPORT_STMT, RE_IMPORT_COMPLETE, RE_PACKAGE_JSON, RE_TSCONFIG_JSON, RE_TRAILING_WS, RE_LEADING_BLANKS, SPACING_CHARS, REGEX_PRECEDING_KEYWORDS;
1129
1411
  var init_format = __esm(() => {
1130
1412
  CODE_EXTS = new Set([".ts", ".js"]);
1131
1413
  JSON_EXTS = new Set([".json", ".jsonc"]);
1132
1414
  YAML_EXTS = new Set([".yaml", ".yml"]);
1133
1415
  SHELL_EXTS = new Set([".sh", ".bash", ".zsh", ".ksh", ".dash"]);
1134
1416
  SHELL_SHEBANG_RE = /^#!\s*(?:\/usr\/bin\/env\s+)?(?:ba|z|k|da)?sh\b/;
1135
- RE_CLOSING_BRACE = /^\}/;
1136
- RE_OPENING_BRACE = /\{\s*$/;
1417
+ RE_CLOSING_BRACE = /^[}\])]/;
1418
+ RE_OPENING_BRACE = /[{[(]\s*$/;
1419
+ RE_TRAILING_LINE_COMMENT = /\s*\/\/.*$/;
1420
+ RE_CONTROL_OPEN = /^(?:if|else\s+if|for|while)\s*\(/;
1421
+ RE_CONTINUATION_LINE = /^(?:\.[\w$[]|\?[\s.:]|:\s|&&|\|\|)/;
1137
1422
  RE_FOR_LOOP = /^\s*for\s*\(/;
1138
1423
  RE_EMPTY_SEMI = new RegExp("^\\s*" + ";" + "\\s*$");
1139
1424
  RE_DUP_SEMI = new RegExp(";" + "{2,}\\s*$");
1140
- RE_SPACE_BEFORE_BRACE = /(\S)\{/g;
1425
+ RE_SPACE_BEFORE_BRACE = /([\w)])\{/g;
1141
1426
  RE_SPACE_AFTER_BRACE_KW = /\{(return|if|for|while|switch|const|let|var|function)\b/g;
1142
1427
  RE_COMMA_SPACE = /,(\S)/g;
1143
- RE_EQUALS_SPACE = /(?<![=!<>])=(?![=><])/g;
1428
+ RE_EQUALS_SPACE = /(?<![=!<>+\-*/%&|^?])=(?![=><])/g;
1144
1429
  RE_PLUS_OP = /(\w)\+(\w)/g;
1145
1430
  RE_MINUS_OP = /(\w)-(\w)/g;
1146
1431
  RE_STAR_OP = /(\w)\*(\w)/g;
1147
1432
  RE_SLASH_OP = /(\w)\/(\w)/g;
1148
- RE_SEMI_SPACE = new RegExp(";" + "([^\\s" + ";" + "])", "g");
1149
- RE_LT_OP = /([\w\])])<(\S)/g;
1150
- RE_GT_OP = /(\S)>([\w[(])/g;
1433
+ RE_SEMI_SPACE = new RegExp("(?<=\\S);" + "([^\\s" + ";" + "])", "g");
1434
+ RE_LT_OP = /([\w)\]])<(\d)/g;
1435
+ RE_GT_OP = /([\w)\]])>(\d)/g;
1151
1436
  RE_MULTI_SPACE = /\s{2,}/g;
1152
1437
  RE_BLANK_LINE = /^\s*$/;
1153
1438
  RE_LINE_COMMENT = /^\s*\/\//;
1154
1439
  RE_BLOCK_COMMENT = /^\s*\/\*/;
1155
1440
  RE_IMPORT_STMT = /^\s*import\b/;
1441
+ RE_IMPORT_COMPLETE = /\bfrom\s*['"][^'"]+['"]|^\s*import\s+['"][^'"]+['"]/;
1156
1442
  RE_PACKAGE_JSON = /package\.json$/i;
1157
1443
  RE_TSCONFIG_JSON = /[jt]sconfig(?:\..+)?\.json$/i;
1158
1444
  RE_TRAILING_WS = /[ \t]+$/;
1159
1445
  RE_LEADING_BLANKS = /^\n+/;
1160
1446
  SPACING_CHARS = new Set(["{", ",", "=", "+", "-", "*", "/", ";", "<", ">"]);
1447
+ REGEX_PRECEDING_KEYWORDS = new Set(["return", "typeof", "instanceof", "in", "of", "new", "delete", "void", "do", "else", "case", "yield", "await"]);
1161
1448
  });
1162
1449
 
1163
1450
  // ../../node_modules/bunfig/dist/index.js
@@ -20724,7 +21011,7 @@ var init_no_unused_vars = __esm(() => {
20724
21011
  let tInBlockComment = false;
20725
21012
  let tEscaped = false;
20726
21013
  let prevSig = "";
20727
- const isRegexStart = () => {
21014
+ const isRegexStart2 = () => {
20728
21015
  if (prevSig === "")
20729
21016
  return true;
20730
21017
  if ("=([{,;!&|?:+-*/%^~<>".includes(prevSig))
@@ -20826,7 +21113,7 @@ var init_no_unused_vars = __esm(() => {
20826
21113
  else
20827
21114
  tmplStack.pop();
20828
21115
  prevSig = "}";
20829
- } else if (ch === "/" && isRegexStart()) {
21116
+ } else if (ch === "/" && isRegexStart2()) {
20830
21117
  tInRegex = true;
20831
21118
  } else if (!/\s/.test(ch)) {
20832
21119
  prevSig = ch;
@@ -20842,7 +21129,7 @@ var init_no_unused_vars = __esm(() => {
20842
21129
  } else if (ch === '"') {
20843
21130
  tInDouble = true;
20844
21131
  prevSig = '"';
20845
- } else if (ch === "/" && isRegexStart()) {
21132
+ } else if (ch === "/" && isRegexStart2()) {
20846
21133
  tInRegex = true;
20847
21134
  } else if (!/\s/.test(ch)) {
20848
21135
  prevSig = ch;
@@ -22041,7 +22328,7 @@ function computeLineStartsInTemplate(text) {
22041
22328
  let inBlockComment = false;
22042
22329
  let escaped = false;
22043
22330
  let prevSig = "";
22044
- const isRegexStart = () => {
22331
+ const isRegexStart2 = () => {
22045
22332
  if (prevSig === "")
22046
22333
  return true;
22047
22334
  return "=([{,;!&|?:+-*/%^~<>".includes(prevSig);
@@ -22141,7 +22428,7 @@ function computeLineStartsInTemplate(text) {
22141
22428
  else
22142
22429
  tmplStack.pop();
22143
22430
  prevSig = "}";
22144
- } else if (ch === "/" && isRegexStart())
22431
+ } else if (ch === "/" && isRegexStart2())
22145
22432
  inRegex = true;
22146
22433
  else if (!/\s/.test(ch))
22147
22434
  prevSig = ch;
@@ -22156,7 +22443,7 @@ function computeLineStartsInTemplate(text) {
22156
22443
  } else if (ch === '"') {
22157
22444
  inDouble = true;
22158
22445
  prevSig = '"';
22159
- } else if (ch === "/" && isRegexStart())
22446
+ } else if (ch === "/" && isRegexStart2())
22160
22447
  inRegex = true;
22161
22448
  else if (!/\s/.test(ch))
22162
22449
  prevSig = ch;
@@ -32802,7 +33089,7 @@ function findMatching(text, start, open, close) {
32802
33089
  }
32803
33090
  return i;
32804
33091
  };
32805
- const isRegexStart = (i) => {
33092
+ const isRegexStart2 = (i) => {
32806
33093
  let j = i - 1;
32807
33094
  while (j >= 0 && isWhitespace(text[j])) {
32808
33095
  j--;
@@ -32858,7 +33145,7 @@ function findMatching(text, start, open, close) {
32858
33145
  i = skipBlockComment(i) - 1;
32859
33146
  continue;
32860
33147
  }
32861
- if (ch === "/" && isRegexStart(i)) {
33148
+ if (ch === "/" && isRegexStart2(i)) {
32862
33149
  i = skipRegex(i) - 1;
32863
33150
  continue;
32864
33151
  }
@@ -38635,7 +38922,7 @@ function stripRegexLiterals(line) {
38635
38922
  }
38636
38923
  return result;
38637
38924
  }
38638
- function isRegexStart(lastSignificant, line, idx) {
38925
+ function isRegexStart2(lastSignificant, line, idx) {
38639
38926
  if (lastSignificant === "")
38640
38927
  return true;
38641
38928
  const regexAfter = "([{,:;!?&|=<>~^+*%-";
@@ -39058,7 +39345,7 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
39058
39345
  prev = ch;
39059
39346
  continue;
39060
39347
  }
39061
- if (ch === "/" && ln[k + 1] !== "/" && ln[k + 1] !== "*" && isRegexStart(lastSig, ln, k)) {
39348
+ if (ch === "/" && ln[k + 1] !== "/" && ln[k + 1] !== "*" && isRegexStart2(lastSig, ln, k)) {
39062
39349
  inRegex = true;
39063
39350
  inRegexClass = false;
39064
39351
  prev = ch;
@@ -43647,7 +43934,7 @@ var require_package = __commonJS((exports, module) => {
43647
43934
  module.exports = {
43648
43935
  name: "pickier",
43649
43936
  type: "module",
43650
- version: "0.1.33",
43937
+ version: "0.1.35",
43651
43938
  description: "Format, lint and more in a fraction of seconds.",
43652
43939
  author: "Chris Breuer <chris@stacksjs.org>",
43653
43940
  license: "MIT",
package/dist/src/index.js CHANGED
@@ -8882,6 +8882,37 @@ var init_config = __esm(() => {
8882
8882
  });
8883
8883
 
8884
8884
  // src/format.ts
8885
+ function isHangingControlLine(code) {
8886
+ const m = RE_CONTROL_OPEN.exec(code);
8887
+ if (!m)
8888
+ return /^(?:else|do)\s*$/.test(code);
8889
+ let depth = 0;
8890
+ let inStr = null;
8891
+ for (let i = m[0].length - 1;i < code.length; i++) {
8892
+ const ch = code[i];
8893
+ if (inStr) {
8894
+ if (ch === "\\") {
8895
+ i++;
8896
+ continue;
8897
+ }
8898
+ if (ch === inStr)
8899
+ inStr = null;
8900
+ continue;
8901
+ }
8902
+ if (ch === "'" || ch === '"' || ch === "`") {
8903
+ inStr = ch;
8904
+ continue;
8905
+ }
8906
+ if (ch === "(") {
8907
+ depth++;
8908
+ } else if (ch === ")") {
8909
+ depth--;
8910
+ if (depth === 0)
8911
+ return code.slice(i + 1).trim().length === 0;
8912
+ }
8913
+ }
8914
+ return false;
8915
+ }
8885
8916
  function getFileExt(filePath) {
8886
8917
  const idx = filePath.lastIndexOf(".");
8887
8918
  return idx >= 0 ? filePath.slice(idx) : "";
@@ -9032,6 +9063,25 @@ function fixQuotesLine(line, preferred) {
9032
9063
  while (i < line.length) {
9033
9064
  const ch = line[i];
9034
9065
  if (inString === 0) {
9066
+ if (ch === "/") {
9067
+ const nxt = line[i + 1];
9068
+ if (nxt === "/")
9069
+ break;
9070
+ if (nxt === "*") {
9071
+ const end = line.indexOf("*/", i + 2);
9072
+ i = end === -1 ? line.length : end + 2;
9073
+ continue;
9074
+ }
9075
+ if (isRegexStart(line, i)) {
9076
+ const end = scanRegexEnd(line, i);
9077
+ if (end !== -1) {
9078
+ i = end;
9079
+ continue;
9080
+ }
9081
+ }
9082
+ i++;
9083
+ continue;
9084
+ }
9035
9085
  if (ch === '"') {
9036
9086
  inString = 2;
9037
9087
  stringStart = i;
@@ -9099,6 +9149,8 @@ function normalizeSpacingLine(line) {
9099
9149
  const c = line[firstNonSpace];
9100
9150
  if (c === "/" && (line[firstNonSpace + 1] === "/" || line[firstNonSpace + 1] === "*"))
9101
9151
  return line;
9152
+ if (c === "*")
9153
+ return line;
9102
9154
  }
9103
9155
  let hasSpacingChar = false;
9104
9156
  for (let j = firstNonSpace;j < line.length; j++) {
@@ -9211,6 +9263,49 @@ function advanceTemplateState(line, stack) {
9211
9263
  }
9212
9264
  return -1;
9213
9265
  }
9266
+ function blockCommentStateAfter(line, startsIn) {
9267
+ let inBlock = startsIn;
9268
+ let inStr = null;
9269
+ let i = 0;
9270
+ while (i < line.length) {
9271
+ const ch = line[i];
9272
+ if (inBlock) {
9273
+ if (ch === "*" && line[i + 1] === "/") {
9274
+ inBlock = false;
9275
+ i += 2;
9276
+ continue;
9277
+ }
9278
+ i++;
9279
+ continue;
9280
+ }
9281
+ if (inStr) {
9282
+ if (ch === "\\") {
9283
+ i += 2;
9284
+ continue;
9285
+ }
9286
+ if (ch === inStr)
9287
+ inStr = null;
9288
+ i++;
9289
+ continue;
9290
+ }
9291
+ if (ch === "'" || ch === '"' || ch === "`") {
9292
+ inStr = ch;
9293
+ i++;
9294
+ continue;
9295
+ }
9296
+ if (ch === "/") {
9297
+ if (line[i + 1] === "/")
9298
+ break;
9299
+ if (line[i + 1] === "*") {
9300
+ inBlock = true;
9301
+ i += 2;
9302
+ continue;
9303
+ }
9304
+ }
9305
+ i++;
9306
+ }
9307
+ return inBlock;
9308
+ }
9214
9309
  function processCodeLinesFused(content, cfg) {
9215
9310
  const lines = content.split(`
9216
9311
  `);
@@ -9219,9 +9314,16 @@ function processCodeLinesFused(content, cfg) {
9219
9314
  const preferred = cfg.format.quotes;
9220
9315
  const doSemiRemoval = cfg.format.semi === true;
9221
9316
  let indentLevel = 0;
9317
+ let hangDepth = 0;
9318
+ let inBlockComment = false;
9222
9319
  const tmplStack = [];
9223
9320
  for (let idx = 0;idx < len; idx++) {
9224
9321
  let line = lines[idx];
9322
+ if (inBlockComment) {
9323
+ inBlockComment = blockCommentStateAfter(line, true);
9324
+ result[idx] = line;
9325
+ continue;
9326
+ }
9225
9327
  const protectedLine = inTemplateText(tmplStack);
9226
9328
  let splitIdx = -1;
9227
9329
  if (tmplStack.length > 0 || line.indexOf("`") !== -1)
@@ -9230,6 +9332,8 @@ function processCodeLinesFused(content, cfg) {
9230
9332
  result[idx] = line;
9231
9333
  continue;
9232
9334
  }
9335
+ if (splitIdx < 0 && tmplStack.length === 0)
9336
+ inBlockComment = blockCommentStateAfter(line, false);
9233
9337
  let tmplTail = "";
9234
9338
  let prefixEndedWithSpace = false;
9235
9339
  if (splitIdx >= 0) {
@@ -9253,9 +9357,15 @@ function processCodeLinesFused(content, cfg) {
9253
9357
  const trimmed = line.slice(wsEnd).trimEnd();
9254
9358
  if (RE_CLOSING_BRACE.test(trimmed))
9255
9359
  indentLevel = Math.max(0, indentLevel - 1);
9256
- line = makeIndent(indentLevel, cfg) + trimmed;
9257
- if (RE_OPENING_BRACE.test(trimmed))
9360
+ const continuationBump = RE_CONTINUATION_LINE.test(trimmed) ? 1 : 0;
9361
+ line = makeIndent(indentLevel + hangDepth + continuationBump, cfg) + trimmed;
9362
+ if (RE_OPENING_BRACE.test(trimmed)) {
9258
9363
  indentLevel += 1;
9364
+ hangDepth = 0;
9365
+ } else if (!trimmed.startsWith("//") && !trimmed.startsWith("*") && !trimmed.startsWith("/*")) {
9366
+ const code = trimmed.replace(RE_TRAILING_LINE_COMMENT, "");
9367
+ hangDepth = isHangingControlLine(code) ? hangDepth + 1 : 0;
9368
+ }
9259
9369
  line = normalizeSpacingLine(line);
9260
9370
  if (doSemiRemoval) {
9261
9371
  if (!RE_FOR_LOOP.test(line)) {
@@ -9448,8 +9558,87 @@ function hasIndentIssue(leading, indentSize, indentStyle = "spaces", lineContent
9448
9558
  }
9449
9559
  return spaces % indentSize !== 0;
9450
9560
  }
9561
+ function skipTemplate(input, start) {
9562
+ let i = start + 1;
9563
+ while (i < input.length) {
9564
+ const c = input[i];
9565
+ if (c === "\\") {
9566
+ i += 2;
9567
+ continue;
9568
+ }
9569
+ if (c === "`")
9570
+ return i + 1;
9571
+ if (c === "$" && input[i + 1] === "{") {
9572
+ i += 2;
9573
+ let depth = 1;
9574
+ while (i < input.length && depth > 0) {
9575
+ const d = input[i];
9576
+ if (d === "\\") {
9577
+ i += 2;
9578
+ continue;
9579
+ }
9580
+ if (d === "`") {
9581
+ i = skipTemplate(input, i);
9582
+ continue;
9583
+ }
9584
+ if (d === "'" || d === '"') {
9585
+ i = skipQuoted(input, i, d);
9586
+ continue;
9587
+ }
9588
+ if (d === "{")
9589
+ depth++;
9590
+ else if (d === "}")
9591
+ depth--;
9592
+ i++;
9593
+ }
9594
+ continue;
9595
+ }
9596
+ i++;
9597
+ }
9598
+ return i;
9599
+ }
9600
+ function isRegexStart(input, slashIdx) {
9601
+ let j = slashIdx - 1;
9602
+ while (j >= 0 && (input[j] === " " || input[j] === "\t"))
9603
+ j--;
9604
+ if (j < 0)
9605
+ return true;
9606
+ const prev = input[j];
9607
+ if ("(,=:[!&|?;{}<>+-*%^~".includes(prev))
9608
+ return true;
9609
+ if (/[\w$]/.test(prev)) {
9610
+ let k = j;
9611
+ while (k >= 0 && /[\w$]/.test(input[k]))
9612
+ k--;
9613
+ return REGEX_PRECEDING_KEYWORDS.has(input.slice(k + 1, j + 1));
9614
+ }
9615
+ return false;
9616
+ }
9617
+ function scanRegexEnd(input, start) {
9618
+ let i = start + 1;
9619
+ let inClass = false;
9620
+ while (i < input.length) {
9621
+ const c = input[i];
9622
+ if (c === "\\") {
9623
+ i += 2;
9624
+ continue;
9625
+ }
9626
+ if (c === "[") {
9627
+ inClass = true;
9628
+ } else if (c === "]") {
9629
+ inClass = false;
9630
+ } else if (c === "/" && !inClass) {
9631
+ i++;
9632
+ while (i < input.length && /[a-z]/i.test(input[i]))
9633
+ i++;
9634
+ return i;
9635
+ }
9636
+ i++;
9637
+ }
9638
+ return -1;
9639
+ }
9451
9640
  function maskStrings(input) {
9452
- if (!input.includes("'") && !input.includes('"') && !input.includes("`"))
9641
+ if (!input.includes("'") && !input.includes('"') && !input.includes("`") && !input.includes("/"))
9453
9642
  return { text: input, strings: [] };
9454
9643
  const strings = [];
9455
9644
  const parts = [];
@@ -9457,22 +9646,62 @@ function maskStrings(input) {
9457
9646
  let segStart = 0;
9458
9647
  while (i < input.length) {
9459
9648
  const ch = input[i];
9649
+ if (ch === "/") {
9650
+ const next = input[i + 1];
9651
+ if (next === "/") {
9652
+ if (i > segStart)
9653
+ parts.push(input.slice(segStart, i));
9654
+ strings.push(input.slice(i));
9655
+ parts.push(`@@S${strings.length - 1}@@`);
9656
+ segStart = input.length;
9657
+ break;
9658
+ }
9659
+ if (next === "*") {
9660
+ const end = input.indexOf("*/", i + 2);
9661
+ const stop = end === -1 ? input.length : end + 2;
9662
+ if (i > segStart)
9663
+ parts.push(input.slice(segStart, i));
9664
+ strings.push(input.slice(i, stop));
9665
+ parts.push(`@@S${strings.length - 1}@@`);
9666
+ i = stop;
9667
+ segStart = i;
9668
+ continue;
9669
+ }
9670
+ if (isRegexStart(input, i)) {
9671
+ const end = scanRegexEnd(input, i);
9672
+ if (end !== -1) {
9673
+ if (i > segStart)
9674
+ parts.push(input.slice(segStart, i));
9675
+ strings.push(input.slice(i, end));
9676
+ parts.push(`@@S${strings.length - 1}@@`);
9677
+ i = end;
9678
+ segStart = i;
9679
+ continue;
9680
+ }
9681
+ }
9682
+ i++;
9683
+ continue;
9684
+ }
9460
9685
  if (ch === "'" || ch === '"' || ch === "`") {
9461
9686
  if (i > segStart)
9462
9687
  parts.push(input.slice(segStart, i));
9463
9688
  const start = i;
9464
- const close = ch;
9465
- i++;
9466
- while (i < input.length) {
9467
- if (input[i] === "\\") {
9468
- i += 2;
9469
- continue;
9470
- }
9471
- if (input[i] === close) {
9689
+ if (ch === "`") {
9690
+ i = skipTemplate(input, i);
9691
+ } else {
9692
+ const close = ch;
9693
+ i++;
9694
+ while (i < input.length) {
9695
+ if (input[i] === "\\") {
9696
+ i += 2;
9697
+ continue;
9698
+ }
9699
+ if (input[i] === close) {
9700
+ i++;
9701
+ break;
9702
+ }
9472
9703
  i++;
9473
- break;
9474
9704
  }
9475
- i++;
9476
9705
  }
9477
9706
  strings.push(input.slice(start, i));
9478
9707
  parts.push(`@@S${strings.length - 1}@@`);
@@ -9508,24 +9737,65 @@ function formatImports(source) {
9508
9737
  const lines = source.split(`
9509
9738
  `);
9510
9739
  const imports = [];
9740
+ const preamble = [];
9741
+ const interleaved = [];
9511
9742
  let idx = 0;
9743
+ let lastEnd = 0;
9744
+ let pendingStart = -1;
9745
+ let sawImport = false;
9512
9746
  while (idx < lines.length) {
9513
9747
  const line = lines[idx];
9514
- if (RE_BLANK_LINE.test(line) || RE_LINE_COMMENT.test(line) || RE_BLOCK_COMMENT.test(line)) {
9748
+ if (RE_BLANK_LINE.test(line)) {
9515
9749
  idx++;
9516
9750
  continue;
9517
9751
  }
9752
+ if (RE_LINE_COMMENT.test(line) || RE_BLOCK_COMMENT.test(line)) {
9753
+ const start = idx;
9754
+ if (RE_BLOCK_COMMENT.test(line)) {
9755
+ while (idx < lines.length && !lines[idx].includes("*/"))
9756
+ idx++;
9757
+ idx++;
9758
+ } else {
9759
+ idx++;
9760
+ }
9761
+ if (!sawImport) {
9762
+ for (let k = start;k < idx && k < lines.length; k++)
9763
+ preamble.push(lines[k]);
9764
+ lastEnd = idx;
9765
+ } else if (pendingStart < 0) {
9766
+ pendingStart = start;
9767
+ }
9768
+ continue;
9769
+ }
9518
9770
  if (!RE_IMPORT_STMT.test(line))
9519
9771
  break;
9520
- const stmt = line.trim();
9772
+ let stmt = line.trim();
9773
+ let stmtEnd = idx + 1;
9774
+ while (!RE_IMPORT_COMPLETE.test(stmt) && stmtEnd < lines.length && stmtEnd - idx < 50) {
9775
+ stmt += ` ${lines[stmtEnd].trim()}`;
9776
+ stmtEnd++;
9777
+ }
9778
+ if (!RE_IMPORT_COMPLETE.test(stmt))
9779
+ return source;
9521
9780
  const parsed = parseImportStatement(stmt);
9522
- if (parsed)
9523
- imports.push(parsed);
9524
- idx++;
9781
+ if (!parsed)
9782
+ return source;
9783
+ if (pendingStart >= 0) {
9784
+ for (let k = pendingStart;k < idx; k++) {
9785
+ if (!RE_BLANK_LINE.test(lines[k]))
9786
+ interleaved.push(lines[k]);
9787
+ }
9788
+ pendingStart = -1;
9789
+ }
9790
+ imports.push(parsed);
9791
+ idx = stmtEnd;
9792
+ lastEnd = idx;
9793
+ sawImport = true;
9525
9794
  }
9526
9795
  if (imports.length === 0)
9527
9796
  return source;
9528
- const rest = lines.slice(idx).join(`
9797
+ const restStart = pendingStart >= 0 ? pendingStart : lastEnd;
9798
+ const rest = lines.slice(restStart).join(`
9529
9799
  `);
9530
9800
  const usedIdentifiers = collectIdentifierSet(rest);
9531
9801
  const used = (name) => usedIdentifiers.has(name);
@@ -9646,17 +9916,29 @@ function formatImports(source) {
9646
9916
  }
9647
9917
  return a.source.localeCompare(b.source);
9648
9918
  });
9919
+ const head = preamble.length > 0 ? `${preamble.join(`
9920
+ `)}
9921
+ ` : "";
9649
9922
  if (entries.length === 0) {
9650
- return rest.replace(/^\n+/, "");
9923
+ const restClean2 = rest.replace(/^\n+/, "");
9924
+ const kept = [...interleaved];
9925
+ if (head || kept.length > 0)
9926
+ return `${head}${kept.length > 0 ? `${kept.join(`
9927
+ `)}
9928
+ ` : ""}${restClean2}`;
9929
+ return restClean2;
9651
9930
  }
9652
9931
  const rendered = entries.map(renderImport).join(`
9653
9932
  `);
9654
- const sep = rest.length > 0 && !rest.startsWith(`
9655
- `) ? `
9933
+ const mid = interleaved.length > 0 ? `
9934
+ ${interleaved.join(`
9935
+ `)}` : "";
9936
+ const restClean = rest.replace(/^\n+/, "");
9937
+ const sep = restClean.length > 0 ? `
9656
9938
 
9657
9939
  ` : `
9658
9940
  `;
9659
- return `${rendered}${sep}${rest.replace(/^\n+/, "")}`;
9941
+ return `${head}${rendered}${mid}${sep}${restClean}`;
9660
9942
  }
9661
9943
  function renderImport(imp) {
9662
9944
  if (imp.kind === "side-effect")
@@ -9959,39 +10241,44 @@ function sortTsconfigContent(text) {
9959
10241
  }
9960
10242
  return JSON.stringify(outTop, null, 2);
9961
10243
  }
9962
- var CODE_EXTS, JSON_EXTS, YAML_EXTS, SHELL_EXTS, SHELL_SHEBANG_RE, RE_CLOSING_BRACE, RE_OPENING_BRACE, RE_FOR_LOOP, RE_EMPTY_SEMI, RE_DUP_SEMI, RE_SPACE_BEFORE_BRACE, RE_SPACE_AFTER_BRACE_KW, RE_COMMA_SPACE, RE_EQUALS_SPACE, RE_PLUS_OP, RE_MINUS_OP, RE_STAR_OP, RE_SLASH_OP, RE_SEMI_SPACE, RE_LT_OP, RE_GT_OP, RE_MULTI_SPACE, RE_BLANK_LINE, RE_LINE_COMMENT, RE_BLOCK_COMMENT, RE_IMPORT_STMT, RE_PACKAGE_JSON, RE_TSCONFIG_JSON, RE_TRAILING_WS, RE_LEADING_BLANKS, SPACING_CHARS;
10244
+ var CODE_EXTS, JSON_EXTS, YAML_EXTS, SHELL_EXTS, SHELL_SHEBANG_RE, RE_CLOSING_BRACE, RE_OPENING_BRACE, RE_TRAILING_LINE_COMMENT, RE_CONTROL_OPEN, RE_CONTINUATION_LINE, RE_FOR_LOOP, RE_EMPTY_SEMI, RE_DUP_SEMI, RE_SPACE_BEFORE_BRACE, RE_SPACE_AFTER_BRACE_KW, RE_COMMA_SPACE, RE_EQUALS_SPACE, RE_PLUS_OP, RE_MINUS_OP, RE_STAR_OP, RE_SLASH_OP, RE_SEMI_SPACE, RE_LT_OP, RE_GT_OP, RE_MULTI_SPACE, RE_BLANK_LINE, RE_LINE_COMMENT, RE_BLOCK_COMMENT, RE_IMPORT_STMT, RE_IMPORT_COMPLETE, RE_PACKAGE_JSON, RE_TSCONFIG_JSON, RE_TRAILING_WS, RE_LEADING_BLANKS, SPACING_CHARS, REGEX_PRECEDING_KEYWORDS;
9963
10245
  var init_format = __esm(() => {
9964
10246
  CODE_EXTS = new Set([".ts", ".js"]);
9965
10247
  JSON_EXTS = new Set([".json", ".jsonc"]);
9966
10248
  YAML_EXTS = new Set([".yaml", ".yml"]);
9967
10249
  SHELL_EXTS = new Set([".sh", ".bash", ".zsh", ".ksh", ".dash"]);
9968
10250
  SHELL_SHEBANG_RE = /^#!\s*(?:\/usr\/bin\/env\s+)?(?:ba|z|k|da)?sh\b/;
9969
- RE_CLOSING_BRACE = /^\}/;
9970
- RE_OPENING_BRACE = /\{\s*$/;
10251
+ RE_CLOSING_BRACE = /^[}\])]/;
10252
+ RE_OPENING_BRACE = /[{[(]\s*$/;
10253
+ RE_TRAILING_LINE_COMMENT = /\s*\/\/.*$/;
10254
+ RE_CONTROL_OPEN = /^(?:if|else\s+if|for|while)\s*\(/;
10255
+ RE_CONTINUATION_LINE = /^(?:\.[\w$[]|\?[\s.:]|:\s|&&|\|\|)/;
9971
10256
  RE_FOR_LOOP = /^\s*for\s*\(/;
9972
10257
  RE_EMPTY_SEMI = new RegExp("^\\s*" + ";" + "\\s*$");
9973
10258
  RE_DUP_SEMI = new RegExp(";" + "{2,}\\s*$");
9974
- RE_SPACE_BEFORE_BRACE = /(\S)\{/g;
10259
+ RE_SPACE_BEFORE_BRACE = /([\w)])\{/g;
9975
10260
  RE_SPACE_AFTER_BRACE_KW = /\{(return|if|for|while|switch|const|let|var|function)\b/g;
9976
10261
  RE_COMMA_SPACE = /,(\S)/g;
9977
- RE_EQUALS_SPACE = /(?<![=!<>])=(?![=><])/g;
10262
+ RE_EQUALS_SPACE = /(?<![=!<>+\-*/%&|^?])=(?![=><])/g;
9978
10263
  RE_PLUS_OP = /(\w)\+(\w)/g;
9979
10264
  RE_MINUS_OP = /(\w)-(\w)/g;
9980
10265
  RE_STAR_OP = /(\w)\*(\w)/g;
9981
10266
  RE_SLASH_OP = /(\w)\/(\w)/g;
9982
- RE_SEMI_SPACE = new RegExp(";" + "([^\\s" + ";" + "])", "g");
9983
- RE_LT_OP = /([\w\])])<(\S)/g;
9984
- RE_GT_OP = /(\S)>([\w[(])/g;
10267
+ RE_SEMI_SPACE = new RegExp("(?<=\\S);" + "([^\\s" + ";" + "])", "g");
10268
+ RE_LT_OP = /([\w)\]])<(\d)/g;
10269
+ RE_GT_OP = /([\w)\]])>(\d)/g;
9985
10270
  RE_MULTI_SPACE = /\s{2,}/g;
9986
10271
  RE_BLANK_LINE = /^\s*$/;
9987
10272
  RE_LINE_COMMENT = /^\s*\/\//;
9988
10273
  RE_BLOCK_COMMENT = /^\s*\/\*/;
9989
10274
  RE_IMPORT_STMT = /^\s*import\b/;
10275
+ RE_IMPORT_COMPLETE = /\bfrom\s*['"][^'"]+['"]|^\s*import\s+['"][^'"]+['"]/;
9990
10276
  RE_PACKAGE_JSON = /package\.json$/i;
9991
10277
  RE_TSCONFIG_JSON = /[jt]sconfig(?:\..+)?\.json$/i;
9992
10278
  RE_TRAILING_WS = /[ \t]+$/;
9993
10279
  RE_LEADING_BLANKS = /^\n+/;
9994
10280
  SPACING_CHARS = new Set(["{", ",", "=", "+", "-", "*", "/", ";", "<", ">"]);
10281
+ REGEX_PRECEDING_KEYWORDS = new Set(["return", "typeof", "instanceof", "in", "of", "new", "delete", "void", "do", "else", "case", "yield", "await"]);
9995
10282
  });
9996
10283
 
9997
10284
  // ../../node_modules/@stacksjs/clarity/dist/src/index.js
@@ -20322,7 +20609,7 @@ var init_no_unused_vars = __esm(() => {
20322
20609
  let tInBlockComment = false;
20323
20610
  let tEscaped = false;
20324
20611
  let prevSig = "";
20325
- const isRegexStart = () => {
20612
+ const isRegexStart2 = () => {
20326
20613
  if (prevSig === "")
20327
20614
  return true;
20328
20615
  if ("=([{,;!&|?:+-*/%^~<>".includes(prevSig))
@@ -20424,7 +20711,7 @@ var init_no_unused_vars = __esm(() => {
20424
20711
  else
20425
20712
  tmplStack.pop();
20426
20713
  prevSig = "}";
20427
- } else if (ch === "/" && isRegexStart()) {
20714
+ } else if (ch === "/" && isRegexStart2()) {
20428
20715
  tInRegex = true;
20429
20716
  } else if (!/\s/.test(ch)) {
20430
20717
  prevSig = ch;
@@ -20440,7 +20727,7 @@ var init_no_unused_vars = __esm(() => {
20440
20727
  } else if (ch === '"') {
20441
20728
  tInDouble = true;
20442
20729
  prevSig = '"';
20443
- } else if (ch === "/" && isRegexStart()) {
20730
+ } else if (ch === "/" && isRegexStart2()) {
20444
20731
  tInRegex = true;
20445
20732
  } else if (!/\s/.test(ch)) {
20446
20733
  prevSig = ch;
@@ -21639,7 +21926,7 @@ function computeLineStartsInTemplate(text) {
21639
21926
  let inBlockComment = false;
21640
21927
  let escaped = false;
21641
21928
  let prevSig = "";
21642
- const isRegexStart = () => {
21929
+ const isRegexStart2 = () => {
21643
21930
  if (prevSig === "")
21644
21931
  return true;
21645
21932
  return "=([{,;!&|?:+-*/%^~<>".includes(prevSig);
@@ -21739,7 +22026,7 @@ function computeLineStartsInTemplate(text) {
21739
22026
  else
21740
22027
  tmplStack.pop();
21741
22028
  prevSig = "}";
21742
- } else if (ch === "/" && isRegexStart())
22029
+ } else if (ch === "/" && isRegexStart2())
21743
22030
  inRegex = true;
21744
22031
  else if (!/\s/.test(ch))
21745
22032
  prevSig = ch;
@@ -21754,7 +22041,7 @@ function computeLineStartsInTemplate(text) {
21754
22041
  } else if (ch === '"') {
21755
22042
  inDouble = true;
21756
22043
  prevSig = '"';
21757
- } else if (ch === "/" && isRegexStart())
22044
+ } else if (ch === "/" && isRegexStart2())
21758
22045
  inRegex = true;
21759
22046
  else if (!/\s/.test(ch))
21760
22047
  prevSig = ch;
@@ -32400,7 +32687,7 @@ function findMatching(text, start, open, close) {
32400
32687
  }
32401
32688
  return i;
32402
32689
  };
32403
- const isRegexStart = (i) => {
32690
+ const isRegexStart2 = (i) => {
32404
32691
  let j = i - 1;
32405
32692
  while (j >= 0 && isWhitespace(text[j])) {
32406
32693
  j--;
@@ -32456,7 +32743,7 @@ function findMatching(text, start, open, close) {
32456
32743
  i = skipBlockComment(i) - 1;
32457
32744
  continue;
32458
32745
  }
32459
- if (ch === "/" && isRegexStart(i)) {
32746
+ if (ch === "/" && isRegexStart2(i)) {
32460
32747
  i = skipRegex(i) - 1;
32461
32748
  continue;
32462
32749
  }
@@ -38634,7 +38921,7 @@ function stripRegexLiterals(line) {
38634
38921
  }
38635
38922
  return result;
38636
38923
  }
38637
- function isRegexStart(lastSignificant, line, idx) {
38924
+ function isRegexStart2(lastSignificant, line, idx) {
38638
38925
  if (lastSignificant === "")
38639
38926
  return true;
38640
38927
  const regexAfter = "([{,:;!?&|=<>~^+*%-";
@@ -39057,7 +39344,7 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
39057
39344
  prev = ch;
39058
39345
  continue;
39059
39346
  }
39060
- if (ch === "/" && ln[k + 1] !== "/" && ln[k + 1] !== "*" && isRegexStart(lastSig, ln, k)) {
39347
+ if (ch === "/" && ln[k + 1] !== "/" && ln[k + 1] !== "*" && isRegexStart2(lastSig, ln, k)) {
39061
39348
  inRegex = true;
39062
39349
  inRegexClass = false;
39063
39350
  prev = ch;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pickier",
3
3
  "type": "module",
4
- "version": "0.1.33",
4
+ "version": "0.1.35",
5
5
  "description": "Format, lint and more in a fraction of seconds.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",