enforce-node-protocol-usage.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. 'use strict';var _messages;function _defineProperty(obj, key, value) {if (key in obj) {Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });} else {obj[key] = value;}return obj;}
  2. var isCoreModule = require('is-core-module');var _require =
  3. require('../docsUrl'),docsUrl = _require['default'];
  4. var DO_PREFER_MESSAGE_ID = 'requireNodeProtocol';
  5. var NEVER_PREFER_MESSAGE_ID = 'forbidNodeProtocol';
  6. var messages = (_messages = {}, _defineProperty(_messages,
  7. DO_PREFER_MESSAGE_ID, 'Prefer `node:{{moduleName}}` over `{{moduleName}}`.'), _defineProperty(_messages,
  8. NEVER_PREFER_MESSAGE_ID, 'Prefer `{{moduleName}}` over `node:{{moduleName}}`.'), _messages);
  9. function replaceStringLiteral(
  10. fixer,
  11. node,
  12. text,
  13. relativeRangeStart,
  14. relativeRangeEnd)
  15. {
  16. var firstCharacterIndex = node.range[0] + 1;
  17. var start = Number.isInteger(relativeRangeEnd) ?
  18. relativeRangeStart + firstCharacterIndex :
  19. firstCharacterIndex;
  20. var end = Number.isInteger(relativeRangeEnd) ?
  21. relativeRangeEnd + firstCharacterIndex :
  22. node.range[1] - 1;
  23. return fixer.replaceTextRange([start, end], text);
  24. }
  25. function isStringLiteral(node) {
  26. return node && node.type === 'Literal' && typeof node.value === 'string';
  27. }
  28. function isStaticRequireWith1Param(node) {
  29. return !node.optional &&
  30. node.callee.type === 'Identifier' &&
  31. node.callee.name === 'require'
  32. // check for only 1 argument
  33. && node.arguments.length === 1 &&
  34. node.arguments[0] &&
  35. isStringLiteral(node.arguments[0]);
  36. }
  37. function checkAndReport(src, context) {
  38. // TODO use src.quasis[0].value.raw
  39. if (!src || src.type === 'TemplateLiteral') {return;}
  40. var moduleName = 'value' in src ? src.value : src.name;
  41. if (typeof moduleName !== 'string') {console.log(src, moduleName);}var
  42. settings = context.settings;
  43. var nodeVersion = settings && settings['import/node-version'];
  44. if (
  45. typeof nodeVersion !== 'undefined' && (
  46. typeof nodeVersion !== 'string' ||
  47. !/^[0-9]+\.[0-9]+\.[0-9]+$/.test(nodeVersion)))
  48. {
  49. throw new TypeError('`import/node-version` setting must be a string in the format "10.23.45" (a semver version, with no leading zero)');
  50. }
  51. if (context.options[0] === 'never') {
  52. if (!moduleName.startsWith('node:')) {return;}
  53. var actualModuleName = moduleName.slice(5);
  54. if (!isCoreModule(actualModuleName, nodeVersion || undefined)) {return;}
  55. context.report({
  56. node: src,
  57. message: messages[NEVER_PREFER_MESSAGE_ID],
  58. data: { moduleName: actualModuleName },
  59. /** @param {import('eslint').Rule.RuleFixer} fixer */
  60. fix: function () {function fix(fixer) {
  61. return replaceStringLiteral(fixer, src, '', 0, 5);
  62. }return fix;}() });
  63. } else if (context.options[0] === 'always') {
  64. if (
  65. moduleName.startsWith('node:') ||
  66. !isCoreModule(moduleName, nodeVersion || undefined) ||
  67. !isCoreModule('node:' + String(moduleName), nodeVersion || undefined))
  68. {
  69. return;
  70. }
  71. context.report({
  72. node: src,
  73. message: messages[DO_PREFER_MESSAGE_ID],
  74. data: { moduleName: moduleName },
  75. /** @param {import('eslint').Rule.RuleFixer} fixer */
  76. fix: function () {function fix(fixer) {
  77. return replaceStringLiteral(fixer, src, 'node:', 0, 0);
  78. }return fix;}() });
  79. } else if (typeof context.options[0] === 'undefined') {
  80. throw new Error('Missing option');
  81. } else {
  82. throw new Error('Unexpected option: ' + String(context.options[0]));
  83. }
  84. }
  85. /** @type {import('eslint').Rule.RuleModule} */
  86. module.exports = {
  87. meta: {
  88. type: 'suggestion',
  89. docs: {
  90. description: 'Enforce either using, or omitting, the `node:` protocol when importing Node.js builtin modules.',
  91. recommended: true,
  92. category: 'Static analysis',
  93. url: docsUrl('enforce-node-protocol-usage') },
  94. fixable: 'code',
  95. schema: {
  96. type: 'array',
  97. minItems: 1,
  98. maxItems: 1,
  99. items: [
  100. {
  101. 'enum': ['always', 'never'] }] },
  102. messages: messages },
  103. create: function () {function create(context) {
  104. return {
  105. CallExpression: function () {function CallExpression(node) {
  106. if (!isStaticRequireWith1Param(node)) {return;}
  107. var arg = node.arguments[0];
  108. return checkAndReport(arg, context);
  109. }return CallExpression;}(),
  110. ExportNamedDeclaration: function () {function ExportNamedDeclaration(node) {
  111. return checkAndReport(node.source, context);
  112. }return ExportNamedDeclaration;}(),
  113. ImportDeclaration: function () {function ImportDeclaration(node) {
  114. return checkAndReport(node.source, context);
  115. }return ImportDeclaration;}(),
  116. ImportExpression: function () {function ImportExpression(node) {
  117. if (!isStringLiteral(node.source)) {return;}
  118. return checkAndReport(node.source, context);
  119. }return ImportExpression;}() };
  120. }return create;}() };
  121. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9lbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UuanMiXSwibmFtZXMiOlsiaXNDb3JlTW9kdWxlIiwicmVxdWlyZSIsImRvY3NVcmwiLCJET19QUkVGRVJfTUVTU0FHRV9JRCIsIk5FVkVSX1BSRUZFUl9NRVNTQUdFX0lEIiwibWVzc2FnZXMiLCJyZXBsYWNlU3RyaW5nTGl0ZXJhbCIsImZpeGVyIiwibm9kZSIsInRleHQiLCJyZWxhdGl2ZVJhbmdlU3RhcnQiLCJyZWxhdGl2ZVJhbmdlRW5kIiwiZmlyc3RDaGFyYWN0ZXJJbmRleCIsInJhbmdlIiwic3RhcnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJlbmQiLCJyZXBsYWNlVGV4dFJhbmdlIiwiaXNTdHJpbmdMaXRlcmFsIiwidHlwZSIsInZhbHVlIiwiaXNTdGF0aWNSZXF1aXJlV2l0aDFQYXJhbSIsIm9wdGlvbmFsIiwiY2FsbGVlIiwibmFtZSIsImFyZ3VtZW50cyIsImxlbmd0aCIsImNoZWNrQW5kUmVwb3J0Iiwic3JjIiwiY29udGV4dCIsIm1vZHVsZU5hbWUiLCJjb25zb2xlIiwibG9nIiwic2V0dGluZ3MiLCJub2RlVmVyc2lvbiIsInRlc3QiLCJUeXBlRXJyb3IiLCJvcHRpb25zIiwic3RhcnRzV2l0aCIsImFjdHVhbE1vZHVsZU5hbWUiLCJzbGljZSIsInVuZGVmaW5lZCIsInJlcG9ydCIsIm1lc3NhZ2UiLCJkYXRhIiwiZml4IiwiRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJkZXNjcmlwdGlvbiIsInJlY29tbWVuZGVkIiwiY2F0ZWdvcnkiLCJ1cmwiLCJmaXhhYmxlIiwic2NoZW1hIiwibWluSXRlbXMiLCJtYXhJdGVtcyIsIml0ZW1zIiwiY3JlYXRlIiwiQ2FsbEV4cHJlc3Npb24iLCJhcmciLCJFeHBvcnROYW1lZERlY2xhcmF0aW9uIiwic291cmNlIiwiSW1wb3J0RGVjbGFyYXRpb24iLCJJbXBvcnRFeHByZXNzaW9uIl0sIm1h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b3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGlzQ29yZU1vZHVsZSA9IHJlcXVpcmUoJ2lzLWNvcmUtbW9kdWxlJyk7XG5jb25zdCB7IGRlZmF1bHQ6IGRvY3NVcmwgfSA9IHJlcXVpcmUoJy4uL2RvY3NVcmwnKTtcblxuY29uc3QgRE9fUFJFRkVSX01FU1NBR0VfSUQgPSAncmVxdWlyZU5vZGVQcm90b2NvbCc7XG5jb25zdCBORVZFUl9QUkVGRVJfTUVTU0FHRV9JRCA9ICdmb3JiaWROb2RlUHJvdG9jb2wnO1xuY29uc3QgbWVzc2FnZXMgPSB7XG4gIFtET19QUkVGRVJfTUVTU0FHRV9JRF06ICdQcmVmZXIgYG5vZGU6e3ttb2R1bGVOYW1lfX1gIG92ZXIgYHt7bW9kdWxlTmFtZX19YC4nLFxuICBbTkVWRVJfUFJFRkVSX01FU1NBR0VfSURdOiAnUHJlZmVyIGB7e21vZHVsZU5hbWV9fWAgb3ZlciBgbm9kZTp7e21vZHVsZU5hbWV9fWAuJyxcbn07XG5cbmZ1bmN0aW9uIHJlcGxhY2VTdHJpbmdMaXRlcmFsKFxuICBmaXhlcixcbiAgbm9kZSxcbiAgdGV4dCxcbiAgcmVsYXRpdmVSYW5nZVN0YXJ0LFxuICByZWxhdGl2ZVJhbmdlRW5kLFxuKSB7XG4gIGNvbnN0IGZpcnN0Q2hhcmFjdGVySW5kZXggPSBub2RlLnJhbmdlWzBdICsgMTtcbiAgY29uc3Qgc3RhcnQgPSBOdW1iZXIuaXNJbnRlZ2VyKHJlbGF0aXZlUmFuZ2VFbmQpXG4gICAgPyByZWxhdGl2ZVJhbmdlU3RhcnQgKyBmaXJzdENoYXJhY3RlckluZGV4XG4gICAgOiBmaXJzdENoYXJhY3RlckluZGV4O1xuICBjb25zdCBlbmQgPSBOdW1iZXIuaXNJbnRlZ2VyKHJlbGF0aXZlUmFuZ2VFbmQpXG4gICAgPyByZWxhdGl2ZVJhbmdlRW5kICsgZmlyc3RDaGFyYWN0ZXJJbmRleFxuICAgIDogbm9kZS5yYW5nZVsxXSAtIDE7XG5cbiAgcmV0dXJuIGZpeGVyLnJlcGxhY2VUZXh0UmFuZ2UoW3N0YXJ0LCBlbmRdLCB0ZXh0KTtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmdMaXRlcmFsKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUgJiYgbm9kZS50eXBlID09PSAnTGl0ZXJhbCcgJiYgdHlwZW9mIG5vZGUudmFsdWUgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc1N0YXRpY1JlcXVpcmVXaXRoMVBhcmFtKG5vZGUpIHtcbiAgcmV0dXJuICFub2RlLm9wdGlvbmFsXG4gICAgJiYgbm9kZS5jYWxsZWUudHlwZSA9PT0gJ0lkZW50aWZpZXInXG4gICAgJiYgbm9kZS5jYWxsZWUubmFtZSA9PT0gJ3JlcXVpcmUnXG4gICAgLy8gY2hlY2sgZm9yIG9ubHkgMSBhcmd1bWVudFxuICAgICYmIG5vZGUuYXJndW1lbnRzLmxlbmd0aCA9PT0gMVxuICAgICYmIG5vZGUuYXJndW1lbnRzWzBdXG4gICAgJiYgaXNTdHJpbmdMaXRlcmFsKG5vZGUuYXJndW1lbnRzWzBdKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tBbmRSZXBvcnQoc3JjLCBjb250ZXh0KSB7XG4gIC8vIFRPRE8gdXNlIHNyYy5xdWFzaXNbMF0udmFsdWUucmF3XG4gIGlmICghc3JjIHx8IHNyYy50eXBlID09PSAnVGVtcGxhdGVMaXRlcmFsJykgeyByZXR1cm47IH1cbiAgY29uc3QgbW9kdWxlTmFtZSA9ICd2YWx1ZScgaW4gc3JjID8gc3JjLnZhbHVlIDogc3JjLm5hbWU7XG4gIGlmICh0eXBlb2YgbW9kdWxlTmFtZSAhPT0gJ3N0cmluZycpIHsgY29uc29sZS5sb2coc3JjLCBtb2R1bGVOYW1lKTsgfVxuICBjb25zdCB7IHNldHRpbmdzIH0gPSBjb250ZXh0O1xuICBjb25zdCBub2RlVmVyc2lvbiA9IHNldHRpbmdzICYmIHNldHRpbmdzWydpbXBvcnQvbm9kZS12ZXJzaW9uJ107XG4gIGlmIChcbiAgICB0eXBlb2Ygbm9kZVZlcnNpb24gIT09ICd1bmRlZmluZWQnXG4gICAgJiYgKFxuICAgICAgdHlwZW9mIG5vZGVWZXJzaW9uICE9PSAnc3RyaW5nJ1xuICAgICAgfHwgISgvXlswLTldK1xcLlswLTldK1xcLlswLTldKyQvKS50ZXN0KG5vZGVWZXJzaW9uKVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGltcG9ydC9ub2RlLXZlcnNpb25gIHNldHRpbmcgbXVzdCBiZSBhIHN0cmluZyBpbiB0aGUgZm9ybWF0IFwiMTAuMjMuNDVcIiAoYSBzZW12ZXIgdmVyc2lvbiwgd2l0aCBubyBsZWFkaW5nIHplcm8pJyk7XG4gIH1cblxuICBpZiAoY29udGV4dC5vcHRpb25zWzBdID09PSAnbmV2ZXInKSB7XG4gICAgaWYgKCFtb2R1bGVOYW1lLnN0YXJ0c1dpdGgoJ25vZGU6JykpIHsgcmV0dXJuOyB9XG5cbiAgICBjb25zdCBhY3R1YWxNb2R1bGVOYW1lID0gbW9kdWxlTmFtZS5zbGljZSg1KTtcbiAgICBpZiAoIWlzQ29yZU1vZHVsZShhY3R1YWxNb2R1bGVOYW1lLCBub2RlVmVyc2lvbiB8fCB1bmRlZmluZWQpKSB7IHJldHVybjsgfVxuXG4gICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgbm9kZTogc3JjLFxuICAgICAgbWVzc2FnZTogbWVzc2FnZXNbTkVWRVJfUFJFRkVSX01FU1NBR0VfSURdLFxuICAgICAgZGF0YTogeyBtb2R1bGVOYW1lOiBhY3R1YWxNb2R1bGVOYW1lIH0sXG4gICAgICAvKiogQHBhcmFtIHtpbXBvcnQoJ2VzbGludCcpLlJ1bGUuUnVsZUZpeGVyfSBmaXhlciAqL1xuICAgICAgZml4KGZpeGVyKSB7XG4gICAgICAgIHJldHVybiByZXBsYWNlU3RyaW5nTGl0ZXJhbChmaXhlciwgc3JjLCAnJywgMCwgNSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKGNvbnRleHQub3B0aW9uc1swXSA9PT0gJ2Fsd2F5cycpIHtcbiAgICBpZiAoXG4gICAgICBtb2R1bGVOYW1lLnN0YXJ0c1dpdGgoJ25vZGU6JylcbiAgICAgIHx8ICFpc0NvcmVNb2R1bGUobW9kdWxlTmFtZSwgbm9kZVZlcnNpb24gfHwgdW5kZWZpbmVkKVxuICAgICAgfHwgIWlzQ29yZU1vZHVsZShgbm9kZToke21vZHVsZU5hbWV9YCwgbm9kZVZlcnNpb24gfHwgdW5kZWZpbmVkKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgIG5vZGU6IHNyYyxcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2VzW0RPX1BSRUZFUl9NRVNTQUdFX0lEXSxcbiAgICAgIGRhdGE6IHsgbW9kdWxlTmFtZSB9LFxuICAgICAgLyoqIEBwYXJhbSB7aW1wb3J0KCdlc2xpbnQnKS5SdWxlLlJ1bGVGaXhlcn0gZml4ZXIgKi9cbiAgICAgIGZpeChmaXhlcikge1xuICAgICAgICByZXR1cm4gcmVwbGFjZVN0cmluZ0xpdGVyYWwoZml4ZXIsIHNyYywgJ25vZGU6JywgMCwgMCk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZXh0Lm9wdGlvbnNbMF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIG9wdGlvbicpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBvcHRpb246ICR7Y29udGV4dC5vcHRpb25zWzBdfWApO1xuICB9XG59XG5cbi8qKiBAdHlwZSB7aW1wb3J0KCdlc2xpbnQnKS5SdWxlLlJ1bGVNb2R1bGV9ICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbWV0YToge1xuICAgIHR5cGU6ICdzdWdnZXN0aW9uJyxcbiAgICBkb2NzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0VuZm9yY2UgZWl0aGVyIHVzaW5nLCBvciBvbWl0dGluZywgdGhlIGBub2RlOmAgcHJvdG9jb2wgd2hlbiBpbXBvcnRpbmcgTm9kZS5qcyBidWlsdGluIG1vZHVsZXMuJyxcbiAgICAgIHJlY29tbWVuZGVkOiB0cnVlLFxuICAgICAgY2F0ZWdvcnk6ICdTdGF0aWMgYW5hbHlzaXMnLFxuICAgICAgdXJsOiBkb2NzVXJsKCdlbmZvcmNlLW5vZGUtcHJvdG9jb2wtdXNhZ2UnKSxcbiAgICB9LFxuICAgIGZpeGFibGU6ICdjb2RlJyxcbiAgICBzY2hlbWE6IHtcbiAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICBtaW5JdGVtczogMSxcbiAgICAgIG1heEl0ZW1zOiAxLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGVudW06IFsnYWx3YXlzJywgJ25ldmVyJ10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0sXG4gICAgbWVzc2FnZXMsXG4gIH0sXG4gIGNyZWF0ZShjb250ZXh0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIENhbGxFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKCFpc1N0YXRpY1JlcXVpcmVXaXRoMVBhcmFtKG5vZGUpKSB7IHJldHVybjsgfVxuXG4gICAgICAgIGNvbnN0IGFyZyA9IG5vZGUuYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIHJldHVybiBjaGVja0FuZFJlcG9ydChhcmcsIGNvbnRleHQpO1xuICAgICAgfSxcbiAgICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICByZXR1cm4gY2hlY2tBbmRSZXBvcnQobm9kZS5zb3VyY2UsIGNvbnRleHQpO1xuICAgICAgfSxcbiAgICAgIEltcG9ydERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGNoZWNrQW5kUmVwb3J0KG5vZGUuc291cmNlLCBjb250ZXh0KTtcbiAgICAgIH0sXG4gICAgICBJbXBvcnRFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKCFpc1N0cmluZ0xpdGVyYWwobm9kZS5zb3VyY2UpKSB7IHJldHVybjsgfVxuXG4gICAgICAgIHJldHVybiBjaGVja0FuZFJlcG9ydChub2RlLnNvdXJjZSwgY29udGV4dCk7XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuIl19