From 1297ab6d91679a68b4c37834dc303a741cd13844 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 21 Mar 2022 01:26:15 -0500 Subject: [PATCH] fix: detect ESLint >= 8 and tell the user about linter-eslint-node (#1464) Co-Authored-By: Tony Brix --- README.md | 6 +- dist/worker-helpers.js | 2 +- package.json | 9 ++- .../lib/node_modules/eslint/lib/api.js | 2 +- .../node_modules/eslint/lib/api.js | 1 + .../node_modules/eslint/package.json | 1 + .../eslint/node_modules/eslint/lib/api.js | 2 +- .../node_modules/eslint/lib/api.js | 2 +- spec/worker-helpers-spec.js | 17 ++++-- src/helpers.js | 60 ++++++++++++++++++- src/main.js | 17 ++++++ src/worker-helpers.js | 40 ++++++++++++- src/worker.js | 6 +- 13 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 spec/fixtures/incompatible-eslint/node_modules/eslint/lib/api.js create mode 100644 spec/fixtures/incompatible-eslint/node_modules/eslint/package.json diff --git a/README.md b/README.md index c2e9f3b4..72b0d4f7 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,11 @@ [![Dependency Status](https://david-dm.org/AtomLinter/linter-eslint.svg)](https://david-dm.org/AtomLinter/linter-eslint) This linter plugin for [Linter](https://github.com/AtomLinter/Linter) provides -an interface to [eslint](http://eslint.org). It will be used with files that +an interface to [eslint](http://eslint.org) versions 7 and below. It will be used with files that have the "JavaScript" syntax. +**For linting in projects that use ESLint v8 and above, install [linter-eslint-node](https://atom.io/packages/linter-eslint-node).** + ## Installation ```ShellSession @@ -24,7 +26,7 @@ This package requires an `eslint` of at least v1.0.0. If you do not have the `linter` package installed, it will be installed -for you. If you are using an alternative `linter-*` consumer, +for you. If you are using an alternative `linter-*` consumer, the `linter` package can be disabled. If you wish to lint files in JavaScript-derivative languages (like Typescript, diff --git a/dist/worker-helpers.js b/dist/worker-helpers.js index 68bcdf17..41a15d90 100644 --- a/dist/worker-helpers.js +++ b/dist/worker-helpers.js @@ -332,4 +332,4 @@ function getRules(cliEngine) { function didRulesChange(currentRules, newRules) { return !(currentRules.size === newRules.size && Array.from(currentRules.keys()).every(ruleId => newRules.has(ruleId))); } -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy93b3JrZXItaGVscGVycy5qcyJdLCJuYW1lcyI6WyJDYWNoZSIsIkVTTElOVF9MT0NBTF9QQVRIIiwiUGF0aCIsIm5vcm1hbGl6ZSIsImpvaW4iLCJfX2Rpcm5hbWUiLCJOT0RFX1BSRUZJWF9QQVRIIiwiTEFTVF9NT0RVTEVTX1BBVEgiLCJjbGVhblBhdGgiLCJwYXRoIiwiZnMiLCJnZXROb2RlUHJlZml4UGF0aCIsIm5wbUNvbW1hbmQiLCJwcm9jZXNzIiwicGxhdGZvcm0iLCJDaGlsZFByb2Nlc3MiLCJzcGF3blN5bmMiLCJlbnYiLCJQQVRIIiwib3V0cHV0IiwidG9TdHJpbmciLCJ0cmltIiwiZSIsImVyck1zZyIsIkVycm9yIiwiaXNEaXJlY3RvcnkiLCJkaXJQYXRoIiwiaXNEaXIiLCJzdGF0U3luYyIsImZhbGxiYWNrRm9yR2xvYmFsRXJyb3JUaHJvd24iLCJmaW5kRVNMaW50RGlyZWN0b3J5IiwibW9kdWxlc0RpciIsImNvbmZpZyIsInByb2plY3RQYXRoIiwiZmFsbGJhY2tGb3JHbG9iYWwiLCJlc2xpbnREaXIiLCJsb2NhdGlvblR5cGUiLCJnbG9iYWwiLCJ1c2VHbG9iYWxFc2xpbnQiLCJjb25maWdHbG9iYWwiLCJnbG9iYWxOb2RlUGF0aCIsInByZWZpeFBhdGgiLCJhZHZhbmNlZCIsImxvY2FsTm9kZU1vZHVsZXMiLCJpc0Fic29sdXRlIiwidHlwZSIsImNvbnNvbGUiLCJlcnJvciIsImdldEVTTGludEZyb21EaXJlY3RvcnkiLCJFU0xpbnREaXJlY3RvcnkiLCJyZXF1aXJlIiwiY29kZSIsInJlZnJlc2hNb2R1bGVzUGF0aCIsIk5PREVfUEFUSCIsIk1vZHVsZSIsIl9pbml0UGF0aHMiLCJnZXRFU0xpbnRJbnN0YW5jZSIsImZpbGVEaXIiLCJkaXJuYW1lIiwibG9nIiwiYXJncyIsIm9iaiIsImxlbmd0aCIsInN0ciIsIkpTT04iLCJzdHJpbmdpZnkiLCJVdGlsIiwiaW5zcGVjdCIsImVtaXQiLCJnZXRDb25maWdGb3JGaWxlIiwiZXNsaW50IiwiZmlsZVBhdGgiLCJjbGkiLCJDTElFbmdpbmUiLCJnZXRSZWxhdGl2ZVBhdGgiLCJpZ25vcmVGaWxlIiwiZGlzYWJsZUVzbGludElnbm9yZSIsImlnbm9yZURpciIsImNoZGlyIiwicmVsYXRpdmUiLCJiYXNlbmFtZSIsImdldENMSUVuZ2luZU9wdGlvbnMiLCJydWxlcyIsImZpbGVDb25maWciLCJjbGlFbmdpbmVDb25maWciLCJpZ25vcmUiLCJmaXgiLCJydWxlUGF0aHMiLCJlc2xpbnRSdWxlc0RpcnMiLCJtYXAiLCJydWxlc0RpciIsImZpbHRlciIsImVzbGludHJjUGF0aCIsImNvbmZpZ0ZpbGUiLCJnZXRSdWxlcyIsImNsaUVuZ2luZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImxpbnRlciIsIk1hcCIsImRpZFJ1bGVzQ2hhbmdlIiwiY3VycmVudFJ1bGVzIiwibmV3UnVsZXMiLCJzaXplIiwiQXJyYXkiLCJmcm9tIiwia2V5cyIsImV2ZXJ5IiwicnVsZUlkIiwiaGFzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBUkE7QUFVQSxNQUFNQSxLQUFLLEdBQUc7QUFDWkMsRUFBQUEsaUJBQWlCLEVBQUVDLGNBQUtDLFNBQUwsQ0FBZUQsY0FBS0UsSUFBTCxDQUFVQyxTQUFWLEVBQXFCLElBQXJCLEVBQTJCLGNBQTNCLEVBQTJDLFFBQTNDLENBQWYsQ0FEUDtBQUVaQyxFQUFBQSxnQkFBZ0IsRUFBRSxJQUZOO0FBR1pDLEVBQUFBLGlCQUFpQixFQUFFO0FBSFAsQ0FBZDtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxNQUFNQyxTQUFTLEdBQUlDLElBQUQsSUFBV0EsSUFBSSxHQUFHLHlCQUFXQyxnQkFBR1AsU0FBSCxDQUFhTSxJQUFiLENBQVgsQ0FBSCxHQUFvQyxFQUFyRTtBQUVBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU0Us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cGF0aCdcbmltcG9ydCBVdGlsIGZyb20gJ3V0aWwnXG5pbXBvcnQgZnMgZnJvbSAnZnMtcGx1cydcbmltcG9ydCBDaGlsZFByb2Nlc3MgZnJvbSAnY2hpbGRfcHJvY2VzcydcbmltcG9ydCByZXNvbHZlRW52IGZyb20gJ3Jlc29sdmUtZW52J1xuaW1wb3J0IHsgZmluZENhY2hlZCB9IGZyb20gJ2F0b20tbGludGVyJ1xuaW1wb3J0IGdldFBhdGggZnJvbSAnY29uc2lzdGVudC1wYXRoJ1xuXG5jb25zdCBDYWNoZSA9IHtcbiAgRVNMSU5UX0xPQ0FMX1BBVEg6IFBhdGgubm9ybWFsaXplKFBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdub2RlX21vZHVsZXMnLCAnZXNsaW50JykpLFxuICBOT0RFX1BSRUZJWF9QQVRIOiBudWxsLFxuICBMQVNUX01PRFVMRVNfUEFUSDogbnVsbFxufVxuXG4vKipcbiAqIFRha2VzIGEgcGF0aCBhbmQgdHJhbnNsYXRlcyBgfmAgdG8gdGhlIHVzZXIncyBob21lIGRpcmVjdG9yeSwgYW5kIHJlcGxhY2VzXG4gKiBhbGwgZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpdGggdGhlaXIgdmFsdWUuXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gcmVtb3ZlIFwic3RyYW5nZW5lc3NcIiBmcm9tXG4gKiBAcmV0dXJuIHtzdHJpbmd9ICAgICAgVGhlIGNsZWFuZWQgcGF0aFxuICovXG5jb25zdCBjbGVhblBhdGggPSAocGF0aCkgPT4gKHBhdGggPyByZXNvbHZlRW52KGZzLm5vcm1hbGl6ZShwYXRoKSkgOiAnJylcblxuLyoqXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Tm9kZVByZWZpeFBhdGgoKSB7XG4gIGlmIChDYWNoZS5OT0RFX1BSRUZJWF9QQVRIID09PSBudWxsKSB7XG4gICAgY29uc3QgbnBtQ29tbWFuZCA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicgPyAnbnBtLmNtZCcgOiAnbnBtJ1xuICAgIHRyeSB7XG4gICAgICBDYWNoZS5OT0RFX1BSRUZJWF9QQVRIID0gQ2hpbGRQcm9jZXNzLnNwYXduU3luYyhucG1Db21tYW5kLCBbJ2dldCcsICdwcmVmaXgnXSwge1xuICAgICAgICBlbnY6IHsgLi4ucHJvY2Vzcy5lbnYsIFBBVEg6IGdldFBhdGgoKSB9XG4gICAgICB9KS5vdXRwdXRbMV0udG9TdHJpbmcoKS50cmltKClcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCBlcnJNc2cgPSAnVW5hYmxlIHRvIGV4ZWN1dGUgYG5wbSBnZXQgcHJlZml4YC4gUGxlYXNlIG1ha2Ugc3VyZSAnXG4gICAgICAgICsgJ0F0b20gaXMgZ2V0dGluZyAkUEFUSCBjb3JyZWN0bHkuJ1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIENhY2hlLk5PREVfUFJFRklYX1BBVEhcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlyUGF0aFxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzRGlyZWN0b3J5KGRpclBhdGgpIHtcbiAgbGV0IGlzRGlyXG4gIHRyeSB7XG4gICAgaXNEaXIgPSBmcy5zdGF0U3luYyhkaXJQYXRoKS5pc0RpcmVjdG9yeSgpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpc0RpciA9IGZhbHNlXG4gIH1cbiAgcmV0dXJuIGlzRGlyXG59XG5cbmxldCBmYWxsYmFja0Zvckdsb2JhbEVycm9yVGhyb3duID0gZmFsc2VcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlc0RpclxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2plY3RQYXRoXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZhbGxiYWNrRm9yR2xvYmFsXG4gKiBAcmV0dXJucyB7eyBwYXRoOiBzdHJpbmcsIHR5cGU6ICdsb2NhbCBwcm9qZWN0JyB8ICdnbG9iYWwnIHwgJ2FkdmFuY2VkIHNwZWNpZmllZCcgfCAnYnVuZGxlZCBmYWxsYmFjaycgfX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRFU0xpbnREaXJlY3RvcnkobW9kdWxlc0RpciwgY29uZmlnLCBwcm9qZWN0UGF0aCwgZmFsbGJhY2tGb3JHbG9iYWwgPSBmYWxzZSkge1xuICBsZXQgZXNsaW50RGlyID0gbnVsbFxuICBsZXQgbG9jYXRpb25UeXBlID0gbnVsbFxuICBpZiAoY29uZmlnLmdsb2JhbC51c2VHbG9iYWxFc2xpbnQgJiYgIWZhbGxiYWNrRm9yR2xvYmFsKSB7XG4gICAgbG9jYXRpb25UeXBlID0gJ2dsb2JhbCdcbiAgICBjb25zdCBjb25maWdHbG9iYWwgPSBjbGVhblBhdGgoY29uZmlnLmdsb2JhbC5nbG9iYWxOb2RlUGF0aClcbiAgICBjb25zdCBwcmVmaXhQYXRoID0gY29uZmlnR2xvYmFsIHx8IGdldE5vZGVQcmVmaXhQYXRoKClcbiAgICAvLyBOUE0gb24gV2luZG93cyBhbmQgWWFybiBvbiBhbGwgcGxhdGZvcm1zXG4gICAgZXNsaW50RGlyID0gUGF0aC5qb2luKHByZWZpeFBhdGgsICdub2RlX21vZHVsZXMnLCAnZXNsaW50JylcbiAgICBpZiAoIWlzRGlyZWN0b3J5KGVzbGludERpcikpIHtcbiAgICAgIC8vIE5QTSBvbiBwbGF0Zm9ybXMgb3RoZXIgdGhhbiBXaW5kb3dzXG4gICAgICBlc2xpbnREaXIgPSBQYXRoLmpvaW4ocHJlZml4UGF0aCwgJ2xpYicsICdub2RlX21vZHVsZXMnLCAnZXNsaW50JylcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWNvbmZpZy5hZHZhbmNlZC5sb2NhbE5vZGVNb2R1bGVzKSB7XG4gICAgbG9jYXRpb25UeXBlID0gJ2xvY2FsIHByb2plY3QnXG4gICAgZXNsaW50RGlyID0gUGF0aC5qb2luKG1vZHVsZXNEaXIgfHwgJycsICdlc2xpbnQnKVxuICB9IGVsc2UgaWYgKFBhdGguaXNBYnNvbHV0ZShjbGVhblBhdGgoY29uZmlnLmFkdmFuY2VkLmxvY2FsTm9kZU1vZHVsZXMpKSkge1xuICAgIGxvY2F0aW9uVHlwZSA9ICdhZHZhbmNlZCBzcGVjaWZpZWQnXG4gICAgZXNsaW50RGlyID0gUGF0aC5qb2luKGNsZWFuUGF0aChjb25maWcuYWR2YW5jZWQubG9jYWxOb2RlTW9kdWxlcyksICdlc2xpbnQnKVxuICB9IGVsc2Uge1xuICAgIGxvY2F0aW9uVHlwZSA9ICdhZHZhbmNlZCBzcGVjaWZpZWQnXG4gICAgZXNsaW50RGlyID0gUGF0aC5qb2luKHByb2plY3RQYXRoIHx8ICcnLCBjbGVhblBhdGgoY29uZmlnLmFkdmFuY2VkLmxvY2FsTm9kZU1vZHVsZXMpLCAnZXNsaW50JylcbiAgfVxuXG4gIGlmIChpc0RpcmVjdG9yeShlc2xpbnREaXIpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGg6IGVzbGludERpcixcbiAgICAgIHR5cGU6IGxvY2F0aW9uVHlwZSxcbiAgICB9XG4gIH1cblxuICBpZiAoY29uZmlnLmdsb2JhbC51c2VHbG9iYWxFc2xpbnQgJiYgIWZhbGxiYWNrRm9yR2xvYmFsKSB7XG4gICAgaWYgKCFmYWxsYmFja0Zvckdsb2JhbEVycm9yVGhyb3duKSB7XG4gICAgICAvLyBUaHJvdyB0aGUgZXJyb3Igb25seSBvbmNlIHRvIHByZXZlbnQgcGVyZm9ybWFuY2UgaXNzdWVzXG4gICAgICBmYWxsYmFja0Zvckdsb2JhbEVycm9yVGhyb3duID0gdHJ1ZVxuICAgICAgY29uc29sZS5lcnJvcihgR2xvYmFsIEVTTGludCBpcyBub3QgZm91bmQsIGZhbGxpbmcgYmFjayB0byBvdGhlciBFc2xpbnQgaW5zdGFsbGF0aW9ucy4uLlxuICAgICAgICBQbGVhc2UgZW5zdXJlIHRoZSBnbG9iYWwgTm9kZSBwYXRoIGlzIHNldCBjb3JyZWN0bHkuXG4gICAgICAgIElmIHlvdSB3YW50ZWQgdG8gdXNlIGEgbG9jYWwgaW5zdGFsbGF0aW9uIG9mIEVzbGludCwgZGlzYWJsZSBHbG9iYWwgRXNsaW50IG9wdGlvbiBpbiB0aGUgbGludGVyLWVzbGludCBjb25maWcuYClcbiAgICB9XG4gICAgcmV0dXJuIGZpbmRFU0xpbnREaXJlY3RvcnkobW9kdWxlc0RpciwgY29uZmlnLCBwcm9qZWN0UGF0aCwgdHJ1ZSlcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcGF0aDogQ2FjaGUuRVNMSU5UX0xPQ0FMX1BBVEgsXG4gICAgdHlwZTogJ2J1bmRsZWQgZmFsbGJhY2snLFxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IG1vZHVsZXNEaXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9qZWN0UGF0aFxuICogQHJldHVybnMge2ltcG9ydChcImVzbGludFwiKX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEVTTGludEZyb21EaXJlY3RvcnkobW9kdWxlc0RpciwgY29uZmlnLCBwcm9qZWN0UGF0aCkge1xuICBjb25zdCB7IHBhdGg6IEVTTGludERpcmVjdG9yeSB9ID0gZmluZEVTTGludERpcmVjdG9yeShtb2R1bGVzRGlyLCBjb25maWcsIHByb2plY3RQYXRoKVxuICB0cnkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZHluYW1pYy1yZXF1aXJlXG4gICAgcmV0dXJuIHJlcXVpcmUoRVNMaW50RGlyZWN0b3J5KVxuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGNvbmZpZy5nbG9iYWwudXNlR2xvYmFsRXNsaW50ICYmIGUuY29kZSA9PT0gJ01PRFVMRV9OT1RfRk9VTkQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VTTGludCBub3QgZm91bmQsIHRyeSByZXN0YXJ0aW5nIEF0b20gdG8gY2xlYXIgY2FjaGVzLicpXG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZHluYW1pYy1yZXF1aXJlXG4gICAgcmV0dXJuIHJlcXVpcmUoQ2FjaGUuRVNMSU5UX0xPQ0FMX1BBVEgpXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlc0RpclxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmcmVzaE1vZHVsZXNQYXRoKG1vZHVsZXNEaXIpIHtcbiAgaWYgKENhY2hlLkxBU1RfTU9EVUxFU19QQVRIICE9PSBtb2R1bGVzRGlyKSB7XG4gICAgQ2FjaGUuTEFTVF9NT0RVTEVTX1BBVEggPSBtb2R1bGVzRGlyXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9QQVRIID0gbW9kdWxlc0RpciB8fCAnJ1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgIHJlcXVpcmUoJ21vZHVsZScpLk1vZHVsZS5faW5pdFBhdGhzKClcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlRGlyXG4gKiBAcGFyYW0ge29iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdFBhdGhcbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJlc2xpbnRcIil9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFU0xpbnRJbnN0YW5jZShmaWxlRGlyLCBjb25maWcsIHByb2plY3RQYXRoKSB7XG4gIGNvbnN0IG1vZHVsZXNEaXIgPSBQYXRoLmRpcm5hbWUoZmluZENhY2hlZChmaWxlRGlyLCAnbm9kZV9tb2R1bGVzL2VzbGludCcpIHx8ICcnKVxuICByZWZyZXNoTW9kdWxlc1BhdGgobW9kdWxlc0RpcilcbiAgcmV0dXJuIGdldEVTTGludEZyb21EaXJlY3RvcnkobW9kdWxlc0RpciwgY29uZmlnLCBwcm9qZWN0UGF0aClcbn1cblxuLyoqXG4gKiBjb25zb2xlLmxvZ1xuICogQHBhcmFtICB7YW55fSBhcmdzXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9nKC4uLmFyZ3MpIHtcbiAgY29uc3Qgb2JqID0gYXJncy5sZW5ndGggPT09IDEgPyBhcmdzWzBdIDogYXJnc1xuICBsZXQgc3RyXG4gIHRyeSB7XG4gICAgc3RyID0gSlNPTi5zdHJpbmdpZnkob2JqKVxuICB9IGNhdGNoIChlKSB7XG4gICAgc3RyID0gVXRpbC5pbnNwZWN0KG9iailcbiAgfVxuXG4gIGVtaXQoJ2xvZycsIHN0cilcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcImVzbGludFwiKX0gZXNsaW50XG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZ0ZvckZpbGUoZXNsaW50LCBmaWxlUGF0aCkge1xuICBjb25zdCBjbGkgPSBuZXcgZXNsaW50LkNMSUVuZ2luZSgpXG4gIHRyeSB7XG4gICAgcmV0dXJuIGNsaS5nZXRDb25maWdGb3JGaWxlKGZpbGVQYXRoKVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gTm8gY29uZmlndXJhdGlvbiB3YXMgZm91bmRcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVEaXJcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2plY3RQYXRoXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVsYXRpdmVQYXRoKGZpbGVEaXIsIGZpbGVQYXRoLCBjb25maWcsIHByb2plY3RQYXRoKSB7XG4gIGNvbnN0IGlnbm9yZUZpbGUgPSBjb25maWcuYWR2YW5jZWQuZGlzYWJsZUVzbGludElnbm9yZSA/IG51bGwgOiBmaW5kQ2FjaGVkKGZpbGVEaXIsICcuZXNsaW50aWdub3JlJylcblxuICAvLyBJZiB3ZSBjYW4gZmluZCBhbiAuZXNsaW50aWdub3JlIGZpbGUsIHdlIGNhbiBzZXQgY3dkIHRoZXJlXG4gIC8vIChiZWNhdXNlIHRoZXkgYXJlIGV4cGVjdGVkIHRvIGJlIGF0IHRoZSBwcm9qZWN0IHJvb3QpXG4gIGlmIChpZ25vcmVGaWxlKSB7XG4gICAgY29uc3QgaWdub3JlRGlyID0gUGF0aC5kaXJuYW1lKGlnbm9yZUZpbGUpXG4gICAgcHJvY2Vzcy5jaGRpcihpZ25vcmVEaXIpXG4gICAgcmV0dXJuIFBhdGgucmVsYXRpdmUoaWdub3JlRGlyLCBmaWxlUGF0aClcbiAgfVxuICAvLyBPdGhlcndpc2UsIHdlJ2xsIHNldCB0aGUgY3dkIHRvIHRoZSBhdG9tIHByb2plY3Qgcm9vdCBhcyBsb25nIGFzIHRoYXQgZXhpc3RzXG4gIGlmIChwcm9qZWN0UGF0aCkge1xuICAgIHByb2Nlc3MuY2hkaXIocHJvamVjdFBhdGgpXG4gICAgcmV0dXJuIFBhdGgucmVsYXRpdmUocHJvamVjdFBhdGgsIGZpbGVQYXRoKVxuICB9XG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgdGhlIGZpbGUgbG9jYXRpb24gaXRzZWxmXG4gIHByb2Nlc3MuY2hkaXIoZmlsZURpcilcbiAgcmV0dXJuIFBhdGguYmFzZW5hbWUoZmlsZVBhdGgpXG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nW119IHJ1bGVzXG4gKiBAcGFyYW0ge29iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWxlQ29uZmlnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDTElFbmdpbmVPcHRpb25zKHR5cGUsIGNvbmZpZywgcnVsZXMsIGZpbGVQYXRoLCBmaWxlQ29uZmlnKSB7XG4gIGNvbnN0IGNsaUVuZ2luZUNvbmZpZyA9IHtcbiAgICBydWxlcyxcbiAgICBpZ25vcmU6ICFjb25maWcuYWR2YW5jZWQuZGlzYWJsZUVzbGludElnbm9yZSxcbiAgICBmaXg6IHR5cGUgPT09ICdmaXgnXG4gIH1cblxuICBjbGlFbmdpbmVDb25maWcucnVsZVBhdGhzID0gY29uZmlnLmFkdmFuY2VkLmVzbGludFJ1bGVzRGlycy5tYXAoKHBhdGgpID0+IHtcbiAgICBjb25zdCBydWxlc0RpciA9IGNsZWFuUGF0aChwYXRoKVxuICAgIGlmICghUGF0aC5pc0Fic29sdXRlKHJ1bGVzRGlyKSkge1xuICAgICAgcmV0dXJuIGZpbmRDYWNoZWQoUGF0aC5kaXJuYW1lKGZpbGVQYXRoKSwgcnVsZXNEaXIpXG4gICAgfVxuICAgIHJldHVybiBydWxlc0RpclxuICB9KS5maWx0ZXIoKHBhdGgpID0+IHBhdGgpXG5cbiAgaWYgKGZpbGVDb25maWcgPT09IG51bGwgJiYgY29uZmlnLmdsb2JhbC5lc2xpbnRyY1BhdGgpIHtcbiAgICAvLyBJZiB3ZSBkaWRuJ3QgZmluZCBhIGNvbmZpZ3VyYXRpb24gdXNlIHRoZSBmYWxsYmFjayBmcm9tIHRoZSBzZXR0aW5nc1xuICAgIGNsaUVuZ2luZUNvbmZpZy5jb25maWdGaWxlID0gY2xlYW5QYXRoKGNvbmZpZy5nbG9iYWwuZXNsaW50cmNQYXRoKVxuICB9XG5cbiAgcmV0dXJuIGNsaUVuZ2luZUNvbmZpZ1xufVxuXG4vKipcbiAqIEdldHMgdGhlIGxpc3Qgb2YgcnVsZXMgdXNlZCBmb3IgYSBsaW50IGpvYlxuICogQHBhcmFtICB7aW1wb3J0KFwiZXNsaW50XCIpLkNMSUVuZ2luZX0gY2xpRW5naW5lIFRoZSBDTElFbmdpbmUgaW5zdGFuY2UgdXNlZCBmb3IgdGhlIGxpbnQgam9iXG4gKiBAcmV0dXJuIHtNYXB9ICAgICAgICAgICAgICBBIE1hcCBvZiB0aGUgcnVsZXMgdXNlZCwgcnVsZSBuYW1lcyBhcyBrZXlzLCBydWxlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzIGFzIHRoZSBjb250ZW50cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJ1bGVzKGNsaUVuZ2luZSkge1xuICAvLyBQdWxsIHRoZSBsaXN0IG9mIHJ1bGVzIHVzZWQgZGlyZWN0bHkgZnJvbSB0aGUgQ0xJRW5naW5lXG4gIGlmICh0eXBlb2YgY2xpRW5naW5lLmdldFJ1bGVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGNsaUVuZ2luZS5nZXRSdWxlcygpXG4gIH1cblxuICAvLyBBdHRlbXB0IHRvIHVzZSB0aGUgaW50ZXJuYWwgKHVuZG9jdW1lbnRlZCkgYGxpbnRlcmAgaW5zdGFuY2UgYXR0YWNoZWQgdG9cbiAgLy8gdGhlIENMSUVuZ2luZSB0byBnZXQgdGhlIGxvYWRlZCBydWxlcyAoaW5jbHVkaW5nIHBsdWdpbiBydWxlcykuXG4gIC8vIEFkZGVkIGluIEVTTGludCB2NFxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGNsaUVuZ2luZSwgJ2xpbnRlcicpKSB7XG4gICAgcmV0dXJuIGNsaUVuZ2luZS5saW50ZXIuZ2V0UnVsZXMoKVxuICB9XG5cbiAgLy8gT2xkZXIgdmVyc2lvbnMgb2YgRVNMaW50IGRvbid0IChlYXNpbHkpIHN1cHBvcnQgZ2V0dGluZyBhIGxpc3Qgb2YgcnVsZXNcbiAgcmV0dXJuIG5ldyBNYXAoKVxufVxuXG4vKipcbiAqIEdpdmVuIGFuIGV4aXRpbmcgcnVsZSBsaXN0IGFuZCBhIG5ldyBydWxlIGxpc3QsIGRldGVybWluZXMgd2hldGhlciB0aGVyZVxuICogaGF2ZSBiZWVuIGNoYW5nZXMuXG4gKiBOT1RFOiBUaGlzIG9ubHkgYWNjb3VudHMgZm9yIHByZXNlbmNlIG9mIHRoZSBydWxlcywgY2hhbmdlcyB0byB0aGVpciBtZXRhZGF0YVxuICogYXJlIG5vdCB0YWtlbiBpbnRvIGFjY291bnQuXG4gKiBAcGFyYW0gIHtNYXB9IG5ld1J1bGVzICAgICBBIE1hcCBvZiB0aGUgbmV3IHJ1bGVzXG4gKiBAcGFyYW0gIHtNYXB9IGN1cnJlbnRSdWxlcyBBIE1hcCBvZiB0aGUgY3VycmVudCBydWxlc1xuICogQHJldHVybiB7Ym9vbGVhbn0gICAgICAgICAgICAgV2hldGhlciBvciBub3QgdGhlcmUgd2VyZSBjaGFuZ2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaWRSdWxlc0NoYW5nZShjdXJyZW50UnVsZXMsIG5ld1J1bGVzKSB7XG4gIHJldHVybiAhKGN1cnJlbnRSdWxlcy5zaXplID09PSBuZXdSdWxlcy5zaXplXG4gICAgJiYgQXJyYXkuZnJvbShjdXJyZW50UnVsZXMua2V5cygpKS5ldmVyeSgocnVsZUlkKSA9PiBuZXdSdWxlcy5oYXMocnVsZUlkKSkpXG59XG4iXX0= \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy93b3JrZXItaGVscGVycy5qcyJdLCJuYW1lcyI6WyJDYWNoZSIsIkVTTElOVF9MT0NBTF9QQVRIIiwiUGF0aCIsIm5vcm1hbGl6ZSIsImpvaW4iLCJfX2Rpcm5hbWUiLCJOT0RFX1BSRUZJWF9QQVRIIiwiTEFTVF9NT0RVTEVTX1BBVEgiLCJjbGVhblBhdGgiLCJwYXRoIiwiZnMiLCJnZXROb2RlUHJlZml4UGF0aCIsIm5wbUNvbW1hbmQiLCJwcm9jZXNzIiwicGxhdGZvcm0iLCJDaGlsZFByb2Nlc3MiLCJzcGF3blN5bmMiLCJlbnYiLCJQQVRIIiwib3V0cHV0IiwidG9TdHJpbmciLCJ0cmltIiwiZSIsImVyck1zZyIsIkVycm9yIiwiaXNEaXJlY3RvcnkiLCJkaXJQYXRoIiwiaXNEaXIiLCJzdGF0U3luYyIsImZhbGxiYWNrRm9yR2xvYmFsRXJyb3JUaHJvd24iLCJmaW5kRVNMaW50RGlyZWN0b3J5IiwibW9kdWxlc0RpciIsImNvbmZpZyIsInByb2plY3RQYXRoIiwiZmFsbGJhY2tGb3JHbG9iYWwiLCJlc2xpbnREaXIiLCJsb2NhdGlvblR5cGUiLCJnbG9iYWwiLCJ1c2VHbG9iYWxFc2xpbnQiLCJjb25maWdHbG9iYWwiLCJnbG9iYWxOb2RlUGF0aCIsInByZWZpeFBhdGgiLCJhZHZhbmNlZCIsImxvY2FsTm9kZU1vZHVsZXMiLCJpc0Fic29sdXRlIiwidHlwZSIsImNvbnNvbGUiLCJlcnJvciIsImdldEVTTGludEZyb21EaXJlY3RvcnkiLCJFU0xpbnREaXJlY3RvcnkiLCJyZXF1aXJlIiwiY29kZSIsInJlZnJlc2hNb2R1bGVzUGF0aCIsIk5PREVfUEFUSCIsIk1vZHVsZSIsIl9pbml0UGF0aHMiLCJnZXRFU0xpbnRJbnN0YW5jZSIsImZpbGVEaXIiLCJkaXJuYW1lIiwibG9nIiwiYXJncyIsIm9iaiIsImxlbmd0aCIsInN0ciIsIkpTT04iLCJzdHJpbmdpZnkiLCJVdGlsIiwiaW5zcGVjdCIsImVtaXQiLCJnZXRDb25maWdGb3JGaWxlIiwiZXNsaW50IiwiZmlsZVBhdGgiLCJjbGkiLCJDTElFbmdpbmUiLCJnZXRSZWxhdGl2ZVBhdGgiLCJpZ25vcmVGaWxlIiwiZGlzYWJsZUVzbGludElnbm9yZSIsImlnbm9yZURpciIsImNoZGlyIiwicmVsYXRpdmUiLCJiYXNlbmFtZSIsImdldENMSUVuZ2luZU9wdGlvbnMiLCJydWxlcyIsImZpbGVDb25maWciLCJjbGlFbmdpbmVDb25maWciLCJpZ25vcmUiLCJmaXgiLCJydWxlUGF0aHMiLCJlc2xpbnRSdWxlc0RpcnMiLCJtYXAiLCJydWxlc0RpciIsImZpbHRlciIsImVzbGludHJjUGF0aCIsImNvbmZpZ0ZpbGUiLCJnZXRSdWxlcyIsImNsaUVuZ2luZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImxpbnRlciIsIk1hcCIsImRpZFJ1bGVzQ2hhbmdlIiwiY3VycmVudFJ1bGVzIiwibmV3UnVsZXMiLCJzaXplIiwiQXJyYXkiLCJmcm9tIiwia2V5cyIsImV2ZXJ5IiwicnVsZUlkIiwiaGFzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBUkE7QUFVQSxNQUFNQSxLQUFLLEdBQUc7QUFDWkMsRUFBQUEsaUJBQWlCLEVBQUVDLGNBQUtDLFNBQUwsQ0FBZUQsY0FBS0UsSUFBTCxDQUFVQyxTQUFWLEVBQXFCLElBQXJCLEVBQTJCLGNBQTNCLEVBQTJDLFFBQTNDLENBQWYsQ0FEUDtBQUVaQyxFQUFBQSxnQkFBZ0IsRUFBRSxJQUZOO0FBR1pDLEVBQUFBLGlCQUFpQixFQUFFO0FBSFAsQ0FBZDtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxNQUFNQyxTQUFTLEdBQUlDLElBQUQsSUFBV0EsSUFBSSxHQUFHLHlCQUFXQyxnQkFBR1AsU0FBSCxDQUFhTSxJQUFiLENBQVgsQ0FBSCxHQUFvQyxFQUFyRTtBQUVBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU0Us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cGF0aCc7XG5pbXBvcnQgVXRpbCBmcm9tICd1dGlsJztcbmltcG9ydCBmcyBmcm9tICdmcy1wbHVzJ1xuaW1wb3J0IENoaWxkUHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJ1xuaW1wb3J0IHJlc29sdmVFbnYgZnJvbSAncmVzb2x2ZS1lbnYnXG5pbXBvcnQgeyBmaW5kQ2FjaGVkIH0gZnJvbSAnYXRvbS1saW50ZXInXG5pbXBvcnQgZ2V0UGF0aCBmcm9tICdjb25zaXN0ZW50LXBhdGgnXG5cbmNvbnN0IENhY2hlID0ge1xuICBFU0xJTlRfTE9DQUxfUEFUSDogUGF0aC5ub3JtYWxpemUoUGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJ25vZGVfbW9kdWxlcycsICdlc2xpbnQnKSksXG4gIE5PREVfUFJFRklYX1BBVEg6IG51bGwsXG4gIExBU1RfTU9EVUxFU19QQVRIOiBudWxsXG59XG5cbi8qKlxuICogVGFrZXMgYSBwYXRoIGFuZCB0cmFuc2xhdGVzIGB+YCB0byB0aGUgdXNlcidzIGhvbWUgZGlyZWN0b3J5LCBhbmQgcmVwbGFjZXNcbiAqIGFsbCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgd2l0aCB0aGVpciB2YWx1ZS5cbiAqIEBwYXJhbSAge3N0cmluZ30gcGF0aCBUaGUgcGF0aCB0byByZW1vdmUgXCJzdHJhbmdlbmVzc1wiIGZyb21cbiAqIEByZXR1cm4ge3N0cmluZ30gICAgICBUaGUgY2xlYW5lZCBwYXRoXG4gKi9cbmNvbnN0IGNsZWFuUGF0aCA9IChwYXRoKSA9PiAocGF0aCA/IHJlc29sdmVFbnYoZnMubm9ybWFsaXplKHBhdGgpKSA6ICcnKVxuXG4vKipcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXROb2RlUHJlZml4UGF0aCgpIHtcbiAgaWYgKENhY2hlLk5PREVfUFJFRklYX1BBVEggPT09IG51bGwpIHtcbiAgICBjb25zdCBucG1Db21tYW5kID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyA/ICducG0uY21kJyA6ICducG0nXG4gICAgdHJ5IHtcbiAgICAgIENhY2hlLk5PREVfUFJFRklYX1BBVEggPSBDaGlsZFByb2Nlc3Muc3Bhd25TeW5jKG5wbUNvbW1hbmQsIFsnZ2V0JywgJ3ByZWZpeCddLCB7XG4gICAgICAgIGVudjogeyAuLi5wcm9jZXNzLmVudiwgUEFUSDogZ2V0UGF0aCgpIH1cbiAgICAgIH0pLm91dHB1dFsxXS50b1N0cmluZygpLnRyaW0oKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnN0IGVyck1zZyA9ICdVbmFibGUgdG8gZXhlY3V0ZSBgbnBtIGdldCBwcmVmaXhgLiBQbGVhc2UgbWFrZSBzdXJlICdcbiAgICAgICAgKyAnQXRvbSBpcyBnZXR0aW5nICRQQVRIIGNvcnJlY3RseS4nXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKVxuICAgIH1cbiAgfVxuICByZXR1cm4gQ2FjaGUuTk9ERV9QUkVGSVhfUEFUSFxufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJQYXRoXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNEaXJlY3RvcnkoZGlyUGF0aCkge1xuICBsZXQgaXNEaXJcbiAgdHJ5IHtcbiAgICBpc0RpciA9IGZzLnN0YXRTeW5jKGRpclBhdGgpLmlzRGlyZWN0b3J5KClcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlzRGlyID0gZmFsc2VcbiAgfVxuICByZXR1cm4gaXNEaXJcbn1cblxubGV0IGZhbGxiYWNrRm9yR2xvYmFsRXJyb3JUaHJvd24gPSBmYWxzZVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGVzRGlyXG4gKiBAcGFyYW0ge29iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdFBhdGhcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFsbGJhY2tGb3JHbG9iYWxcbiAqIEByZXR1cm5zIHt7IHBhdGg6IHN0cmluZywgdHlwZTogJ2xvY2FsIHByb2plY3QnIHwgJ2dsb2JhbCcgfCAnYWR2YW5jZWQgc3BlY2lmaWVkJyB8ICdidW5kbGVkIGZhbGxiYWNrJyB9fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEVTTGludERpcmVjdG9yeShtb2R1bGVzRGlyLCBjb25maWcsIHByb2plY3RQYXRoLCBmYWxsYmFja0Zvckdsb2JhbCA9IGZhbHNlKSB7XG4gIGxldCBlc2xpbnREaXIgPSBudWxsXG4gIGxldCBsb2NhdGlvblR5cGUgPSBudWxsXG4gIGlmIChjb25maWcuZ2xvYmFsLnVzZUdsb2JhbEVzbGludCAmJiAhZmFsbGJhY2tGb3JHbG9iYWwpIHtcbiAgICBsb2NhdGlvblR5cGUgPSAnZ2xvYmFsJ1xuICAgIGNvbnN0IGNvbmZpZ0dsb2JhbCA9IGNsZWFuUGF0aChjb25maWcuZ2xvYmFsLmdsb2JhbE5vZGVQYXRoKVxuICAgIGNvbnN0IHByZWZpeFBhdGggPSBjb25maWdHbG9iYWwgfHwgZ2V0Tm9kZVByZWZpeFBhdGgoKVxuICAgIC8vIE5QTSBvbiBXaW5kb3dzIGFuZCBZYXJuIG9uIGFsbCBwbGF0Zm9ybXNcbiAgICBlc2xpbnREaXIgPSBQYXRoLmpvaW4ocHJlZml4UGF0aCwgJ25vZGVfbW9kdWxlcycsICdlc2xpbnQnKVxuICAgIGlmICghaXNEaXJlY3RvcnkoZXNsaW50RGlyKSkge1xuICAgICAgLy8gTlBNIG9uIHBsYXRmb3JtcyBvdGhlciB0aGFuIFdpbmRvd3NcbiAgICAgIGVzbGludERpciA9IFBhdGguam9pbihwcmVmaXhQYXRoLCAnbGliJywgJ25vZGVfbW9kdWxlcycsICdlc2xpbnQnKVxuICAgIH1cbiAgfSBlbHNlIGlmICghY29uZmlnLmFkdmFuY2VkLmxvY2FsTm9kZU1vZHVsZXMpIHtcbiAgICBsb2NhdGlvblR5cGUgPSAnbG9jYWwgcHJvamVjdCdcbiAgICBlc2xpbnREaXIgPSBQYXRoLmpvaW4obW9kdWxlc0RpciB8fCAnJywgJ2VzbGludCcpXG4gIH0gZWxzZSBpZiAoUGF0aC5pc0Fic29sdXRlKGNsZWFuUGF0aChjb25maWcuYWR2YW5jZWQubG9jYWxOb2RlTW9kdWxlcykpKSB7XG4gICAgbG9jYXRpb25UeXBlID0gJ2FkdmFuY2VkIHNwZWNpZmllZCdcbiAgICBlc2xpbnREaXIgPSBQYXRoLmpvaW4oY2xlYW5QYXRoKGNvbmZpZy5hZHZhbmNlZC5sb2NhbE5vZGVNb2R1bGVzKSwgJ2VzbGludCcpXG4gIH0gZWxzZSB7XG4gICAgbG9jYXRpb25UeXBlID0gJ2FkdmFuY2VkIHNwZWNpZmllZCdcbiAgICBlc2xpbnREaXIgPSBQYXRoLmpvaW4ocHJvamVjdFBhdGggfHwgJycsIGNsZWFuUGF0aChjb25maWcuYWR2YW5jZWQubG9jYWxOb2RlTW9kdWxlcyksICdlc2xpbnQnKVxuICB9XG5cbiAgaWYgKGlzRGlyZWN0b3J5KGVzbGludERpcikpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcGF0aDogZXNsaW50RGlyLFxuICAgICAgdHlwZTogbG9jYXRpb25UeXBlLFxuICAgIH1cbiAgfVxuXG4gIGlmIChjb25maWcuZ2xvYmFsLnVzZUdsb2JhbEVzbGludCAmJiAhZmFsbGJhY2tGb3JHbG9iYWwpIHtcbiAgICBpZiAoIWZhbGxiYWNrRm9yR2xvYmFsRXJyb3JUaHJvd24pIHtcbiAgICAgIC8vIFRocm93IHRoZSBlcnJvciBvbmx5IG9uY2UgdG8gcHJldmVudCBwZXJmb3JtYW5jZSBpc3N1ZXNcbiAgICAgIGZhbGxiYWNrRm9yR2xvYmFsRXJyb3JUaHJvd24gPSB0cnVlXG4gICAgICBjb25zb2xlLmVycm9yKGBHbG9iYWwgRVNMaW50IGlzIG5vdCBmb3VuZCwgZmFsbGluZyBiYWNrIHRvIG90aGVyIEVzbGludCBpbnN0YWxsYXRpb25zLi4uXG4gICAgICAgIFBsZWFzZSBlbnN1cmUgdGhlIGdsb2JhbCBOb2RlIHBhdGggaXMgc2V0IGNvcnJlY3RseS5cbiAgICAgICAgSWYgeW91IHdhbnRlZCB0byB1c2UgYSBsb2NhbCBpbnN0YWxsYXRpb24gb2YgRXNsaW50LCBkaXNhYmxlIEdsb2JhbCBFc2xpbnQgb3B0aW9uIGluIHRoZSBsaW50ZXItZXNsaW50IGNvbmZpZy5gKVxuICAgIH1cbiAgICByZXR1cm4gZmluZEVTTGludERpcmVjdG9yeShtb2R1bGVzRGlyLCBjb25maWcsIHByb2plY3RQYXRoLCB0cnVlKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoOiBDYWNoZS5FU0xJTlRfTE9DQUxfUEFUSCxcbiAgICB0eXBlOiAnYnVuZGxlZCBmYWxsYmFjaycsXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlc0RpclxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2plY3RQYXRoXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiZXNsaW50XCIpfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RVNMaW50RnJvbURpcmVjdG9yeShtb2R1bGVzRGlyLCBjb25maWcsIHByb2plY3RQYXRoKSB7XG4gIGNvbnN0IHsgcGF0aDogRVNMaW50RGlyZWN0b3J5IH0gPSBmaW5kRVNMaW50RGlyZWN0b3J5KG1vZHVsZXNEaXIsIGNvbmZpZywgcHJvamVjdFBhdGgpXG4gIHRyeSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1keW5hbWljLXJlcXVpcmVcbiAgICByZXR1cm4gcmVxdWlyZShFU0xpbnREaXJlY3RvcnkpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoY29uZmlnLmdsb2JhbC51c2VHbG9iYWxFc2xpbnQgJiYgZS5jb2RlID09PSAnTU9EVUxFX05PVF9GT1VORCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRVNMaW50IG5vdCBmb3VuZCwgdHJ5IHJlc3RhcnRpbmcgQXRvbSB0byBjbGVhciBjYWNoZXMuJylcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1keW5hbWljLXJlcXVpcmVcbiAgICByZXR1cm4gcmVxdWlyZShDYWNoZS5FU0xJTlRfTE9DQUxfUEFUSClcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGVzRGlyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWZyZXNoTW9kdWxlc1BhdGgobW9kdWxlc0Rpcikge1xuICBpZiAoQ2FjaGUuTEFTVF9NT0RVTEVTX1BBVEggIT09IG1vZHVsZXNEaXIpIHtcbiAgICBDYWNoZS5MQVNUX01PRFVMRVNfUEFUSCA9IG1vZHVsZXNEaXJcbiAgICBwcm9jZXNzLmVudi5OT0RFX1BBVEggPSBtb2R1bGVzRGlyIHx8ICcnXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG4gICAgcmVxdWlyZSgnbW9kdWxlJykuTW9kdWxlLl9pbml0UGF0aHMoKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVEaXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9qZWN0UGF0aFxuICogQHJldHVybnMge2ltcG9ydChcImVzbGludFwiKX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEVTTGludEluc3RhbmNlKGZpbGVEaXIsIGNvbmZpZywgcHJvamVjdFBhdGgpIHtcbiAgY29uc3QgbW9kdWxlc0RpciA9IFBhdGguZGlybmFtZShmaW5kQ2FjaGVkKGZpbGVEaXIsICdub2RlX21vZHVsZXMvZXNsaW50JykgfHwgJycpXG4gIHJlZnJlc2hNb2R1bGVzUGF0aChtb2R1bGVzRGlyKVxuICByZXR1cm4gZ2V0RVNMaW50RnJvbURpcmVjdG9yeShtb2R1bGVzRGlyLCBjb25maWcsIHByb2plY3RQYXRoKVxufVxuXG4vKipcbiAqIGNvbnNvbGUubG9nXG4gKiBAcGFyYW0gIHthbnl9IGFyZ3NcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2coLi4uYXJncykge1xuICBjb25zdCBvYmogPSBhcmdzLmxlbmd0aCA9PT0gMSA/IGFyZ3NbMF0gOiBhcmdzXG4gIGxldCBzdHJcbiAgdHJ5IHtcbiAgICBzdHIgPSBKU09OLnN0cmluZ2lmeShvYmopXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBzdHIgPSBVdGlsLmluc3BlY3Qob2JqKVxuICB9XG5cbiAgZW1pdCgnbG9nJywgc3RyKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiZXNsaW50XCIpfSBlc2xpbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uZmlnRm9yRmlsZShlc2xpbnQsIGZpbGVQYXRoKSB7XG4gIGNvbnN0IGNsaSA9IG5ldyBlc2xpbnQuQ0xJRW5naW5lKClcbiAgdHJ5IHtcbiAgICByZXR1cm4gY2xpLmdldENvbmZpZ0ZvckZpbGUoZmlsZVBhdGgpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBObyBjb25maWd1cmF0aW9uIHdhcyBmb3VuZFxuICAgIHJldHVybiBudWxsXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZURpclxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKiBAcGFyYW0ge29iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvamVjdFBhdGhcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZWxhdGl2ZVBhdGgoZmlsZURpciwgZmlsZVBhdGgsIGNvbmZpZywgcHJvamVjdFBhdGgpIHtcbiAgY29uc3QgaWdub3JlRmlsZSA9IGNvbmZpZy5hZHZhbmNlZC5kaXNhYmxlRXNsaW50SWdub3JlID8gbnVsbCA6IGZpbmRDYWNoZWQoZmlsZURpciwgJy5lc2xpbnRpZ25vcmUnKVxuXG4gIC8vIElmIHdlIGNhbiBmaW5kIGFuIC5lc2xpbnRpZ25vcmUgZmlsZSwgd2UgY2FuIHNldCBjd2QgdGhlcmVcbiAgLy8gKGJlY2F1c2UgdGhleSBhcmUgZXhwZWN0ZWQgdG8gYmUgYXQgdGhlIHByb2plY3Qgcm9vdClcbiAgaWYgKGlnbm9yZUZpbGUpIHtcbiAgICBjb25zdCBpZ25vcmVEaXIgPSBQYXRoLmRpcm5hbWUoaWdub3JlRmlsZSlcbiAgICBwcm9jZXNzLmNoZGlyKGlnbm9yZURpcilcbiAgICByZXR1cm4gUGF0aC5yZWxhdGl2ZShpZ25vcmVEaXIsIGZpbGVQYXRoKVxuICB9XG4gIC8vIE90aGVyd2lzZSwgd2UnbGwgc2V0IHRoZSBjd2QgdG8gdGhlIGF0b20gcHJvamVjdCByb290IGFzIGxvbmcgYXMgdGhhdCBleGlzdHNcbiAgaWYgKHByb2plY3RQYXRoKSB7XG4gICAgcHJvY2Vzcy5jaGRpcihwcm9qZWN0UGF0aClcbiAgICByZXR1cm4gUGF0aC5yZWxhdGl2ZShwcm9qZWN0UGF0aCwgZmlsZVBhdGgpXG4gIH1cbiAgLy8gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSB0aGUgZmlsZSBsb2NhdGlvbiBpdHNlbGZcbiAgcHJvY2Vzcy5jaGRpcihmaWxlRGlyKVxuICByZXR1cm4gUGF0aC5iYXNlbmFtZShmaWxlUGF0aClcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHBhcmFtIHtzdHJpbmdbXX0gcnVsZXNcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICogQHBhcmFtIHtvYmplY3R9IGZpbGVDb25maWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENMSUVuZ2luZU9wdGlvbnModHlwZSwgY29uZmlnLCBydWxlcywgZmlsZVBhdGgsIGZpbGVDb25maWcpIHtcbiAgY29uc3QgY2xpRW5naW5lQ29uZmlnID0ge1xuICAgIHJ1bGVzLFxuICAgIGlnbm9yZTogIWNvbmZpZy5hZHZhbmNlZC5kaXNhYmxlRXNsaW50SWdub3JlLFxuICAgIGZpeDogdHlwZSA9PT0gJ2ZpeCdcbiAgfVxuXG4gIGNsaUVuZ2luZUNvbmZpZy5ydWxlUGF0aHMgPSBjb25maWcuYWR2YW5jZWQuZXNsaW50UnVsZXNEaXJzLm1hcCgocGF0aCkgPT4ge1xuICAgIGNvbnN0IHJ1bGVzRGlyID0gY2xlYW5QYXRoKHBhdGgpXG4gICAgaWYgKCFQYXRoLmlzQWJzb2x1dGUocnVsZXNEaXIpKSB7XG4gICAgICByZXR1cm4gZmluZENhY2hlZChQYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCBydWxlc0RpcilcbiAgICB9XG4gICAgcmV0dXJuIHJ1bGVzRGlyXG4gIH0pLmZpbHRlcigocGF0aCkgPT4gcGF0aClcblxuICBpZiAoZmlsZUNvbmZpZyA9PT0gbnVsbCAmJiBjb25maWcuZ2xvYmFsLmVzbGludHJjUGF0aCkge1xuICAgIC8vIElmIHdlIGRpZG4ndCBmaW5kIGEgY29uZmlndXJhdGlvbiB1c2UgdGhlIGZhbGxiYWNrIGZyb20gdGhlIHNldHRpbmdzXG4gICAgY2xpRW5naW5lQ29uZmlnLmNvbmZpZ0ZpbGUgPSBjbGVhblBhdGgoY29uZmlnLmdsb2JhbC5lc2xpbnRyY1BhdGgpXG4gIH1cblxuICByZXR1cm4gY2xpRW5naW5lQ29uZmlnXG59XG5cbi8qKlxuICogR2V0cyB0aGUgbGlzdCBvZiBydWxlcyB1c2VkIGZvciBhIGxpbnQgam9iXG4gKiBAcGFyYW0gIHtpbXBvcnQoXCJlc2xpbnRcIikuQ0xJRW5naW5lfSBjbGlFbmdpbmUgVGhlIENMSUVuZ2luZSBpbnN0YW5jZSB1c2VkIGZvciB0aGUgbGludCBqb2JcbiAqIEByZXR1cm4ge01hcH0gICAgICAgICAgICAgIEEgTWFwIG9mIHRoZSBydWxlcyB1c2VkLCBydWxlIG5hbWVzIGFzIGtleXMsIHJ1bGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXMgYXMgdGhlIGNvbnRlbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVsZXMoY2xpRW5naW5lKSB7XG4gIC8vIFB1bGwgdGhlIGxpc3Qgb2YgcnVsZXMgdXNlZCBkaXJlY3RseSBmcm9tIHRoZSBDTElFbmdpbmVcbiAgaWYgKHR5cGVvZiBjbGlFbmdpbmUuZ2V0UnVsZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gY2xpRW5naW5lLmdldFJ1bGVzKClcbiAgfVxuXG4gIC8vIEF0dGVtcHQgdG8gdXNlIHRoZSBpbnRlcm5hbCAodW5kb2N1bWVudGVkKSBgbGludGVyYCBpbnN0YW5jZSBhdHRhY2hlZCB0b1xuICAvLyB0aGUgQ0xJRW5naW5lIHRvIGdldCB0aGUgbG9hZGVkIHJ1bGVzIChpbmNsdWRpbmcgcGx1Z2luIHJ1bGVzKS5cbiAgLy8gQWRkZWQgaW4gRVNMaW50IHY0XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2xpRW5naW5lLCAnbGludGVyJykpIHtcbiAgICByZXR1cm4gY2xpRW5naW5lLmxpbnRlci5nZXRSdWxlcygpXG4gIH1cblxuICAvLyBPbGRlciB2ZXJzaW9ucyBvZiBFU0xpbnQgZG9uJ3QgKGVhc2lseSkgc3VwcG9ydCBnZXR0aW5nIGEgbGlzdCBvZiBydWxlc1xuICByZXR1cm4gbmV3IE1hcCgpXG59XG5cbi8qKlxuICogR2l2ZW4gYW4gZXhpdGluZyBydWxlIGxpc3QgYW5kIGEgbmV3IHJ1bGUgbGlzdCwgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZXJlXG4gKiBoYXZlIGJlZW4gY2hhbmdlcy5cbiAqIE5PVEU6IFRoaXMgb25seSBhY2NvdW50cyBmb3IgcHJlc2VuY2Ugb2YgdGhlIHJ1bGVzLCBjaGFuZ2VzIHRvIHRoZWlyIG1ldGFkYXRhXG4gKiBhcmUgbm90IHRha2VuIGludG8gYWNjb3VudC5cbiAqIEBwYXJhbSAge01hcH0gbmV3UnVsZXMgICAgIEEgTWFwIG9mIHRoZSBuZXcgcnVsZXNcbiAqIEBwYXJhbSAge01hcH0gY3VycmVudFJ1bGVzIEEgTWFwIG9mIHRoZSBjdXJyZW50IHJ1bGVzXG4gKiBAcmV0dXJuIHtib29sZWFufSAgICAgICAgICAgICBXaGV0aGVyIG9yIG5vdCB0aGVyZSB3ZXJlIGNoYW5nZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpZFJ1bGVzQ2hhbmdlKGN1cnJlbnRSdWxlcywgbmV3UnVsZXMpIHtcbiAgcmV0dXJuICEoY3VycmVudFJ1bGVzLnNpemUgPT09IG5ld1J1bGVzLnNpemVcbiAgICAmJiBBcnJheS5mcm9tKGN1cnJlbnRSdWxlcy5rZXlzKCkpLmV2ZXJ5KChydWxlSWQpID0+IG5ld1J1bGVzLmhhcyhydWxlSWQpKSlcbn1cbiJdfQ== \ No newline at end of file diff --git a/package.json b/package.json index 0a4f8c9c..0c391f19 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "linter-eslint", "main": "./dist/main.js", "version": "9.0.0", - "description": "Lint JavaScript on the fly, using ESLint", + "description": "Lint JavaScript on the fly, using ESLint (v7 or older)", "repository": "https://github.com/AtomLinter/linter-eslint.git", "license": "MIT", "engines": { @@ -155,6 +155,13 @@ "type": "string", "default": "", "order": 5 + }, + "showIncompatibleVersionNotification": { + "title": "Notify when incompatible ESLint is detected", + "description": "When enabled, will show a notification if this package loads inside a project using ESLint version 8 or greater _and_ the user has not already installed the newer `linter-eslint-node` package. Uncheck if you don't want these notifications.", + "type": "boolean", + "default": true, + "order": 6 } } } diff --git a/spec/fixtures/global-eslint/lib/node_modules/eslint/lib/api.js b/spec/fixtures/global-eslint/lib/node_modules/eslint/lib/api.js index 620463e4..3e6df747 100644 --- a/spec/fixtures/global-eslint/lib/node_modules/eslint/lib/api.js +++ b/spec/fixtures/global-eslint/lib/node_modules/eslint/lib/api.js @@ -1 +1 @@ -module.exports = "located" +module.exports = { CLIEngine: true, type: "located" } diff --git a/spec/fixtures/incompatible-eslint/node_modules/eslint/lib/api.js b/spec/fixtures/incompatible-eslint/node_modules/eslint/lib/api.js new file mode 100644 index 00000000..2b374656 --- /dev/null +++ b/spec/fixtures/incompatible-eslint/node_modules/eslint/lib/api.js @@ -0,0 +1 @@ +module.exports = { ESLint: true, type: 'incompatible' } diff --git a/spec/fixtures/incompatible-eslint/node_modules/eslint/package.json b/spec/fixtures/incompatible-eslint/node_modules/eslint/package.json new file mode 100644 index 00000000..01c9f959 --- /dev/null +++ b/spec/fixtures/incompatible-eslint/node_modules/eslint/package.json @@ -0,0 +1 @@ +{ "version": "8.0.0" } diff --git a/spec/fixtures/indirect-local-eslint/testing/eslint/node_modules/eslint/lib/api.js b/spec/fixtures/indirect-local-eslint/testing/eslint/node_modules/eslint/lib/api.js index 620463e4..3e6df747 100644 --- a/spec/fixtures/indirect-local-eslint/testing/eslint/node_modules/eslint/lib/api.js +++ b/spec/fixtures/indirect-local-eslint/testing/eslint/node_modules/eslint/lib/api.js @@ -1 +1 @@ -module.exports = "located" +module.exports = { CLIEngine: true, type: "located" } diff --git a/spec/fixtures/local-eslint/node_modules/eslint/lib/api.js b/spec/fixtures/local-eslint/node_modules/eslint/lib/api.js index 620463e4..3e6df747 100644 --- a/spec/fixtures/local-eslint/node_modules/eslint/lib/api.js +++ b/spec/fixtures/local-eslint/node_modules/eslint/lib/api.js @@ -1 +1 @@ -module.exports = "located" +module.exports = { CLIEngine: true, type: "located" } diff --git a/spec/worker-helpers-spec.js b/spec/worker-helpers-spec.js index 3f829d6d..da5f24cb 100644 --- a/spec/worker-helpers-spec.js +++ b/spec/worker-helpers-spec.js @@ -81,7 +81,7 @@ describe('Worker Helpers', () => { advanced: { localNodeModules: path } }) const eslint = Helpers.getESLintInstance('', config) - expect(eslint).toBe('located') + expect(eslint.type).toBe('located') }) it('tries to find an indirect local eslint using a relative path', () => { @@ -93,13 +93,13 @@ describe('Worker Helpers', () => { }) const eslint = Helpers.getESLintInstance('', config, projectPath) - expect(eslint).toBe('located') + expect(eslint.type).toBe('located') }) it('tries to find a local eslint', () => { const config = createConfig() const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) - expect(eslint).toBe('located') + expect(eslint.type).toBe('located') }) it('cries if local eslint is not found', () => { @@ -109,13 +109,20 @@ describe('Worker Helpers', () => { }).toThrow() }) + it('cries if incompatible eslint is found', () => { + expect(() => { + const config = createConfig() + Helpers.getESLintInstance(getFixturesPath('incompatible-eslint'), config) + }).toThrow() + }) + it('tries to find a global eslint if config is specified', () => { const config = createConfig({ global: { useGlobalEslint: true, globalNodePath } }) console.log({ config }) const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) - expect(eslint).toBe('located') + expect(eslint.type).toBe('located') }) it('cries if global eslint is not found', () => { @@ -133,7 +140,7 @@ describe('Worker Helpers', () => { const fileDir = Path.join(getFixturesPath('local-eslint'), 'lib', 'foo.js') const config = createConfig() const eslint = Helpers.getESLintInstance(fileDir, config) - expect(eslint).toBe('located') + expect(eslint.type).toBe('located') }) }) diff --git a/src/helpers.js b/src/helpers.js index 98d9e16b..bb24b3c8 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -4,12 +4,16 @@ import { randomBytes } from 'crypto' import { promisify } from 'util' // eslint-disable-next-line import/no-extraneous-dependencies, import/extensions import { Range, Task } from 'atom' +// eslint-disable-next-line import/no-unresolved +import { shell } from 'electron' import Rules from './rules' import { throwIfInvalidPoint } from './validate/editor' const asyncRandomBytes = promisify(randomBytes) export const rules = new Rules() let worker = null +let isIncompatibleEslintVersion = false +let seenIncompatibleVersionNotification = false /** * Start the worker process if it hasn't already been started @@ -48,6 +52,10 @@ export function killWorker() { } } +export function isIncompatibleEslint() { + return isIncompatibleEslintVersion +} + /** * Send a job to the worker and return the results * @param {Object} config Configuration for the job to send to the worker @@ -74,11 +82,12 @@ export async function sendJob(config) { // All worker errors are caught and re-emitted along with their associated // emitKey, so that we do not create multiple listeners for the same // 'task:error' event - const errSub = worker.on(`workerError:${config.emitKey}`, ({ msg, stack }) => { + const errSub = worker.on(`workerError:${config.emitKey}`, ({ msg, stack, name }) => { // Re-throw errors from the task const error = new Error(msg) // Set the stack to the one given to us by the worker error.stack = stack + error.name = name errSub.dispose() // eslint-disable-next-line no-use-before-define responseSub.dispose() @@ -189,6 +198,44 @@ export function generateUserMessage(textEditor, options) { }] } +function isNewPackageInstalled() { + return atom.packages.isPackageLoaded('linter-eslint-node') + || atom.packages.isPackageDisabled('linter-eslint-node') +} + +function showIncompatibleVersionNotification(message) { + const notificationEnabled = atom.config.get('linter-eslint.advanced.showIncompatibleVersionNotification') + if (!notificationEnabled || seenIncompatibleVersionNotification || isNewPackageInstalled()) { + return + } + + // Show this message only once per session. + seenIncompatibleVersionNotification = true + const notification = atom.notifications.addWarning( + 'linter-eslint: Incompatible version', + { + description: message, + dismissable: true, + buttons: [ + { + text: 'Install linter-eslint-node', + onDidClick() { + shell.openExternal('https://atom.io/packages/linter-eslint-node') + notification.dismiss() + } + }, + { + text: 'Don\'t show this notification again', + onDidClick() { + atom.config.set('linter-eslint.advanced.showIncompatibleVersionNotification', false) + notification.dismiss() + } + } + ] + } + ) +} + /** * Generates a message to the user in order to nicely display the Error being * thrown instead of depending on generic error handling. @@ -197,10 +244,19 @@ export function generateUserMessage(textEditor, options) { * @return {import("atom/linter").Message[]} Message to user generated from the Error */ export function handleError(textEditor, error) { - const { stack, message } = error + const { stack, message, name } = error + // We want this specific worker error to show up as a notification so that we + // can include a button for installing the new package. + if (name === 'IncompatibleESLintError') { + isIncompatibleEslintVersion = true + killWorker() + showIncompatibleVersionNotification(message) + return + } // Only show the first line of the message as the excerpt const excerpt = `Error while running ESLint: ${message.split('\n')[0]}.` const description = `
${message}\n
${stack}
` + // eslint-disable-next-line consistent-return return generateUserMessage(textEditor, { severity: 'error', excerpt, description }) } diff --git a/src/main.js b/src/main.js index 6b5ecfad..d94f3a9c 100644 --- a/src/main.js +++ b/src/main.js @@ -182,6 +182,13 @@ module.exports = { return null } + if (helpers.isIncompatibleEslint()) { + // The project's version of ESLint doesn't work with this package. Once + // this is detected, we won't try to send any jobs until the window is + // reloaded. + return null + } + const filePath = textEditor.getPath() if (!filePath) { // The editor currently has no path, we can't report messages back to @@ -246,6 +253,13 @@ module.exports = { return } + if (helpers.isIncompatibleEslint()) { + // The project's version of ESLint doesn't work with this package. Once + // this is detected, we won't try to send any jobs until the window is + // reloaded. + return + } + if (textEditor.isModified()) { // Abort for invalid or unsaved text editors const message = 'Linter-ESLint: Please save before fixing' @@ -280,6 +294,9 @@ module.exports = { atom.notifications.addSuccess(response) } } catch (err) { + if (err.name === 'IncompatibleESLintError') { + return + } atom.notifications.addWarning(err.message) } }, diff --git a/src/worker-helpers.js b/src/worker-helpers.js index a042ceaf..7375738a 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -14,6 +14,14 @@ const Cache = { LAST_MODULES_PATH: null } +class IncompatibleESLintError extends Error { + constructor(version) { + // eslint-disable-next-line max-len + super(`The version of ESLint used in this project is ${version}, which is incompatible with this package. The \`linter-eslint-node\` Atom package provides support for ESLint versions 8 and higher.\n\nYou can disable this notice in the linter-eslint package settings under **Uncommon → Notify when incompatible ESLint is detected**.`) + this.name = 'IncompatibleESLintError' + } +} + /** * Takes a path and translates `~` to the user's home directory, and replaces * all environment variables with their value. @@ -112,6 +120,27 @@ export function findESLintDirectory(modulesDir, config, projectPath, fallbackFor } } +// Given an ESLint module path, checks its version and throws if the version is +// too new for this package to support. +function checkForIncompatibleESLint(directory) { + let packageMeta + try { + // eslint-disable-next-line import/no-dynamic-require + packageMeta = require(Path.join(directory, 'package.json')) + if (!packageMeta || !packageMeta.version) { + return + } + } catch (_) { + return + } + // We don't need sophisticated parsing logic here; we just need to look at + // the major version. + const m = packageMeta.version.match(/^([\d]+)\./) + if (m && Number(m[1]) > 7) { + throw new IncompatibleESLintError(packageMeta.version) + } +} + /** * @param {string} modulesDir * @param {object} config @@ -120,10 +149,19 @@ export function findESLintDirectory(modulesDir, config, projectPath, fallbackFor */ export function getESLintFromDirectory(modulesDir, config, projectPath) { const { path: ESLintDirectory } = findESLintDirectory(modulesDir, config, projectPath) + let eslint try { // eslint-disable-next-line import/no-dynamic-require - return require(ESLintDirectory) + eslint = require(ESLintDirectory) + if (!('CLIEngine' in eslint)) { + checkForIncompatibleESLint(ESLintDirectory) + } + return eslint } catch (e) { + // If this is the result of an incompatible ESLint, an error will be + // thrown; otherwise we should proceed with the local-path fallback. + checkForIncompatibleESLint(ESLintDirectory) + if (config.global.useGlobalEslint && e.code === 'MODULE_NOT_FOUND') { throw new Error('ESLint not found, try restarting Atom to clear caches.') } diff --git a/src/worker.js b/src/worker.js index 1be054b8..e68aac80 100644 --- a/src/worker.js +++ b/src/worker.js @@ -99,7 +99,11 @@ module.exports = async () => { } emit(emitKey, response) } catch (workerErr) { - emit(`workerError:${emitKey}`, { msg: workerErr.message, stack: workerErr.stack }) + emit(`workerError:${emitKey}`, { + msg: workerErr.message, + stack: workerErr.stack, + name: workerErr.name + }) } }) }