import-index.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. 'use strict';
  2. const {STATIC_REQUIRE_SELECTOR} = require('./selectors/index.js');
  3. const MESSAGE_ID = 'import-index';
  4. const messages = {
  5. [MESSAGE_ID]: 'Do not reference the index file directly..',
  6. };
  7. const regexp = /^(?<package>@.*?\/.*?|[./]+?.*?)\/(?:\.|(?:index(?:\.js)?))?$/;
  8. const isImportingIndex = value => regexp.test(value);
  9. const normalize = value => value.replace(regexp, '$<package>');
  10. const importIndex = (context, node, argument) => {
  11. if (argument && isImportingIndex(argument.value)) {
  12. return {
  13. node,
  14. messageId: MESSAGE_ID,
  15. fix: fixer => fixer.replaceText(argument, `'${normalize(argument.value)}'`),
  16. };
  17. }
  18. };
  19. /** @param {import('eslint').Rule.RuleContext} context */
  20. const create = context => {
  21. const options = context.options[0] || {};
  22. const rules = {
  23. [STATIC_REQUIRE_SELECTOR]: node => importIndex(context, node, node.arguments[0]),
  24. };
  25. if (!options.ignoreImports) {
  26. rules.ImportDeclaration = node => importIndex(context, node, node.source);
  27. }
  28. return rules;
  29. };
  30. const schema = [
  31. {
  32. type: 'object',
  33. additionalProperties: false,
  34. properties: {
  35. ignoreImports: {
  36. type: 'boolean',
  37. default: false,
  38. },
  39. },
  40. },
  41. ];
  42. /** @type {import('eslint').Rule.RuleModule} */
  43. module.exports = {
  44. create,
  45. meta: {
  46. type: 'suggestion',
  47. docs: {
  48. description: 'Enforce importing index files with `.`.',
  49. },
  50. fixable: 'code',
  51. schema,
  52. messages,
  53. },
  54. };