apotheke 0.1.4 → 0.1.6

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/cli.js CHANGED
@@ -312,7 +312,29 @@ function sortNamedImports(node) {
312
312
  }
313
313
 
314
314
  // src/format.ts
315
- function collectOrphanSegments(source, imports) {
315
+ function printedHeaders(config) {
316
+ return /* @__PURE__ */ new Set([...config.groups.map((group) => `// ${group.name}`), `// ${OTHERS_GROUP}`]);
317
+ }
318
+ function isStrandedHeaders(segment, headers) {
319
+ const lines = segment.split("\n").filter((line) => line.trim() !== "");
320
+ return lines.length > 0 && lines.every((line) => headers.has(line.trim()));
321
+ }
322
+ function strandedHeaderStart(source, importStart, headers) {
323
+ let start;
324
+ let lineEnd = source.lastIndexOf("\n", importStart - 1);
325
+ while (lineEnd > -1) {
326
+ const lineStart = source.lastIndexOf("\n", lineEnd - 1) + 1;
327
+ const line = source.slice(lineStart, lineEnd).trim();
328
+ if (line !== "") {
329
+ if (!headers.has(line)) break;
330
+ start = lineStart;
331
+ }
332
+ if (lineStart === 0) break;
333
+ lineEnd = lineStart - 1;
334
+ }
335
+ return start;
336
+ }
337
+ function collectOrphanSegments(source, imports, headers) {
316
338
  const orphans = [];
317
339
  for (let i = 0; i < imports.length - 1; i++) {
318
340
  const gapStart = imports[i].end;
@@ -321,7 +343,7 @@ function collectOrphanSegments(source, imports) {
321
343
  const commentStart = imports[i + 1].attachedCommentStart;
322
344
  const cut = commentStart !== void 0 && commentStart >= gapStart && commentStart < gapEnd ? commentStart : gapEnd;
323
345
  const trimmed = source.slice(gapStart, cut).trim();
324
- if (trimmed) orphans.push(trimmed);
346
+ if (trimmed && !isStrandedHeaders(trimmed, headers)) orphans.push(trimmed);
325
347
  }
326
348
  return orphans;
327
349
  }
@@ -357,7 +379,8 @@ function buildBlocks(imports, config, options) {
357
379
  function formatImports(source, config, options = {}) {
358
380
  const imports = parseImports(source);
359
381
  if (imports.length === 0) return source;
360
- const orphans = collectOrphanSegments(source, imports);
382
+ const headers = printedHeaders(config);
383
+ const orphans = collectOrphanSegments(source, imports, headers);
361
384
  const clean = imports.map((n) => ({ ...n, attachedCommentStart: void 0 }));
362
385
  const deduped = deduplicateImports(clean);
363
386
  const sorted = deduped.map(sortNamedImports);
@@ -370,6 +393,7 @@ function formatImports(source, config, options = {}) {
370
393
  if (firstImport.attachedCommentStart !== void 0) {
371
394
  regionStart = source.lastIndexOf("\n", firstImport.attachedCommentStart) + 1;
372
395
  }
396
+ regionStart = strandedHeaderStart(source, regionStart, headers) ?? regionStart;
373
397
  let regionEnd = lastImport.end;
374
398
  if (source[regionEnd] === "\n") regionEnd++;
375
399
  const before = source.slice(0, regionStart);
package/dist/index.js CHANGED
@@ -309,7 +309,29 @@ function sortNamedImports(node) {
309
309
  }
310
310
 
311
311
  // src/format.ts
312
- function collectOrphanSegments(source, imports) {
312
+ function printedHeaders(config) {
313
+ return /* @__PURE__ */ new Set([...config.groups.map((group) => `// ${group.name}`), `// ${OTHERS_GROUP}`]);
314
+ }
315
+ function isStrandedHeaders(segment, headers) {
316
+ const lines = segment.split("\n").filter((line) => line.trim() !== "");
317
+ return lines.length > 0 && lines.every((line) => headers.has(line.trim()));
318
+ }
319
+ function strandedHeaderStart(source, importStart, headers) {
320
+ let start;
321
+ let lineEnd = source.lastIndexOf("\n", importStart - 1);
322
+ while (lineEnd > -1) {
323
+ const lineStart = source.lastIndexOf("\n", lineEnd - 1) + 1;
324
+ const line = source.slice(lineStart, lineEnd).trim();
325
+ if (line !== "") {
326
+ if (!headers.has(line)) break;
327
+ start = lineStart;
328
+ }
329
+ if (lineStart === 0) break;
330
+ lineEnd = lineStart - 1;
331
+ }
332
+ return start;
333
+ }
334
+ function collectOrphanSegments(source, imports, headers) {
313
335
  const orphans = [];
314
336
  for (let i = 0; i < imports.length - 1; i++) {
315
337
  const gapStart = imports[i].end;
@@ -318,7 +340,7 @@ function collectOrphanSegments(source, imports) {
318
340
  const commentStart = imports[i + 1].attachedCommentStart;
319
341
  const cut = commentStart !== void 0 && commentStart >= gapStart && commentStart < gapEnd ? commentStart : gapEnd;
320
342
  const trimmed = source.slice(gapStart, cut).trim();
321
- if (trimmed) orphans.push(trimmed);
343
+ if (trimmed && !isStrandedHeaders(trimmed, headers)) orphans.push(trimmed);
322
344
  }
323
345
  return orphans;
324
346
  }
@@ -354,7 +376,8 @@ function buildBlocks(imports, config, options) {
354
376
  function formatImports(source, config, options = {}) {
355
377
  const imports = parseImports(source);
356
378
  if (imports.length === 0) return source;
357
- const orphans = collectOrphanSegments(source, imports);
379
+ const headers = printedHeaders(config);
380
+ const orphans = collectOrphanSegments(source, imports, headers);
358
381
  const clean = imports.map((n) => ({ ...n, attachedCommentStart: void 0 }));
359
382
  const deduped = deduplicateImports(clean);
360
383
  const sorted = deduped.map(sortNamedImports);
@@ -367,6 +390,7 @@ function formatImports(source, config, options = {}) {
367
390
  if (firstImport.attachedCommentStart !== void 0) {
368
391
  regionStart = source.lastIndexOf("\n", firstImport.attachedCommentStart) + 1;
369
392
  }
393
+ regionStart = strandedHeaderStart(source, regionStart, headers) ?? regionStart;
370
394
  let regionEnd = lastImport.end;
371
395
  if (source[regionEnd] === "\n") regionEnd++;
372
396
  const before = source.slice(0, regionStart);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apotheke",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Prettier for imports — deterministic import organization as a Prettier plugin or CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",