pm-ops 2026.9.18 → 2026.9.26

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.
@@ -1,14 +1,20 @@
1
1
  /**
2
2
  * Canonical TypeScript duplication analysis and fail-closed gate for the fleet.
3
3
  *
4
- * This module uses jscpd's programmatic detector rather than its CLI, keeping
5
- * consumer launchers small while preserving the detector's clone locations and
6
- * aggregate percentage for machine-readable callers.
4
+ * Two jscpd majors are supported, and their engines are structurally
5
+ * different, so the analyzer dispatches on the installed major:
6
+ *
7
+ * - jscpd 4 ships a Node.js programmatic API, used directly so consumer
8
+ * launchers stay small while preserving the detector's clone locations.
9
+ * - jscpd 5 replaced the Node.js API with a self-contained Rust binary, so
10
+ * the analyzer runs the binary with its JSON reporter and parses the report.
7
11
  */
8
12
  import fastGlob from "fast-glob";
9
13
  import { createRequire } from "node:module";
10
- import { readFileSync } from "node:fs";
11
- import { relative, resolve, sep } from "node:path";
14
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
15
+ import { tmpdir } from "node:os";
16
+ import { dirname, join, relative, resolve, sep } from "node:path";
17
+ import { spawnSync } from "node:child_process";
12
18
  /** Default TypeScript glob scanned by the duplication gate. */
13
19
  export const DEFAULT_DUPLICATION_GLOBS = ["**/*.ts"];
14
20
  const defaultRepoRoot = process.cwd();
@@ -23,11 +29,75 @@ const DUPLICATION_IGNORES = [
23
29
  "**/*.d.ts",
24
30
  ];
25
31
  const require = createRequire(import.meta.url);
26
- const jscpd = require("jscpd");
27
32
  /** Return whether an unknown JSON value is a record with string keys. */
28
33
  function isRecord(value) {
29
34
  return typeof value === "object" && value !== null;
30
35
  }
36
+ /** Require a record-shaped JSON value from jscpd's report, failing closed otherwise. */
37
+ function expectRecord(value, context) {
38
+ if (!isRecord(value))
39
+ throw new Error(`duplication: jscpd report ${context} is not an object`);
40
+ return value;
41
+ }
42
+ /** Require a finite number field of a jscpd report record, failing closed otherwise. */
43
+ function expectNumber(record, key, context) {
44
+ const value = record[key];
45
+ if (typeof value !== "number" || !Number.isFinite(value)) {
46
+ throw new Error(`duplication: jscpd report ${context} is not a number`);
47
+ }
48
+ return value;
49
+ }
50
+ /** Require a string field of a jscpd report record, failing closed otherwise. */
51
+ function expectString(record, key, context) {
52
+ const value = record[key];
53
+ if (typeof value !== "string")
54
+ throw new Error(`duplication: jscpd report ${context} is not a string`);
55
+ return value;
56
+ }
57
+ /** Require one cloned file end of a jscpd 5 report record. */
58
+ function expectCloneEnd(value, context) {
59
+ const record = expectRecord(value, context);
60
+ return {
61
+ name: expectString(record, "name", `${context}.name`),
62
+ start: expectNumber(record, "start", `${context}.start`),
63
+ end: expectNumber(record, "end", `${context}.end`),
64
+ };
65
+ }
66
+ /**
67
+ * Parse and validate a jscpd 5 JSON report.
68
+ *
69
+ * Every field the duplication gate consumes is checked, so a jscpd output
70
+ * format change fails the gate closed instead of silently reporting zero.
71
+ *
72
+ * @param report - The parsed `jscpd-report.json` value.
73
+ * @returns The clone pairs and aggregate line statistics, validated.
74
+ */
75
+ export function parseJscpdReport(report) {
76
+ const root = expectRecord(report, "root");
77
+ const duplicates = root.duplicates;
78
+ if (!Array.isArray(duplicates))
79
+ throw new Error("duplication: jscpd report duplicates is not an array");
80
+ const clones = duplicates.map((clone) => {
81
+ const record = expectRecord(clone, "clone");
82
+ return {
83
+ firstFile: expectCloneEnd(record.firstFile, "clone.firstFile"),
84
+ secondFile: expectCloneEnd(record.secondFile, "clone.secondFile"),
85
+ };
86
+ });
87
+ const statistics = expectRecord(root.statistics, "statistics");
88
+ const total = expectRecord(statistics.total, "statistics.total");
89
+ const lines = expectNumber(total, "lines", "statistics.total.lines");
90
+ const duplicatedLines = expectNumber(total, "duplicatedLines", "statistics.total.duplicatedLines");
91
+ // An impossible count (negative, fractional, or more duplicated than total lines)
92
+ // would compute a passing percentage, so it fails closed like a missing field.
93
+ if (!Number.isInteger(lines) ||
94
+ !Number.isInteger(duplicatedLines) ||
95
+ duplicatedLines < 0 ||
96
+ duplicatedLines > lines) {
97
+ throw new Error("duplication: jscpd report statistics.total contains impossible line counts");
98
+ }
99
+ return { duplicates: clones, statistics: { total: { lines, duplicatedLines } } };
100
+ }
31
101
  /** Parse and validate the package-level duplication gate contract. */
32
102
  function readDuplicationConfig(manifest) {
33
103
  if (!isRecord(manifest.duplicationGate))
@@ -49,19 +119,22 @@ function readDuplicationConfig(manifest) {
49
119
  function relativeSource(repoRoot, sourceId) {
50
120
  return relative(repoRoot, resolve(repoRoot, sourceId)).split(sep).join("/");
51
121
  }
52
- /** Convert one jscpd clone into the public report's line-range shape. */
53
- function mapClone(repoRoot, clone) {
122
+ /** Convert one cloned file end into the public report's file and line-range shape. */
123
+ function cloneEnd(repoRoot, sourceId, startLine, endLine) {
124
+ return { file: relativeSource(repoRoot, sourceId), startLine, endLine };
125
+ }
126
+ /** Convert one jscpd 4 clone into the public report's line-range shape. */
127
+ function mapProgrammaticClone(repoRoot, clone) {
128
+ return {
129
+ first: cloneEnd(repoRoot, clone.duplicationA.sourceId, clone.duplicationA.start.line, clone.duplicationA.end.line),
130
+ second: cloneEnd(repoRoot, clone.duplicationB.sourceId, clone.duplicationB.start.line, clone.duplicationB.end.line),
131
+ };
132
+ }
133
+ /** Convert one jscpd 5 clone into the public report's line-range shape. */
134
+ function mapReportedClone(repoRoot, clone) {
54
135
  return {
55
- first: {
56
- file: relativeSource(repoRoot, clone.duplicationA.sourceId),
57
- startLine: clone.duplicationA.start.line,
58
- endLine: clone.duplicationA.end.line,
59
- },
60
- second: {
61
- file: relativeSource(repoRoot, clone.duplicationB.sourceId),
62
- startLine: clone.duplicationB.start.line,
63
- endLine: clone.duplicationB.end.line,
64
- },
136
+ first: cloneEnd(repoRoot, clone.firstFile.name, clone.firstFile.start, clone.firstFile.end),
137
+ second: cloneEnd(repoRoot, clone.secondFile.name, clone.secondFile.start, clone.secondFile.end),
65
138
  };
66
139
  }
67
140
  /** Turn configured glob entries into the one fast-glob pattern jscpd accepts. */
@@ -84,7 +157,7 @@ function globMatchedSources(repoRoot, pattern) {
84
157
  .map((source) => relativeSource(repoRoot, source))
85
158
  .sort();
86
159
  }
87
- /** Build the bounded jscpd options shared by matching and actual analysis. */
160
+ /** Build the bounded jscpd 4 options shared by matching and actual analysis. */
88
161
  function duplicationOptions(repoRoot, pattern, minTokens) {
89
162
  return {
90
163
  path: [repoRoot],
@@ -101,6 +174,116 @@ function duplicationOptions(repoRoot, pattern, minTokens) {
101
174
  silent: true,
102
175
  };
103
176
  }
177
+ /** Compute the duplicated-line percentage jscpd's own line counts imply. */
178
+ function percentageOf(duplicatedLines, totalLines) {
179
+ return totalLines > 0 ? (duplicatedLines / totalLines) * 100 : 0;
180
+ }
181
+ /**
182
+ * Resolve the installed jscpd package, preferring the repository root.
183
+ *
184
+ * Consumers install jscpd as their own (optional) peer dependency, so the
185
+ * repository root is where the analyzer must find it; this module's own
186
+ * directory keeps the gate working for this repository's runs. jscpd 4
187
+ * resolves through its programmatic entry point, while jscpd 5 exposes no
188
+ * entry at all and resolves through its package manifest; when jscpd is
189
+ * installed nowhere, the manifest lookup throws Node's own not-found error.
190
+ */
191
+ function resolveJscpdEntry(repoRoot) {
192
+ try {
193
+ const entryPath = require.resolve("jscpd", { paths: [repoRoot, import.meta.dirname] });
194
+ const packageDir = packageDirOf(entryPath);
195
+ return { major: majorOf(packageDir), packageDir, entryPath };
196
+ }
197
+ catch {
198
+ // jscpd 5 has no package entry point; its manifest is the only anchor.
199
+ const manifestPath = require.resolve("jscpd/package.json", { paths: [repoRoot, import.meta.dirname] });
200
+ const packageDir = dirname(manifestPath);
201
+ return { major: majorOf(packageDir), packageDir, entryPath: manifestPath };
202
+ }
203
+ }
204
+ /** Read the engine generation from a jscpd package's manifest. */
205
+ function majorOf(packageDir) {
206
+ const manifest = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
207
+ return Number.parseInt(String(manifest.version), 10);
208
+ }
209
+ /** The directory of a package entry, walking up to the package manifest. */
210
+ function packageDirOf(entryPath) {
211
+ let directory = dirname(entryPath);
212
+ while (!existsSync(join(directory, "package.json")))
213
+ directory = dirname(directory);
214
+ return directory;
215
+ }
216
+ /**
217
+ * Analyze with jscpd 4's programmatic API.
218
+ *
219
+ * jscpd 4 publishes a per-file statistic, so files the globs matched but
220
+ * jscpd never analyzed fail the gate closed through `skippedSources`.
221
+ */
222
+ async function analyzeWithProgrammatic(installation, repoRoot, pattern, minTokens, matchedSources) {
223
+ const api = require(installation.entryPath);
224
+ const result = await api.detectClonesAndStatistic(duplicationOptions(repoRoot, pattern, minTokens));
225
+ const analyzedSources = Object.keys(result.statistic.formats.typescript?.sources ?? {})
226
+ .map((source) => relativeSource(repoRoot, source))
227
+ .sort();
228
+ const analyzed = new Set(analyzedSources);
229
+ return {
230
+ percentage: percentageOf(result.statistic.total.duplicatedLines, result.statistic.total.lines),
231
+ totalLines: result.statistic.total.lines,
232
+ duplicatedLines: result.statistic.total.duplicatedLines,
233
+ sources: result.statistic.total.sources,
234
+ skippedSources: matchedSources.filter((source) => !analyzed.has(source)),
235
+ cloneCount: result.clones.length,
236
+ clones: result.clones.map((clone) => mapProgrammaticClone(repoRoot, clone)),
237
+ };
238
+ }
239
+ /**
240
+ * Analyze with jscpd 5's binary through its JSON reporter.
241
+ *
242
+ * jscpd 5 is a self-contained Rust binary driven by `run-jscpd.js`, and its
243
+ * JSON report carries no per-file analysis record. The only files it drops
244
+ * from `statistics.total.sources` are those below the token floor, which
245
+ * cannot hold a clone of `minTokens` tokens, so the in-scope file set is the
246
+ * analyzed set and nothing in scope can be silently skipped.
247
+ */
248
+ function analyzeWithBinary(installation, repoRoot, pattern, minTokens, matchedSources) {
249
+ const outputDir = mkdtempSync(join(tmpdir(), "pm-ops-jscpd-"));
250
+ try {
251
+ const result = spawnSync(process.execPath, [
252
+ join(installation.packageDir, "run-jscpd.js"),
253
+ repoRoot,
254
+ "--pattern", pattern,
255
+ "--format", "typescript",
256
+ "--min-tokens", String(minTokens),
257
+ "--min-lines", "1",
258
+ "--max-lines", String(MAX_DUPLICATION_LINES),
259
+ "--max-size", MAX_DUPLICATION_SIZE,
260
+ "--ignore", DUPLICATION_IGNORES.join(","),
261
+ "--reporters", "json",
262
+ "--output", outputDir,
263
+ "--silent",
264
+ "--no-colors",
265
+ "--absolute",
266
+ "--no-gitignore",
267
+ ], { encoding: "utf8" });
268
+ if (result.status !== 0) {
269
+ throw new Error(`duplication: jscpd exited with status ${String(result.status)}: ${String(result.stderr)}`);
270
+ }
271
+ const rawReport = JSON.parse(readFileSync(join(outputDir, "jscpd-report.json"), "utf8"));
272
+ const reported = parseJscpdReport(rawReport);
273
+ return {
274
+ percentage: percentageOf(reported.statistics.total.duplicatedLines, reported.statistics.total.lines),
275
+ totalLines: reported.statistics.total.lines,
276
+ duplicatedLines: reported.statistics.total.duplicatedLines,
277
+ sources: matchedSources.length,
278
+ skippedSources: [],
279
+ cloneCount: reported.duplicates.length,
280
+ clones: reported.duplicates.map((clone) => mapReportedClone(repoRoot, clone)),
281
+ };
282
+ }
283
+ finally {
284
+ rmSync(outputDir, { recursive: true, force: true });
285
+ }
286
+ }
104
287
  /** Return the fail-closed diagnostic for an empty or partially analyzed scope. */
105
288
  export function duplicationGateDiagnostic(report) {
106
289
  if (report.sources === 0)
@@ -112,7 +295,11 @@ export function duplicationGateDiagnostic(report) {
112
295
  return undefined;
113
296
  }
114
297
  /**
115
- * Analyze a repository's TypeScript sources with jscpd's programmatic API.
298
+ * Analyze a repository's TypeScript sources with the installed jscpd major.
299
+ *
300
+ * jscpd 4 runs through its Node.js API and jscpd 5 through its Rust binary,
301
+ * and both are resolved from the repository root so a consumer's own jscpd
302
+ * dependency is the engine that answers.
116
303
  *
117
304
  * @param options - Repository root and optional source globs.
118
305
  * @returns Aggregate percentage and every clone pair found by jscpd.
@@ -121,21 +308,12 @@ export async function analyzeDuplication(options = {}) {
121
308
  const repoRoot = options.repoRoot ?? defaultRepoRoot;
122
309
  const pattern = combineGlobs(options.globs ?? DEFAULT_DUPLICATION_GLOBS);
123
310
  const minTokens = options.minTokens ?? 50;
124
- const result = await jscpd.detectClonesAndStatistic(duplicationOptions(repoRoot, pattern, minTokens));
125
311
  const matchedSources = globMatchedSources(repoRoot, pattern);
126
- const analyzedSources = Object.keys(result.statistic.formats.typescript?.sources ?? {})
127
- .map((source) => relativeSource(repoRoot, source))
128
- .sort();
129
- const analyzed = new Set(analyzedSources);
130
- return {
131
- percentage: result.statistic.total.percentage,
132
- totalLines: result.statistic.total.lines,
133
- duplicatedLines: result.statistic.total.duplicatedLines,
134
- sources: result.statistic.total.sources,
135
- skippedSources: matchedSources.filter((source) => !analyzed.has(source)),
136
- cloneCount: result.clones.length,
137
- clones: result.clones.map((clone) => mapClone(repoRoot, clone)),
138
- };
312
+ const installation = resolveJscpdEntry(repoRoot);
313
+ if (installation.major >= 5) {
314
+ return analyzeWithBinary(installation, repoRoot, pattern, minTokens, matchedSources);
315
+ }
316
+ return analyzeWithProgrammatic(installation, repoRoot, pattern, minTokens, matchedSources);
139
317
  }
140
318
  /**
141
319
  * Run the configured duplication threshold gate and print every clone pair.
@@ -1 +1 @@
1
- {"version":3,"file":"duplication.js","sourceRoot":"","sources":["../duplication.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"duplication.js","sourceRoot":"","sources":["../duplication.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2082,7 +2082,7 @@ function renderDocstringsMarkdown(result) {
2082
2082
  const defineExtension = (module) => module;
2083
2083
  export default defineExtension({
2084
2084
  name: "pm-ops",
2085
- version: "2026.9.18",
2085
+ version: "2026.9.26",
2086
2086
  activate(api) {
2087
2087
  if (typeof api.registerRenderer === "function") {
2088
2088
  // Derived from OPS_COMMAND_PATHS rather than restated. A literal copy is
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Executable entry that registers pm's merge drivers for a consumer's npm
3
+ * `prepare` hook, published as `pm-ops/merge-driver/prepare`.
4
+ *
5
+ * Consumer launchers must not import pm-ops: it is a devDependency, so an
6
+ * `npm install --omit=dev` checkout does not have it and a static import fails
7
+ * before any fallback can run. The canonical launcher
8
+ * (`templates/prepare-merge-driver.ts`) instead resolves this subpath and runs
9
+ * it in a child process. Running it performs {@link runPrepareMergeDriver} and
10
+ * reports its status as the process exit code.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=merge-driver-prepare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-driver-prepare.d.ts","sourceRoot":"","sources":["../merge-driver-prepare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Executable entry that registers pm's merge drivers for a consumer's npm
3
+ * `prepare` hook, published as `pm-ops/merge-driver/prepare`.
4
+ *
5
+ * Consumer launchers must not import pm-ops: it is a devDependency, so an
6
+ * `npm install --omit=dev` checkout does not have it and a static import fails
7
+ * before any fallback can run. The canonical launcher
8
+ * (`templates/prepare-merge-driver.ts`) instead resolves this subpath and runs
9
+ * it in a child process. Running it performs {@link runPrepareMergeDriver} and
10
+ * reports its status as the process exit code.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+ import { runPrepareMergeDriver } from "./merge-driver.js";
15
+ process.exitCode = runPrepareMergeDriver();
16
+ //# sourceMappingURL=merge-driver-prepare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-driver-prepare.js","sourceRoot":"","sources":["../merge-driver-prepare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,CAAC,QAAQ,GAAG,qBAAqB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shell-scan.d.ts","sourceRoot":"","sources":["../shell-scan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shell-scan.d.ts","sourceRoot":"","sources":["../shell-scan.ts"],"names":[],"mappings":"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"}
@@ -976,6 +976,40 @@ export function bashArrays(text) {
976
976
  }
977
977
  return arrays;
978
978
  }
979
+ /**
980
+ * Advance a shell word scan past the characters quoting itself consumes.
981
+ *
982
+ * A backslash outside single quotes consumes the character after it, and
983
+ * each quote character toggles its own state while the other quote kind is
984
+ * inactive; both loops that read shell words advance over exactly these
985
+ * characters and read everything else themselves.
986
+ *
987
+ * @param quotes - The mutable quote state of the word scan.
988
+ * @param line - The line being scanned.
989
+ * @param index - The scan index to advance from.
990
+ * @returns The first character quoting does not consume, and its index.
991
+ */
992
+ function nextBareChar(quotes, line, index) {
993
+ while (index < line.length) {
994
+ const char = line[index];
995
+ if (char === "\\" && !quotes.single) {
996
+ index += 2;
997
+ continue;
998
+ }
999
+ if (char === "'" && !quotes.double) {
1000
+ quotes.single = !quotes.single;
1001
+ index += 1;
1002
+ continue;
1003
+ }
1004
+ if (char === '"' && !quotes.single) {
1005
+ quotes.double = !quotes.double;
1006
+ index += 1;
1007
+ continue;
1008
+ }
1009
+ return { char, index };
1010
+ }
1011
+ return { char: undefined, index };
1012
+ }
979
1013
  /**
980
1014
  * Parse the run of assignments a line opens with, reading each value that is a
981
1015
  * fully literal shell word.
@@ -1013,28 +1047,19 @@ function leadingAssignments(line) {
1013
1047
  break;
1014
1048
  index += head[0].length;
1015
1049
  const start = index;
1016
- let single = false;
1017
- let double = false;
1050
+ const quotes = { single: false, double: false };
1018
1051
  let backtick = false;
1019
1052
  let substitutionDepth = 0;
1020
1053
  let readable = true;
1021
1054
  for (; index < line.length; index += 1) {
1022
- const char = line[index];
1023
- if (char === "\\" && !single) {
1024
- index += 1;
1025
- continue;
1026
- }
1027
- if (char === "'" && !double) {
1028
- single = !single;
1029
- continue;
1030
- }
1031
- if (char === '"' && !single) {
1032
- double = !double;
1033
- continue;
1034
- }
1055
+ const next = nextBareChar(quotes, line, index);
1056
+ index = next.index;
1057
+ if (next.char === undefined)
1058
+ break;
1059
+ const char = next.char;
1035
1060
  // Inside single quotes bash resolves nothing: no substitution opens, no
1036
1061
  // delimiter closes, no separator ends the word.
1037
- if (single)
1062
+ if (quotes.single)
1038
1063
  continue;
1039
1064
  if (char === "`") {
1040
1065
  backtick = !backtick;
@@ -1053,7 +1078,7 @@ function leadingAssignments(line) {
1053
1078
  // A parenthesis inside quotes is literal text of the substituted
1054
1079
  // command, not its delimiter. Counting one would close the
1055
1080
  // substitution early and put the rest of the word outside it.
1056
- if (!double) {
1081
+ if (!quotes.double) {
1057
1082
  if (char === "(")
1058
1083
  substitutionDepth += 1;
1059
1084
  else if (char === ")")
@@ -1064,14 +1089,14 @@ function leadingAssignments(line) {
1064
1089
  if (backtick)
1065
1090
  continue;
1066
1091
  // Inside double quotes a separator is part of the value.
1067
- if (double)
1092
+ if (quotes.double)
1068
1093
  continue;
1069
1094
  if (/\s/.test(char) || char === ";")
1070
1095
  break;
1071
1096
  if (/[()]/.test(char))
1072
1097
  readable = false;
1073
1098
  }
1074
- if (single || double || backtick || substitutionDepth > 0) {
1099
+ if (quotes.single || quotes.double || backtick || substitutionDepth > 0) {
1075
1100
  // The word's own extent is a guess, so neither its value nor what follows
1076
1101
  // it can be read.
1077
1102
  readable = false;
@@ -1517,27 +1542,17 @@ export function segmentShellLine(line) {
1517
1542
  */
1518
1543
  function unquotedText(line) {
1519
1544
  let bare = "";
1520
- let single = false;
1521
- let double = false;
1545
+ const quotes = { single: false, double: false };
1522
1546
  for (let index = 0; index < line.length; index += 1) {
1523
- const char = line[index];
1524
- if (char === "\\" && !single) {
1525
- index += 1;
1526
- continue;
1527
- }
1528
- if (char === "'" && !double) {
1529
- single = !single;
1530
- continue;
1531
- }
1532
- if (char === '"' && !single) {
1533
- double = !double;
1534
- continue;
1535
- }
1536
- if (single || double)
1547
+ const next = nextBareChar(quotes, line, index);
1548
+ index = next.index;
1549
+ if (next.char === undefined)
1550
+ break;
1551
+ if (quotes.single || quotes.double)
1537
1552
  continue;
1538
- if (char === "#" && (index === 0 || /\s/u.test(line[index - 1])))
1553
+ if (next.char === "#" && (next.index === 0 || /\s/u.test(line[next.index - 1])))
1539
1554
  break;
1540
- bare += char;
1555
+ bare += next.char;
1541
1556
  }
1542
1557
  return bare;
1543
1558
  }