eslint-plugin-imports-regulation 0.2.13 → 0.2.14

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.
@@ -13,6 +13,7 @@ type Options = [
13
13
  importsAddenda?: string[];
14
14
  preferTypeDeclarations?: boolean;
15
15
  inferTypeOnlyImports?: boolean;
16
+ maxLen?: number;
16
17
  }?
17
18
  ];
18
19
  declare const rule: TSESLint.RuleModule<MessageIds, Options>;
@@ -1,5 +1,7 @@
1
1
  const DEFAULT_BLANK_LINES_BETWEEN = 1;
2
2
  const DEFAULT_BLANK_LINES_AFTER = 2;
3
+ // A rule cannot read `max-len`'s options, so this is its default.
4
+ const DEFAULT_MAX_LEN = 80;
3
5
  // The order, as written. The blank line falls between 1 and 2 — nowhere else.
4
6
  const EXTERNAL_TYPE = 0;
5
7
  const INTERNAL_TYPE = 2;
@@ -58,6 +60,8 @@ const rule = {
58
60
  preferTypeDeclarations: { type: 'boolean' },
59
61
  // Mark bindings that scope analysis shows are only ever used in type positions.
60
62
  inferTypeOnlyImports: { type: 'boolean' },
63
+ // The longest line a fix may write when it gathers names; lines as written are left alone.
64
+ maxLen: { type: 'integer', minimum: 1 },
61
65
  },
62
66
  additionalProperties: false,
63
67
  },
@@ -90,6 +94,7 @@ const rule = {
90
94
  const addenda = (options?.importsAddenda ?? []).map(lineGlobToRegExp);
91
95
  const preferTypeDeclarations = options?.preferTypeDeclarations ?? true;
92
96
  const inferTypeOnlyImports = options?.inferTypeOnlyImports ?? true;
97
+ const maxLen = options?.maxLen ?? DEFAULT_MAX_LEN;
93
98
  const eol = BREAK.exec(source.text)?.[0] ?? '\n';
94
99
  const originOf = (path) => {
95
100
  for (const { test, group } of patterns)
@@ -352,8 +357,7 @@ const rule = {
352
357
  return fixer.replaceTextRange(range, rejoin(range, named, [...types, ...values], specifier => source.getText(specifier)));
353
358
  }
354
359
  const { indent, closeIndent, trailingComma } = shapeOf(range, named);
355
- const line = (group) => `${indent}${group.map(specifier => source.getText(specifier)).join(', ')}`;
356
- const text = `${line(types)},${eol}${line(values)}${trailingComma ? ',' : ''}`;
360
+ const text = stacked(named, indent, trailingComma).join(eol);
357
361
  return fixer.replaceTextRange(range, `${eol}${text}${eol}${closeIndent}`);
358
362
  },
359
363
  });
@@ -369,6 +373,31 @@ const rule = {
369
373
  fix: fixer => fixer.replaceTextRange(range, rejoin(range, named, [...values, ...types], specifier => source.getText(specifier))),
370
374
  });
371
375
  };
376
+ const isTypeSpecifier = (specifier) => (specifier.type === 'ImportSpecifier' ? specifier.importKind : specifier.exportKind) === 'type';
377
+ /** Names packed greedily into lines within `maxLen`, every line but the last ending in a comma. */
378
+ const pack = (specifiers, indent, comma) => {
379
+ const lines = [];
380
+ let line = '';
381
+ for (const specifier of specifiers) {
382
+ const text = source.getText(specifier);
383
+ const joined = line ? `${line}, ${text}` : text;
384
+ if (line && indent.length + joined.length + 1 > maxLen) {
385
+ lines.push(line);
386
+ line = text;
387
+ }
388
+ else
389
+ line = joined;
390
+ }
391
+ if (line)
392
+ lines.push(line);
393
+ return lines.map((text, i) => `${indent}${text}${i < lines.length - 1 || comma ? ',' : ''}`);
394
+ };
395
+ /** Types' lines above the values', since a line holding both would read as one list. */
396
+ const stacked = (specifiers, indent, trailingComma) => {
397
+ const types = specifiers.filter(isTypeSpecifier);
398
+ const values = specifiers.filter(specifier => !isTypeSpecifier(specifier));
399
+ return [...pack(types, indent, values.length > 0 || trailingComma), ...pack(values, indent, trailingComma)];
400
+ };
372
401
  const checkBraces = (node, specifiers) => {
373
402
  const first = specifiers[0];
374
403
  const last = specifiers[specifiers.length - 1];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-imports-regulation",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
4
4
  "description": "Order imports: external type-only, external, blank line, internal type-only, internal — with type specifiers last inside each import.",
5
5
  "author": "Robert Sandiford",
6
6
  "type": "module",