diff --git a/eslint.flat.config.js b/eslint.flat.config.js index 7e87d1f7a498..55fbf87dd461 100644 --- a/eslint.flat.config.js +++ b/eslint.flat.config.js @@ -22,18 +22,26 @@ // MODULES // +var path = require( 'path' ); var globals = require( 'globals' ); +var tsParser = require( '@typescript-eslint/parser' ); +var tsPlugin = require( '@typescript-eslint/eslint-plugin' ); +var stylisticTs = require( '@stylistic/eslint-plugin-ts' ); var pluginN = require( 'eslint-plugin-n' ); var pluginCspell = require( '@cspell/eslint-plugin' ); var pluginJsdoc = require( 'eslint-plugin-jsdoc' ); +var pluginImport = require( 'eslint-plugin-import' ); +var pluginExpectType = require( 'eslint-plugin-expect-type' ); var assign = require( './lib/node_modules/@stdlib/object/assign' ); var stdlibPlugin = require( './lib/node_modules/@stdlib/_tools/eslint/rules/scripts/plugin.js' ); var restrictedSyntaxConfig = require( './etc/eslint/overrides/restricted_syntax.js' ); var rules = require( './etc/eslint/rules' ); +var tsRules = require( './etc/eslint/rules/typescript.js' ); // VARIABLES // +var tsGlobalVars; var globalVars; var config; @@ -42,6 +50,7 @@ var config; globalVars = assign( {}, globals.browser, globals.node ); globalVars = assign( globalVars, globals.commonjs, globals.worker ); +tsGlobalVars = assign( {}, globals.browser, globals.node ); config = [ // Global ignores: @@ -50,7 +59,10 @@ config = [ '**/build/', '**/reports/', 'dist/', - '.git*' + '.git*', + + // Un-ignore stdlib source (nested `node_modules` directories remain ignored by ESLint's defaults): + '!lib/node_modules/' ] }, @@ -122,6 +134,36 @@ config = [ }], 'no-restricted-syntax': restrictedSyntaxConfig } + }, + + // TypeScript declarations: + { + 'files': [ '**/*.d.ts' ], + 'languageOptions': { + 'parser': tsParser, + 'sourceType': 'module', + 'parserOptions': { + 'project': path.join( __dirname, 'tsconfig.json' ) + }, + 'globals': tsGlobalVars + }, + 'plugins': { + '@typescript-eslint': tsPlugin, + '@stylistic/ts': stylisticTs, + 'jsdoc': pluginJsdoc, + 'import': pluginImport, + 'expect-type': pluginExpectType, + 'stdlib': stdlibPlugin + }, + 'rules': tsRules + }, + + // TypeScript test files: + { + 'files': [ '**/test/**/*.ts' ], + 'rules': { + 'jsdoc/require-jsdoc': 'off' + } } ]; diff --git a/etc/eslint/eslint.flat.config.markdown.js b/etc/eslint/eslint.flat.config.markdown.js new file mode 100644 index 000000000000..00989dcd5d65 --- /dev/null +++ b/etc/eslint/eslint.flat.config.markdown.js @@ -0,0 +1,132 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var assign = require( './../../lib/node_modules/@stdlib/object/assign' ); +var defaults = require( './../../eslint.flat.config.js' ); + + +// VARIABLES // + +var config; +var entry; +var i; + + +// MAIN // + +/** +* ESLint flat configuration for linting Markdown code blocks. +*/ +config = [ + // Allow linting code blocks belonging to files residing under `node_modules` directories (e.g., package files residing under `lib/node_modules`), which ESLint unconditionally ignores by default: + { + 'ignores': [ '!**/node_modules/' ] + } +]; + +// Include the default configuration, ensuring that Markdown files are matched, as code blocks are linted using the path of the containing Markdown file: +for ( i = 0; i < defaults.length; i++ ) { + entry = defaults[ i ]; + if ( entry.files && entry.files.indexOf( '**/*.js' ) !== -1 ) { + entry = assign( {}, entry ); + entry.files = entry.files.concat( [ '**/*.md' ] ); + } + config.push( entry ); +} + +// Append configuration specific to Markdown code blocks: +config.push({ + 'linterOptions': { + // Do not flag unused disable directives, as the remark plugin unconditionally injects a `stdlib/require-order` disable directive when prepending the main `require` statement to subsequent code blocks: + 'reportUnusedDisableDirectives': 'off' + }, + 'rules': { + // Allow variables to be declared as needed: + 'vars-on-top': 'off', + + // Allow using synchronous methods: + 'n/no-sync': 'off', + + // Allow using `console`: + 'no-console': 'off', + + // Do not require `use strict` pragma: + 'strict': 'off', + + // Do not require an end-of-line character in code blocks: + 'eol-last': 'off', + + // Require `4` space indentation: + 'indent': [ 'error', 4, { + 'SwitchCase': 0, + 'VariableDeclarator': 1, + 'outerIIFEBody': 1, + 'MemberExpression': 1, + 'FunctionDeclaration': { + 'body': 1, + 'parameters': 'off' + }, + 'FunctionExpression': { + 'body': 1, + 'parameters': 'off' + }, + 'CallExpression': { + 'arguments': 'off' + }, + 'ArrayExpression': 1, + 'ObjectExpression': 1, + 'flatTernaryExpressions': true + }], + + // Never allow tabs: + 'no-tabs': 'error', + + // Do not require JSDoc comments: + 'jsdoc/require-jsdoc': 'off', + + // Do not require `@private` annotations: + 'stdlib/jsdoc-private-annotation': 'off', + + // Do not lint return annotation values in JSDoc comments (FIXME: remove this once we can reliably lint Markdown code blocks): + 'stdlib/jsdoc-return-annotations-values': 'off', + + // Do not enforce disallowing empty lines between module-level require statements: + 'stdlib/no-empty-lines-between-requires': 'off', + + // Allow requiring the package as a whole even though only a single property is used: + 'stdlib/no-single-property-require': 'off', + + // Allow use of undeclared variables, as variables may be defined in previous code blocks or be implied: + 'no-undef': 'off', + + // Allow unused variables, as variables may be illustrative or used in subsequent code blocks: + 'no-unused-vars': 'off', + + // Allow unpublished packages to be required in example code: + 'n/no-unpublished-require': 'off' + } +}); + + +// EXPORTS // + +module.exports = config; diff --git a/etc/npm/deps.txt b/etc/npm/deps.txt index f5db971ffee8..e9ba17002caf 100644 --- a/etc/npm/deps.txt +++ b/etc/npm/deps.txt @@ -1 +1 @@ -acorn@"^8.1.0" acorn-loose@"^8.0.2" acorn-walk@"^8.0.2" d3-format@"^1.0.0" d3-scale@"^1.0.0" d3-shape@"^1.0.0" d3-time-format@"^2.0.0" debug@"^2.6.9" glob@"^7.0.5" minimist@"^1.2.0" readable-stream@"^2.1.4" resolve@"^1.1.7" vdom-to-html@"^2.3.0" virtual-dom@"^2.1.1" 0x@"^4.10.2" @cspell/eslint-plugin@"^8.8.0" @commitlint/cli@"^17.4.4" @commitlint/cz-commitlint@"^17.4.4" @conventional-commits/parser@"^0.4.1" @kaciras/deasync@"^1.0.1" @types/node@"^13.9.0" @typescript-eslint/parser@"^8.57.0" @typescript-eslint/eslint-plugin@"^8.57.0" ajv@"^5.2.2" browser-pack-flat@"^3.0.0" browserify@"^17.0.0" bundle-collapser@"^1.3.0" c8@"^7.12.0" chai@"^3.5.0" cheerio@"^1.0.0-rc.12" commitizen@"^4.3.0" common-shakeify@"^0.6.0" conventional-changelog-conventionalcommits@"^5.0.0" doctrine@"^3.0.0" editorconfig-checker@"^6.0.0" envify@"^4.0.0" @stylistic/eslint-plugin-ts@"^2.13.0" eslint@"^8.57.0" eslint-plugin-n@"^17.17.0" eslint-plugin-expect-type@"^0.2.3" eslint-plugin-import@"^2.29.0" eslint-plugin-jsdoc@"^46.8.2" eslint-plugin-stdlib@"file:./etc/eslint/plugin" globals@"^16.1.0" exorcist@"^2.0.0" factor-bundle@"^2.5.0" gh-pages@"git+https://github.com/Planeshifter/gh-pages.git#main" inquirer@"^8.0.0" jscodeshift@"^0.15.0" jsdoc@"^3.4.0" lunr@"^2.3.9" mathjax-node@"^2.0.1" mathjax-node-sre@"^3.0.0" mkdirp@"^0.5.1" mustache@"^4.0.0" parse-link-header@"^1.0.1" plato@"^1.5.0" process@"^0.11.10" proxyquire@"^2.0.0" proxyquire-universal@"^2.0.0" proxyquireify@"^3.1.1" read-installed@"^4.0.3" rehype@"^9.0.0" rehype-highlight@"^3.0.0" remark@"^11.0.1" remark-cli@"^7.0.0" remark-frontmatter@"^1.2.0" remark-html@"^10.0.0" remark-lint@"^6.0.0" remark-lint-blockquote-indentation@"^1.0.0" remark-lint-checkbox-character-style@"^1.0.0" remark-lint-checkbox-content-indent@"^1.0.0" remark-lint-code-block-style@"^1.0.0" remark-lint-definition-case@"^1.0.0" remark-lint-definition-spacing@"^1.0.0" remark-lint-emphasis-marker@"^1.0.0" remark-lint-fenced-code-flag@"^1.0.0" remark-lint-fenced-code-marker@"^1.0.0" remark-lint-file-extension@"^1.0.0" remark-lint-final-definition@"^1.0.0" remark-lint-final-newline@"^1.0.0" remark-lint-first-heading-level@"^1.1.0" remark-lint-hard-break-spaces@"^1.0.1" remark-lint-heading-increment@"^1.0.0" remark-lint-heading-style@"^1.0.0" remark-lint-linebreak-style@"^1.0.0" remark-lint-link-title-style@"^1.0.0" remark-lint-list-item-bullet-indent@"^1.0.0" remark-lint-list-item-content-indent@"^1.0.0" remark-lint-list-item-indent@"^1.0.0" remark-lint-list-item-spacing@"^1.1.0" remark-lint-maximum-heading-length@"^1.0.0" remark-lint-maximum-line-length@"^1.0.0" remark-lint-no-auto-link-without-protocol@"^1.0.0" remark-lint-no-blockquote-without-marker@"^2.0.0" remark-lint-no-consecutive-blank-lines@"^1.0.0" remark-lint-no-duplicate-definitions@"^1.0.0" remark-lint-no-duplicate-headings@"^1.0.0" remark-lint-no-duplicate-headings-in-section@"^1.0.0" remark-lint-no-emphasis-as-heading@"^1.0.0" remark-lint-no-empty-url@"^1.0.1" remark-lint-no-file-name-articles@"^1.0.0" remark-lint-no-file-name-consecutive-dashes@"^1.0.0" remark-lint-no-file-name-irregular-characters@"^1.0.0" remark-lint-no-file-name-mixed-case@"^1.0.0" remark-lint-no-file-name-outer-dashes@"^1.0.1" remark-lint-no-heading-content-indent@"^1.0.0" remark-lint-no-heading-indent@"^1.0.0" remark-lint-no-heading-like-paragraph@"^1.0.0" remark-lint-no-heading-punctuation@"^1.0.0" remark-lint-no-html@"^1.0.0" remark-lint-no-inline-padding@"^1.0.0" remark-lint-no-literal-urls@"^1.0.0" remark-lint-no-missing-blank-lines@"^1.0.0" remark-lint-no-multiple-toplevel-headings@"^1.0.0" remark-lint-no-paragraph-content-indent@"^1.0.1" remark-lint-no-reference-like-url@"^1.0.0" remark-lint-no-shell-dollars@"^1.0.0" remark-lint-no-shortcut-reference-image@"^1.0.0" remark-lint-no-shortcut-reference-link@"^1.0.1" remark-lint-no-table-indentation@"^1.0.0" remark-lint-no-tabs@"^1.0.0" remark-lint-no-trailing-spaces@"^3.0.2" remark-lint-no-undefined-references@"^1.0.0" remark-lint-no-unused-definitions@"^1.0.0" remark-lint-ordered-list-marker-style@"^1.0.0" remark-lint-ordered-list-marker-value@"^1.0.0" remark-lint-rule-style@"^1.0.0" remark-lint-strong-marker@"^1.0.0" remark-lint-table-cell-padding@"^1.0.0" remark-lint-table-pipe-alignment@"^1.0.0" remark-lint-table-pipes@"^1.0.0" remark-lint-unordered-list-marker-style@"^1.0.0" remark-slug@"^5.0.0" remark-unlink@"^2.0.0" remark-validate-links@"^9.0.1" remark-vdom@"^8.0.0" semver@"^6.0.0" source-map-explorer@"^2.5.3" spdx-license-ids@"^3.0.0" tap-min@"git+https://github.com/Planeshifter/tap-min.git" tap-spec@"5.x.x" tap-summary@"^4.0.0" tap-xunit@"^2.2.0" tape@"git+https://github.com/kgryte/tape.git#fix/globby" to-vfile@"^6.0.0" typedoc@"git+https://github.com/kgryte/typedoc.git#0.16.11-patch" typescript@"4.9.5" uglify-js@"^3.17.4" uglifyify@"^5.0.0" unified-lint-rule@"^1.0.1" unist-util-visit@"^2.0.0" unist-util-visit-parents@"^3.1.1" yaml@"^1.0.0" node-gyp@"^9.3.1" +acorn@"^8.1.0" acorn-loose@"^8.0.2" acorn-walk@"^8.0.2" d3-format@"^1.0.0" d3-scale@"^1.0.0" d3-shape@"^1.0.0" d3-time-format@"^2.0.0" debug@"^2.6.9" glob@"^7.0.5" minimist@"^1.2.0" readable-stream@"^2.1.4" resolve@"^1.1.7" vdom-to-html@"^2.3.0" virtual-dom@"^2.1.1" 0x@"^4.10.2" @cspell/eslint-plugin@"^8.8.0" @commitlint/cli@"^17.4.4" @commitlint/cz-commitlint@"^17.4.4" @conventional-commits/parser@"^0.4.1" @kaciras/deasync@"^1.0.1" @types/node@"^13.9.0" @typescript-eslint/parser@"^8.57.0" @typescript-eslint/eslint-plugin@"^8.57.0" ajv@"^5.2.2" browser-pack-flat@"^3.0.0" browserify@"^17.0.0" bundle-collapser@"^1.3.0" c8@"^7.12.0" chai@"^3.5.0" cheerio@"^1.0.0-rc.12" commitizen@"^4.3.0" common-shakeify@"^0.6.0" conventional-changelog-conventionalcommits@"^5.0.0" doctrine@"^3.0.0" editorconfig-checker@"^6.0.0" envify@"^4.0.0" @stylistic/eslint-plugin-ts@"^2.13.0" eslint@"^9.0.0" eslint-plugin-n@"^17.17.0" eslint-plugin-expect-type@"^0.6.2" eslint-plugin-import@"^2.29.0" eslint-plugin-jsdoc@"^46.8.2" eslint-plugin-stdlib@"file:./etc/eslint/plugin" globals@"^16.1.0" exorcist@"^2.0.0" factor-bundle@"^2.5.0" gh-pages@"git+https://github.com/Planeshifter/gh-pages.git#main" inquirer@"^8.0.0" jscodeshift@"^0.15.0" jsdoc@"^3.4.0" lunr@"^2.3.9" mathjax-node@"^2.0.1" mathjax-node-sre@"^3.0.0" mkdirp@"^0.5.1" mustache@"^4.0.0" parse-link-header@"^1.0.1" plato@"^1.5.0" process@"^0.11.10" proxyquire@"^2.0.0" proxyquire-universal@"^2.0.0" proxyquireify@"^3.1.1" read-installed@"^4.0.3" rehype@"^9.0.0" rehype-highlight@"^3.0.0" remark@"^11.0.1" remark-cli@"^7.0.0" remark-frontmatter@"^1.2.0" remark-html@"^10.0.0" remark-lint@"^6.0.0" remark-lint-blockquote-indentation@"^1.0.0" remark-lint-checkbox-character-style@"^1.0.0" remark-lint-checkbox-content-indent@"^1.0.0" remark-lint-code-block-style@"^1.0.0" remark-lint-definition-case@"^1.0.0" remark-lint-definition-spacing@"^1.0.0" remark-lint-emphasis-marker@"^1.0.0" remark-lint-fenced-code-flag@"^1.0.0" remark-lint-fenced-code-marker@"^1.0.0" remark-lint-file-extension@"^1.0.0" remark-lint-final-definition@"^1.0.0" remark-lint-final-newline@"^1.0.0" remark-lint-first-heading-level@"^1.1.0" remark-lint-hard-break-spaces@"^1.0.1" remark-lint-heading-increment@"^1.0.0" remark-lint-heading-style@"^1.0.0" remark-lint-linebreak-style@"^1.0.0" remark-lint-link-title-style@"^1.0.0" remark-lint-list-item-bullet-indent@"^1.0.0" remark-lint-list-item-content-indent@"^1.0.0" remark-lint-list-item-indent@"^1.0.0" remark-lint-list-item-spacing@"^1.1.0" remark-lint-maximum-heading-length@"^1.0.0" remark-lint-maximum-line-length@"^1.0.0" remark-lint-no-auto-link-without-protocol@"^1.0.0" remark-lint-no-blockquote-without-marker@"^2.0.0" remark-lint-no-consecutive-blank-lines@"^1.0.0" remark-lint-no-duplicate-definitions@"^1.0.0" remark-lint-no-duplicate-headings@"^1.0.0" remark-lint-no-duplicate-headings-in-section@"^1.0.0" remark-lint-no-emphasis-as-heading@"^1.0.0" remark-lint-no-empty-url@"^1.0.1" remark-lint-no-file-name-articles@"^1.0.0" remark-lint-no-file-name-consecutive-dashes@"^1.0.0" remark-lint-no-file-name-irregular-characters@"^1.0.0" remark-lint-no-file-name-mixed-case@"^1.0.0" remark-lint-no-file-name-outer-dashes@"^1.0.1" remark-lint-no-heading-content-indent@"^1.0.0" remark-lint-no-heading-indent@"^1.0.0" remark-lint-no-heading-like-paragraph@"^1.0.0" remark-lint-no-heading-punctuation@"^1.0.0" remark-lint-no-html@"^1.0.0" remark-lint-no-inline-padding@"^1.0.0" remark-lint-no-literal-urls@"^1.0.0" remark-lint-no-missing-blank-lines@"^1.0.0" remark-lint-no-multiple-toplevel-headings@"^1.0.0" remark-lint-no-paragraph-content-indent@"^1.0.1" remark-lint-no-reference-like-url@"^1.0.0" remark-lint-no-shell-dollars@"^1.0.0" remark-lint-no-shortcut-reference-image@"^1.0.0" remark-lint-no-shortcut-reference-link@"^1.0.1" remark-lint-no-table-indentation@"^1.0.0" remark-lint-no-tabs@"^1.0.0" remark-lint-no-trailing-spaces@"^3.0.2" remark-lint-no-undefined-references@"^1.0.0" remark-lint-no-unused-definitions@"^1.0.0" remark-lint-ordered-list-marker-style@"^1.0.0" remark-lint-ordered-list-marker-value@"^1.0.0" remark-lint-rule-style@"^1.0.0" remark-lint-strong-marker@"^1.0.0" remark-lint-table-cell-padding@"^1.0.0" remark-lint-table-pipe-alignment@"^1.0.0" remark-lint-table-pipes@"^1.0.0" remark-lint-unordered-list-marker-style@"^1.0.0" remark-slug@"^5.0.0" remark-unlink@"^2.0.0" remark-validate-links@"^9.0.1" remark-vdom@"^8.0.0" semver@"^6.0.0" source-map-explorer@"^2.5.3" spdx-license-ids@"^3.0.0" tap-min@"git+https://github.com/Planeshifter/tap-min.git" tap-spec@"5.x.x" tap-summary@"^4.0.0" tap-xunit@"^2.2.0" tape@"git+https://github.com/kgryte/tape.git#fix/globby" to-vfile@"^6.0.0" typedoc@"git+https://github.com/kgryte/typedoc.git#0.16.11-patch" typescript@"4.9.5" uglify-js@"^3.17.4" uglifyify@"^5.0.0" unified-lint-rule@"^1.0.1" unist-util-visit@"^2.0.0" unist-util-visit-parents@"^3.1.1" yaml@"^1.0.0" node-gyp@"^9.3.1" diff --git a/etc/remark/plugins/eslint/index.js b/etc/remark/plugins/eslint/index.js index 0f3e2d5e75b9..eede4d548f3b 100644 --- a/etc/remark/plugins/eslint/index.js +++ b/etc/remark/plugins/eslint/index.js @@ -27,15 +27,13 @@ var join = require( 'path' ).join; // VARIABLES // var etc = resolve( __dirname, '..', '..', '..' ); -var config = join( etc, 'eslint', '.eslintrc.markdown.js' ); +var config = join( etc, 'eslint', 'eslint.flat.config.markdown.js' ); var eslint = resolve( etc, '..', 'lib', 'node_modules', '@stdlib', '_tools', 'remark', 'plugins', 'remark-lint-eslint' ); var opts = { 'config': config, 'rules': { 'stdlib/doctest': 'error' // enable otherwise disabled lint rule - }, - 'ignore': false, - 'useEslintrc': false + } }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-marker/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-marker/lib/main.js index 8cb9fc46d9d7..b0cfade42245 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-marker/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-marker/lib/main.js @@ -77,6 +77,10 @@ function checkComment( source, comment ) { if ( !token ) { return 'Encountered an orphaned return annotation without a preceding node'; } + // Ignore annotations on the same line as the preceding token: + if ( comment.loc.start.line === token.loc.end.line ) { + return null; + } // Check for orphaned annotation (preceding token is not on the same or previous line): if ( comment.loc.start.line - token.loc.end.line > 1 ) { return 'Encountered an orphaned return annotation without a preceding node'; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-quote-props/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-quote-props/test/fixtures/valid.js index 5ed24c68a3e4..0e72ddb6bb25 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-quote-props/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest-quote-props/test/fixtures/valid.js @@ -47,32 +47,6 @@ test = { }; valid.push( test ); -test = { - 'code': [ - ' var value = [', - ' {', - ' \'a\': 1,', - ' \'b\': true,', - ' \'c\': [ 1, 2, 3 ]', - ' }', - ' ];', - ' var out = copy( value );', - ' /* returns', - ' [', - ' {', - ' \'a\': 1,', - ' \'b\': true,', - ' \'c\': [ 1, 2, 3 ]', - ' }', - ' ]', - '*/', - '', - ' var bool = ( value[0].c === out[0].c );', - ' // returns false' - ].join( '\n' ) -}; -valid.push( test ); - test = { 'code': [ 'var target = {', diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/main.js index 8fab198588a2..ed4ff9a3e9b1 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/main.js @@ -25,6 +25,7 @@ var proc = require( 'process' ); var join = require( 'path' ).join; var format = require( 'util' ).format; var dirname = require( 'path' ).dirname; +var extname = require( 'path' ).extname; var logger = require( 'debug' ); var rootDir = require( '@stdlib/_tools/utils/root-dir' ); var Buffer = require( '@stdlib/buffer/ctor' ); @@ -162,6 +163,15 @@ function main( context ) { 'clearInterval': clearInterval, 'window': windowShim, 'Buffer': Buffer, + + // Share the host realm's error constructors, as required modules are loaded in the host realm, meaning that, without sharing, `instanceof` checks on host-created errors would always fail within the sandbox: + 'Error': Error, + 'EvalError': EvalError, + 'RangeError': RangeError, + 'ReferenceError': ReferenceError, + 'SyntaxError': SyntaxError, + 'TypeError': TypeError, + 'URIError': URIError, '__dirname': dir, '__filename': filename, 'console': { @@ -327,7 +337,7 @@ function main( context ) { }; // Do not report errors in `Markdown` fenced code blocks due to modules failing to load as implementations may not be available yet (readme-driven development): - if ( filename === '' && contains( err.message, 'Cannot find module' ) ) { + if ( ( filename === '' || extname( filename ) === '.md' ) && contains( err.message, 'Cannot find module' ) ) { return; } report( loc, 'Encountered an error while running code: '+err.message ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/scope_defaults.json b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/scope_defaults.json index fab6c5ea05dc..0a0ba4ec3f5f 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/scope_defaults.json +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/doctest/lib/scope_defaults.json @@ -9,6 +9,13 @@ "clearInterval", "window", "Buffer", + "Error", + "EvalError", + "RangeError", + "ReferenceError", + "SyntaxError", + "TypeError", + "URIError", "__dirname", "__filename", "console" diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/fixtures/valid.js index bd1ce1ce75fc..39c8f32459d4 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/fixtures/valid.js @@ -105,7 +105,7 @@ test = { 'var args = [ \'foo\' ];', 'var str = format( \'%s %s\', ...args );' ].join( '\n' ), - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2018 } }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/test.js index 38346420ddd9..215de0603f65 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/test.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/format-args/test/test.js @@ -42,7 +42,7 @@ tape( 'main export is an object', function test( t ) { tape( 'the function positively validates format calls which are provided an expected number of arguments', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); @@ -61,7 +61,7 @@ tape( 'the function positively validates format calls which are provided an expe tape( 'the function negatively validates format calls which are provided an unexpected number of arguments', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); @@ -80,7 +80,7 @@ tape( 'the function negatively validates format calls which are provided an unex tape( 'the function does not validate code not containing checkable format calls', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-checkbox-character-style/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-checkbox-character-style/test/fixtures/valid.js index 26de6966f456..cb2f3e7e4d17 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-checkbox-character-style/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-checkbox-character-style/test/fixtures/valid.js @@ -343,25 +343,6 @@ test = { }; valid.push( test ); -test = { - 'code': [ - '/**', - '* Beep boop.', - '*', - '* - [ ] Item', - '* - [X] Item', - '*/', - 'function beep() {', - ' console.log( "boop" );', - '}' - ].join( '\n' ), - 'options': [{ - 'checked': 'X', - 'unchecked': ' ' - }] -}; -valid.push( test ); - // EXPORTS // diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-heading-style/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-heading-style/test/fixtures/valid.js index 1e00e5ee46f3..f3c3a2088e27 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-heading-style/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-heading-style/test/fixtures/valid.js @@ -369,27 +369,6 @@ test = { }; valid.push( test ); -test = { - 'code': [ - '/**', - '* Beep boop.', - '*', - '* # Beep #', - '*', - '* boop', - '*', - '* ## Boop ##', - '*', - '* beep', - '*/', - 'function beep() {', - ' console.log( "boop" );', - '}' - ].join( '\n' ), - 'options': [ 'atx-closed' ] -}; -valid.push( test ); - test = { 'code': [ '/**', diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/unvalidated.js index 7c5c2629c7c8..8ed14a5bb5c1 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/unvalidated.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/unvalidated.js @@ -20,7 +20,7 @@ // MODULES // -var config = require( './config.js' ); +var configPath = require.resolve( './config.js' ); // VARIABLES // @@ -52,7 +52,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -77,7 +77,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -102,7 +102,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -127,7 +127,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/valid.js index 3070e63b5c21..d88b9fe38d6f 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/valid.js @@ -20,7 +20,7 @@ // MODULES // -var config = require( './config.js' ); +var configPath = require.resolve( './config.js' ); // VARIABLES // @@ -52,7 +52,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -75,7 +75,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -159,7 +159,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -199,7 +199,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -218,7 +218,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; @@ -269,7 +269,7 @@ test = { ].join( '\n' ), 'options': [ { - 'config': config + 'configPath': configPath } ] }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/test.js index 94d45d272a02..c2722e27278c 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/test.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/test.js @@ -22,6 +22,7 @@ var tape = require( 'tape' ); var RuleTester = require( 'eslint' ).RuleTester; +var Linter = require( 'eslint' ).Linter; var rule = require( './../lib' ); @@ -32,6 +33,33 @@ var invalid = require( './fixtures/invalid.js' ); var unvalidated = require( './fixtures/unvalidated.js' ); +// FUNCTIONS // + +/** +* Lints code using the legacy inline remark configuration. +* +* @private +* @param {string} code - code to lint +* @param {Array} options - rule options +* @returns {Array} lint messages +*/ +function lintCode( code, options ) { + var linter; + var config; + + linter = new Linter({ + 'configType': 'eslintrc' + }); + linter.defineRule( 'jsdoc-markdown-remark', rule ); + config = { + 'rules': { + 'jsdoc-markdown-remark': [ 'error' ].concat( options || [] ) + } + }; + return linter.verify( code, config ); +} + + // TESTS // tape( 'main export is an object', function test( t ) { @@ -61,7 +89,7 @@ tape( 'the function negatively validates code with JSDoc descriptions that conta try { tester.run( 'jsdoc-markdown-remark', rule, { 'valid': [], - 'invalid': invalid + 'invalid': invalid.slice( 1 ) }); t.pass( 'passed without errors' ); } catch ( err ) { @@ -70,6 +98,14 @@ tape( 'the function negatively validates code with JSDoc descriptions that conta t.end(); }); +tape( 'the function supports an inline remark configuration', function test( t ) { + var messages; + + messages = lintCode( invalid[ 0 ].code, invalid[ 0 ].options ); + t.strictEqual( messages.length, invalid[ 0 ].errors.length, 'returns expected errors' ); + t.end(); +}); + tape( 'the function does not validate non-JSDoc comments', function test( t ) { var tester = new RuleTester(); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-tag-spacing/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-tag-spacing/test/fixtures/valid.js index 730d71f8b419..8234263bdc31 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-tag-spacing/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-tag-spacing/test/fixtures/valid.js @@ -198,39 +198,6 @@ test = { }; valid.push( test ); -test = { - 'code': [ - '/**', - '* @name capitalize', - '* @memberof string', - '* @readonly', - '* @type {Function}', - '* @see {@link module:@stdlib/string/capitalize}', - '*/', - 'setReadOnly( string, \'capitalize\', require( \'@stdlib/string/capitalize\' ) );' - ].join( '\n' ) -}; -valid.push( test ); - -test = { - 'code': [ - '/**', - '* Squares a number.', - '* ', - '* @param {number} x - input number', - '* @returns {number} x squared', - '*', - '* @example', - '* var y = square( 2.0 );', - '* // returns 4.0', - '*/', - 'function square( x ) {', - ' return x*x;', - '}' - ].join( '\n' ) -}; -valid.push( test ); - test = { 'code': [ '/**', diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/invalid.js index df9e3d157182..f6de8bfedef7 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/invalid.js @@ -110,9 +110,11 @@ test = { 'type': 'ExportNamedDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; invalid.push( test ); @@ -131,9 +133,11 @@ test = { 'type': 'ExportNamedDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; invalid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/valid.js index 140d3c1ead54..b05bb3d52513 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/module-exports-last/test/fixtures/valid.js @@ -51,9 +51,11 @@ test = { '', 'export { gamma };' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; valid.push( test ); @@ -64,9 +66,11 @@ test = { 'export const beep = 0;', 'export default boop;' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; valid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/namespace-export-all/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/namespace-export-all/test/fixtures/invalid.js index 23de9c5d4bb8..0b2755eed453 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/namespace-export-all/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/namespace-export-all/test/fixtures/invalid.js @@ -97,7 +97,49 @@ test = { 'errors': [ { 'message': '`reviver` should be exported from namespace `index.js`', - 'type': null + 'type': null, + 'suggestions': [ + { + 'desc': 'Add `reviver` to the namespace `index.js`', + 'output': [ + '/*', + '* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.', + '*/', + '', + '// MODULES //', + '', + 'var setReadOnly = require( \'@stdlib/utils/define-read-only-property\' );', + '', + '', + '// MAIN //', + '', + '/**', + '* Top-level namespace.', + '*', + '* @namespace ns', + '*/', + 'var ns = {};', + '', + '/**', + '* @name reviver', + '* @memberof ns', + '* @readonly', + '* @type {Function}', + '* @see {@link module:@stdlib/error/reviver}', + '*/', + 'setReadOnly( ns, \'reviver\', require( \'@stdlib/error/reviver\' ) );', + '', + '/**', + '* @name error2json', + '* @memberof ns', + '* @readonly', + '* @type {Function}', + '* @see {@link module:@stdlib/error/to-json}', + '*/', + 'setReadOnly( ns, \'error2json\', require( \'@stdlib/error/to-json\' ) );' + ].join( '\n' ) + } + ] } ], 'filename': join( __dirname, 'error', 'lib', 'index.js' ) @@ -213,7 +255,69 @@ test = { 'errors': [ { 'message': '`conj` should be exported from namespace `index.js`', - 'type': null + 'type': null, + 'suggestions': [ + { + 'desc': 'Add `conj` to the namespace `index.js`', + 'output': [ + '\'use strict\';', + '', + '/*', + '* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.', + '*/', + '', + '// MODULES //', + '', + 'var setReadOnly = require( \'@stdlib/utils/define-read-only-property\' );', + '', + '', + '// MAIN //', + '', + '/**', + '* Top-level namespace.', + '*', + '* @namespace ns', + '*/', + 'var ns = {};', + '', + '/**', + '* @name complex', + '* @memberof ns', + '* @readonly', + '* @type {Function}', + '* @see {@link module:@stdlib/complex/cmplx}', + '*/', + 'setReadOnly( ns, \'complex\', require( \'@stdlib/complex/cmplx\' ) );', + '', + '/**', + '* @name conj', + '* @memberof ns', + '* @readonly', + '* @type {Function}', + '* @see {@link module:@stdlib/complex/conj}', + '*/', + 'setReadOnly( ns, \'conj\', require( \'@stdlib/complex/conj\' ) );', + '', + '/**', + '* @name Complex128', + '* @memberof ns', + '* @readonly', + '* @constructor', + '* @see {@link module:@stdlib/complex/float64/ctor}', + '*/', + 'setReadOnly( ns, \'Complex128\', require( \'@stdlib/complex/float64/ctor\' ) );', + '', + '/**', + '* @name Complex64', + '* @memberof ns', + '* @readonly', + '* @constructor', + '* @see {@link module:@stdlib/complex/float32/ctor}', + '*/', + 'setReadOnly( ns, \'Complex64\', require( \'@stdlib/complex/float32/ctor\' ) );' + ].join( '\n' ) + } + ] } ], 'filename': join( __dirname, 'complex', 'lib', 'index.js' ) diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/fixtures/valid.js index 303e6013c81d..6dd3c8372554 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/fixtures/valid.js @@ -41,15 +41,6 @@ test = { }; valid.push( test ); -test = { - 'code': [ - 'var BigInt = require( \'@stdlib/bigint/ctor\' );', - '', - 'var x = BigInt( 123 );' - ].join( '\n' ) -}; -valid.push( test ); - test = { 'code': [ 'var BigInt = require( \'@stdlib/bigint/ctor\' );', diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/test.js index 1bd0d761ceac..f0e9d8b891b7 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/test.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-builtin-big-int/test/test.js @@ -42,7 +42,7 @@ tape( 'main export is an object', function test( t ) { tape( 'the function positively validates code without the built-in global `BigInt` constructor or the BigInt literal syntax', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); @@ -61,7 +61,7 @@ tape( 'the function positively validates code without the built-in global `BigIn tape( 'the function negatively validates code with the built-in global `BigInt` constructor or the BigInt literal syntax', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); @@ -80,7 +80,7 @@ tape( 'the function negatively validates code with the built-in global `BigInt` tape( 'the function does not validate code without global `BigInt`s', function test( t ) { var tester = new RuleTester({ - 'parserOptions': { + 'languageOptions': { 'ecmaVersion': 2020 } }); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/invalid.js index bcdc217d226b..808ff937bc97 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/invalid.js @@ -52,9 +52,11 @@ test = { 'type': 'ExportDefaultDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; invalid.push( test ); @@ -110,9 +112,11 @@ test = { 'type': 'ExportDefaultDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; invalid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/valid.js index 692a42a6a1da..be2799527e80 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-dynamic-exports/test/fixtures/valid.js @@ -36,9 +36,11 @@ test = { '', 'export default betainc;' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; @@ -57,9 +59,11 @@ test = { '', 'export default foo;' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; @@ -97,9 +101,11 @@ test = { 'code': [ 'export default Object.create;' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; @@ -114,9 +120,11 @@ test = { 'code': [ 'export default 6;' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; @@ -173,9 +181,11 @@ test = { ' \'create\': main', '};' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js index a7e0415e659f..857b4d59d797 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-empty-lines-between-requires/test/fixtures/valid.js @@ -181,7 +181,7 @@ test = { '', 'var tape = require( \'tape\' );', '', - 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' ); // eslint-disable-line no-empty-lines-between-requires' + 'var isnan = require( \'@stdlib/math/base/assert/is-nan\' ); // eslint-disable-line rule-to-test/no-empty-lines-between-requires' ].join( '\n' ) }; valid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/lib/main.js index 6c9ddcc0bd66..5818612729e0 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/lib/main.js @@ -127,7 +127,7 @@ function main( context ) { for ( i = 0; i < scope.variables.length; i++ ) { variable = scope.variables[ i ]; ids = variable.identifiers; - hasBuiltin = opts.builtinGlobals && hasProp( variable, 'writeable' ); + hasBuiltin = opts.builtinGlobals && ( hasProp( variable, 'writeable' ) || hasProp( variable, 'writable' ) ); if ( hasBuiltin ) { if ( contains( opts.globalsWhitelist, variable.name ) ) { hasBuiltin = false; @@ -151,7 +151,8 @@ function main( context ) { * @param {ASTNode} node - program node. */ function checkForGlobal( node ) { - var parserOptions = context.parserOptions; + var languageOptions = context.languageOptions || {}; + var parserOptions = languageOptions.parserOptions || context.parserOptions || {}; var ecmaFeatures = parserOptions.ecmaFeatures || {}; var scope = source.getScope( node ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/invalid.js index 87b250da6067..ef1960c9b102 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/invalid.js @@ -58,6 +58,9 @@ test = { 'options': [{ 'builtinGlobals': true }], + 'languageOptions': { + 'sourceType': 'script' + }, 'errors': [ { 'message': 'Object is already defined', @@ -78,6 +81,9 @@ test = { 'options': [{ 'builtinGlobals': true }], + 'languageOptions': { + 'sourceType': 'script' + }, 'errors': [ { 'message': 'Float64Array is already defined', diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/valid.js index 09c9690988e1..abc22c3014a8 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-redeclare/test/fixtures/valid.js @@ -74,9 +74,11 @@ test = { 'options': [{ 'builtinGlobals': true }], - 'parserOptions': { - 'ecmaVersion': 2015, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 2015, + 'sourceType': 'module' + } } }; valid.push( test ); @@ -90,9 +92,11 @@ test = { 'options': [{ 'builtinGlobals': true }], - 'parserOptions': { - 'ecmaFeatures': { - 'globalReturn': true + 'languageOptions': { + 'parserOptions': { + 'ecmaFeatures': { + 'globalReturn': true + } } } }; diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/invalid.js index 8ab8317d8beb..e65727f24c00 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/invalid.js @@ -53,9 +53,11 @@ test = { 'type': 'ImportDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; invalid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/valid.js index 6fb237322de3..560a9002f4cf 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-self-require/test/fixtures/valid.js @@ -53,9 +53,11 @@ test = { 'import invalid from \'./invalid.js\';' ].join( '\n' ), 'filename': resolve( './valid.js' ), - 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6, + 'sourceType': 'module' + } } }; valid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-single-property-require/test/fixtures/unvalidated.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-single-property-require/test/fixtures/unvalidated.js index e8bbfb33a134..840632553b15 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-single-property-require/test/fixtures/unvalidated.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-single-property-require/test/fixtures/unvalidated.js @@ -42,8 +42,10 @@ unvalidated.push({ 'var { a } = require( \'foo\' );', 'a();' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6 + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6 + } } }); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/invalid.js index 67c6c1411eaf..902b37f73713 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/invalid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/invalid.js @@ -362,8 +362,10 @@ test = { 'type': 'FunctionDeclaration' } ], - 'parserOptions': { - 'ecmaVersion': 6 + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6 + } } }; invalid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/valid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/valid.js index e199de18a5db..7746a0430738 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/valid.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/no-unnecessary-nested-functions/test/fixtures/valid.js @@ -51,8 +51,10 @@ test = { ' return helper();', '}' ].join( '\n' ), - 'parserOptions': { - 'ecmaVersion': 6 + 'languageOptions': { + 'parserOptions': { + 'ecmaVersion': 6 + } } }; valid.push( test ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/require-file-extensions/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/require-file-extensions/lib/main.js index e7af4d6eb31a..90914ca7f2cf 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/require-file-extensions/lib/main.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/require-file-extensions/lib/main.js @@ -27,6 +27,7 @@ var hasOwnProp = require( '@stdlib/assert/has-own-property' ); var isString = require( '@stdlib/assert/is-string' ); var contains = require( '@stdlib/assert/contains' ); var dirname = require( '@stdlib/utils/dirname' ); +var extname = require( '@stdlib/utils/extname' ); var DELIMITER = require( '@stdlib/constants/path/delimiter' ); var ENV = require( '@stdlib/process/env' ); @@ -139,7 +140,7 @@ function main( context ) { return; } // Ignore error for internal requires in fenced code blocks of Markdown files as the package's implementation may not yet be available... - if ( filename === '' && startsWith( requirePath, '@stdlib' ) ) { + if ( ( filename === '' || extname( filename ) === '.md' ) && startsWith( requirePath, '@stdlib' ) ) { return; } return report( node, 'cannot resolve module: "'+requirePath+'"' ); diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/tsdoc-declarations-doctest/test/test.js b/lib/node_modules/@stdlib/_tools/eslint/rules/tsdoc-declarations-doctest/test/test.js index c06ff39a3c79..3f5437c36ab0 100644 --- a/lib/node_modules/@stdlib/_tools/eslint/rules/tsdoc-declarations-doctest/test/test.js +++ b/lib/node_modules/@stdlib/_tools/eslint/rules/tsdoc-declarations-doctest/test/test.js @@ -23,6 +23,7 @@ var tape = require( 'tape' ); var proxyquire = require( 'proxyquire' ); var RuleTester = require( 'eslint' ).RuleTester; +var tsParser = require( '@typescript-eslint/parser' ); var resolveParentPath = require( '@stdlib/fs/resolve-parent-path' ); // Mock the rule to work with renamed _package.json files: @@ -57,10 +58,12 @@ tape( 'main export is an object', function test( t ) { tape( 'the function positively validates code where all return annotations inside of example code match the actual output', function test( t ) { var tester = new RuleTester({ - 'parser': require.resolve( '@typescript-eslint/parser' ), - 'parserOptions': { - 'ecmaVersion': 2018, - 'sourceType': 'module' + 'languageOptions': { + 'parser': tsParser, + 'parserOptions': { + 'ecmaVersion': 2018, + 'sourceType': 'module' + } } }); @@ -78,10 +81,12 @@ tape( 'the function positively validates code where all return annotations insid tape( 'the function negatively validates code where not all return annotations inside of example code match the actual output', function test( t ) { var tester = new RuleTester({ - 'parser': require.resolve( '@typescript-eslint/parser' ), - 'parserOptions': { - 'ecmaVersion': 2018, - 'sourceType': 'module' + 'languageOptions': { + 'parser': tsParser, + 'parserOptions': { + 'ecmaVersion': 2018, + 'sourceType': 'module' + } } }); @@ -99,10 +104,12 @@ tape( 'the function negatively validates code where not all return annotations i tape( 'the function does not validate comments without TSDoc examples', function test( t ) { var tester = new RuleTester({ - 'parser': require.resolve( '@typescript-eslint/parser' ), - 'parserOptions': { - 'ecmaVersion': 2018, - 'sourceType': 'module' + 'languageOptions': { + 'parser': tsParser, + 'parserOptions': { + 'ecmaVersion': 2018, + 'sourceType': 'module' + } } }); diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/README.md b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/README.md index c686835933dc..360fb7a92082 100644 --- a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/README.md +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/README.md @@ -60,7 +60,7 @@ var vfile = linter( '```javascript\nvar beep = \'boop\';\n```' ); The function recognizes the following `options`: -- **config**: path to an [ESLint][eslint] configuration file. A configuration path is resolved relative to the current working directory of the calling process. +- **config**: path to an [ESLint][eslint] "flat" configuration file. A configuration path is resolved relative to the current working directory of the calling process. To specify configuration `options`, set the respective properties. @@ -71,7 +71,7 @@ var remark = require( 'remark' ); // Define options: var opts = { - 'config': '/path/to/.eslintrc' + 'config': '/path/to/eslint.config.js' }; // Create a plugin: @@ -196,9 +196,11 @@ var vfile = linter( '```javascript\nvar beep = \'boop\';\n```' ); ## Examples - + - + + + ```javascript var join = require( 'path' ).join; @@ -208,7 +210,7 @@ var readFileSync = require( '@stdlib/fs/read-file' ).sync; var factory = require( '@stdlib/_tools/remark/plugins/remark-lint-eslint' ).factory; // Define path to an ESLint config file: -var config = resolve( __dirname, '..', '..', '..', '..', '..', '..', '..', 'etc', 'eslint', '.eslintrc.markdown.js' ); +var config = resolve( __dirname, '..', '..', '..', '..', '..', '..', '..', 'etc', 'eslint', 'eslint.flat.config.markdown.js' ); // Load a Markdown file: var fpath = join( __dirname, 'examples', 'fixtures', 'file.md' ); @@ -220,10 +222,10 @@ var opts = { }; // Create a plugin: -var plugin = factory( opts ); +var lint = factory( opts ); // Lint code blocks: -var out = remark().use( plugin ).processSync( file.toString() ); +var out = remark().use( lint ).processSync( file.toString() ); console.log( out ); ``` diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/examples/index.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/examples/index.js index 64e696806cd8..88a4c565dec9 100644 --- a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/examples/index.js +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/examples/index.js @@ -16,6 +16,10 @@ * limitations under the License. */ +/* eslint stdlib/doctest: "off" */ + +// Note: executing this example via the `stdlib/doctest` rule would run the linter within the linter and deadlock; hence, the rule is disabled for this file. + 'use strict'; var join = require( 'path' ).join; @@ -25,7 +29,7 @@ var readFileSync = require( '@stdlib/fs/read-file' ).sync; var factory = require( './../lib' ).factory; // Define path to an ESLint config file: -var config = resolve( __dirname, '..', '..', '..', '..', '..', '..', '..', '..', 'etc', 'eslint', '.eslintrc.markdown.js' ); +var config = resolve( __dirname, '..', '..', '..', '..', '..', '..', '..', '..', 'etc', 'eslint', 'eslint.flat.config.markdown.js' ); // Load a Markdown file: var fpath = join( __dirname, 'fixtures', 'file.md' ); diff --git a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/lib/factory.js b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/lib/factory.js index f5d3fa2b6b4b..bc58d7ae577d 100644 --- a/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/lib/factory.js +++ b/lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-eslint/lib/factory.js @@ -33,6 +33,14 @@ var format = require( '@stdlib/string/format' ); var transformHTML = require( './transform_html.js' ); +// VARIABLES // + +// Resolve an ESLint class supporting "flat" configuration (note: in ESLint v9+, the default `ESLint` class supports "flat" configuration; in ESLint v8, a separate class must be explicitly loaded): +if ( parseInt( ESLint.version, 10 ) < 9 ) { + ESLint = require( 'eslint/use-at-your-own-risk' ).FlatESLint; // eslint-disable-line stdlib/require-file-extensions, stdlib/require-order +} + + // MAIN // /** @@ -70,9 +78,6 @@ function factory( options ) { if ( hasOwnProp( options, 'ignore' ) ) { opts.ignore = options.ignore; } - if ( hasOwnProp( options, 'useEslintrc' ) ) { - opts.useEslintrc = options.useEslintrc; - } // TODO: add support for other ESLint options } eslint = new ESLint( opts ); @@ -89,6 +94,14 @@ function factory( options ) { */ function lint( tree, file ) { var FIRST; + var fpath; + + // Resolve the path of the file being linted, which allows linting code blocks in the context of the containing file (e.g., resolving relative require paths and providing meaningful `__filename` and `__dirname` values when evaluating doctests): + if ( file.path ) { + fpath = resolve( cwd(), file.path ); + } else { + fpath = null; + } visit( tree, 'code', onNode ); /** @@ -152,7 +165,13 @@ function factory( options ) { code = comments.join( '\n' ); // Lint the code block... - awaitSync( eslint.lintText( code ).then( onLint ) ); + if ( fpath ) { + awaitSync( eslint.lintText( code, { + 'filePath': fpath + }).then( onLint ) ); + } else { + awaitSync( eslint.lintText( code ).then( onLint ) ); + } } /** diff --git a/lib/node_modules/@stdlib/string/format/README.md b/lib/node_modules/@stdlib/string/format/README.md index 3c32738b9a75..4e719778c5fe 100644 --- a/lib/node_modules/@stdlib/string/format/README.md +++ b/lib/node_modules/@stdlib/string/format/README.md @@ -121,7 +121,7 @@ out = format( str, 3.14159 ); str = '%g (shortest representation)'; out = format( str, 3.14159 ); -// returns '3.14159' +// returns '3.14159 (shortest representation)' ``` A conversion specification may contain zero or more flags, which modify the behavior of the conversion. The following flags are supported: @@ -174,7 +174,7 @@ out = format( str, 2 ); str = '%*i'; out = format( str, 5, 2 ); -// returns ' 2' +// returns ' 2' ``` The `precision` may be specified as a decimal integer or as an asterisk character (`*`), in which case the argument preceding the conversion specification is used as the precision value. The behavior of the `precision` differs depending on the conversion type: @@ -220,10 +220,10 @@ out = format( 'Pi: ~%.2f', 3.141592653589793 ); // returns 'Pi: ~3.14' out = format( '%-10s %-10s', 'a', 'b' ); -// returns 'a b ' +// returns 'a b ' out = format( '%10s %10s', 'a', 'b' ); -// returns ' a b' +// returns ' a b' out = format( '%2$s %1$s %3$s', 'b', 'a', 'c' ); // returns 'a b c' diff --git a/package.json b/package.json index d6672b72b383..7265a2174d01 100644 --- a/package.json +++ b/package.json @@ -142,9 +142,9 @@ "editorconfig-checker": "^6.0.0", "envify": "^4.0.0", "@stylistic/eslint-plugin-ts": "^2.13.0", - "eslint": "^8.57.0", + "eslint": "^9.0.0", "eslint-plugin-n": "^17.17.0", - "eslint-plugin-expect-type": "^0.2.3", + "eslint-plugin-expect-type": "^0.6.2", "eslint-plugin-import": "^2.29.0", "eslint-plugin-jsdoc": "^46.8.2", "eslint-plugin-stdlib": "file:./etc/eslint/plugin", diff --git a/tools/make/lib/lint/javascript/eslint.mk b/tools/make/lib/lint/javascript/eslint.mk index eda192fb5cb8..ca21c4d525e8 100644 --- a/tools/make/lib/lint/javascript/eslint.mk +++ b/tools/make/lib/lint/javascript/eslint.mk @@ -44,6 +44,9 @@ ESLINT_CONF_BENCHMARKS ?= $(CONFIG_DIR)/eslint/.eslintrc.benchmarks.js # Define the path to the ESLint ignore file: ESLINT_IGNORE ?= $(ROOT_DIR)/.eslintignore +# Use legacy config until build tooling switches to flat config: +export ESLINT_USE_FLAT_CONFIG := false + # Define the command-line options to use when invoking the ESLint executable: eslint_flags := \ --ignore-path $(ESLINT_IGNORE) \