diff --git a/eslint.flat.config.js b/eslint.flat.config.js
new file mode 100644
index 000000000000..7e87d1f7a498
--- /dev/null
+++ b/eslint.flat.config.js
@@ -0,0 +1,131 @@
+/**
+* @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.
+*/
+
+/* eslint-disable n/no-unpublished-require */
+
+'use strict';
+
+// MODULES //
+
+var globals = require( 'globals' );
+var pluginN = require( 'eslint-plugin-n' );
+var pluginCspell = require( '@cspell/eslint-plugin' );
+var pluginJsdoc = require( 'eslint-plugin-jsdoc' );
+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' );
+
+
+// VARIABLES //
+
+var globalVars;
+var config;
+
+
+// MAIN //
+
+globalVars = assign( {}, globals.browser, globals.node );
+globalVars = assign( globalVars, globals.commonjs, globals.worker );
+
+config = [
+ // Global ignores:
+ {
+ 'ignores': [
+ '**/build/',
+ '**/reports/',
+ 'dist/',
+ '.git*'
+ ]
+ },
+
+ // Base JavaScript config:
+ {
+ 'files': [ '**/*.js' ],
+ 'languageOptions': {
+ 'ecmaVersion': 6,
+ 'sourceType': 'script',
+ 'globals': globalVars
+ },
+ 'plugins': {
+ 'n': pluginN,
+ 'jsdoc': pluginJsdoc,
+ '@cspell': pluginCspell,
+ 'stdlib': stdlibPlugin
+ },
+ 'rules': rules
+ },
+
+ // REPL namespace files:
+ {
+ 'files': [ '**/lib/node_modules/@stdlib/**/lib/[a-z].js' ],
+ 'rules': {
+ 'stdlib/repl-namespace-order': 'error'
+ }
+ },
+
+ // Benchmarks:
+ {
+ 'files': [ '**/benchmark/**/*.js' ],
+ 'rules': {
+ 'no-new-wrappers': 'warn',
+ 'max-lines': [ 'warn', {
+ 'max': 1000,
+ 'skipBlankLines': true,
+ 'skipComments': true
+ }],
+ 'jsdoc/require-jsdoc': 'off',
+ 'no-restricted-syntax': restrictedSyntaxConfig
+ }
+ },
+
+ // Examples:
+ {
+ 'files': [ '**/examples/**/*.js' ],
+ 'rules': {
+ 'no-console': 'off',
+ 'vars-on-top': 'off',
+ 'jsdoc/require-jsdoc': 'off',
+ 'stdlib/jsdoc-private-annotation': 'off',
+ 'stdlib/require-order': 'off',
+ 'stdlib/require-file-extensions': 'off',
+ 'no-restricted-syntax': restrictedSyntaxConfig
+ }
+ },
+
+ // Tests:
+ {
+ 'files': [ '**/test/**/*.js' ],
+ 'rules': {
+ 'no-empty-function': 'off',
+ 'jsdoc/require-jsdoc': 'off',
+ 'no-undefined': 'off',
+ 'max-lines': [ 'warn', {
+ 'max': 1000,
+ 'skipBlankLines': true,
+ 'skipComments': true
+ }],
+ 'no-restricted-syntax': restrictedSyntaxConfig
+ }
+ }
+];
+
+
+// EXPORTS //
+
+module.exports = config;
diff --git a/etc/eslint/overrides/index.js b/etc/eslint/overrides/index.js
index 8133780619d1..6b45d71d8051 100644
--- a/etc/eslint/overrides/index.js
+++ b/etc/eslint/overrides/index.js
@@ -21,48 +21,7 @@
// MODULES //
var resolve = require( 'path' ).resolve;
-
-
-// VARIABLES //
-
-var restrictedSyntaxConfig = [ 'error',
- 'ArrowFunctionExpression',
- 'ClassBody',
- 'ClassDeclaration',
- 'ClassExpression',
- 'DebuggerStatement',
- 'ExperimentalRestProperty',
- 'ExperimentalSpreadProperty',
-
- // 'FunctionExpression',
- 'LabeledStatement',
- 'RestElement',
- 'SpreadElement',
- 'TaggedTemplateExpression',
- 'TemplateElement',
- 'TemplateLiteral',
- 'WithStatement',
- 'YieldExpression',
- 'JSXIdentifier',
- 'JSXNamespacedName',
- 'JSXMemberExpression',
- 'JSXEmptyExpression',
- 'JSXExpressionContainer',
- 'JSXElement',
- 'JSXClosingElement',
- 'JSXOpeningElement',
- 'JSXAttribute',
- 'JSXSpreadAttribute',
- 'JSXText',
- 'ExportDefaultDeclaration',
- 'ExportNamedDeclaration',
- 'ExportAllDeclaration',
- 'ExportSpecifier',
- 'ImportDeclaration',
- 'ImportSpecifier',
- 'ImportDefaultSpecifier',
- 'ImportNamespaceSpecifier'
-];
+var restrictedSyntaxConfig = require( './restricted_syntax.js' );
// MAIN //
diff --git a/etc/eslint/overrides/restricted_syntax.js b/etc/eslint/overrides/restricted_syntax.js
new file mode 100644
index 000000000000..d33a9d190bb7
--- /dev/null
+++ b/etc/eslint/overrides/restricted_syntax.js
@@ -0,0 +1,65 @@
+/**
+* @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';
+
+// MAIN //
+
+var rule = [ 'error',
+ 'ArrowFunctionExpression',
+ 'ClassBody',
+ 'ClassDeclaration',
+ 'ClassExpression',
+ 'DebuggerStatement',
+ 'ExperimentalRestProperty',
+ 'ExperimentalSpreadProperty',
+
+ // 'FunctionExpression',
+ 'LabeledStatement',
+ 'RestElement',
+ 'SpreadElement',
+ 'TaggedTemplateExpression',
+ 'TemplateElement',
+ 'TemplateLiteral',
+ 'WithStatement',
+ 'YieldExpression',
+ 'JSXIdentifier',
+ 'JSXNamespacedName',
+ 'JSXMemberExpression',
+ 'JSXEmptyExpression',
+ 'JSXExpressionContainer',
+ 'JSXElement',
+ 'JSXClosingElement',
+ 'JSXOpeningElement',
+ 'JSXAttribute',
+ 'JSXSpreadAttribute',
+ 'JSXText',
+ 'ExportDefaultDeclaration',
+ 'ExportNamedDeclaration',
+ 'ExportAllDeclaration',
+ 'ExportSpecifier',
+ 'ImportDeclaration',
+ 'ImportSpecifier',
+ 'ImportDefaultSpecifier',
+ 'ImportNamespaceSpecifier'
+];
+
+
+// EXPORTS //
+
+module.exports = rule;
diff --git a/etc/eslint/rules/stdlib.js b/etc/eslint/rules/stdlib.js
index 1c84b79de46c..806287f8f0cc 100644
--- a/etc/eslint/rules/stdlib.js
+++ b/etc/eslint/rules/stdlib.js
@@ -1,4 +1,4 @@
-/* eslint-disable stdlib/jsdoc-doctest-marker, stdlib/jsdoc-doctest, stdlib/jsdoc-example-require-spacing, stdlib/jsdoc-no-tabs */
+/* eslint-disable stdlib/jsdoc-doctest-marker, stdlib/jsdoc-example-require-spacing, stdlib/jsdoc-no-tabs */
/**
* @license Apache-2.0
@@ -1720,7 +1720,7 @@ rules[ 'stdlib/jsdoc-list-item-spacing' ] = 'error';
*/
rules[ 'stdlib/jsdoc-markdown-remark' ] = [ 'error',
{
- 'config': require( './../../remark/.remarkrc.jsdoc.js' )
+ 'configPath': require.resolve( './../../remark/.remarkrc.jsdoc.js' )
}
];
diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/README.md b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/README.md
index 43dea465621b..d764a819c5ff 100644
--- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/README.md
+++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/README.md
@@ -84,6 +84,16 @@ function beep() {
+
+
+## Notes
+
+- To keep rule options serializable (e.g., when using an ESLint flat config), set the `configPath` option to an absolute path for a CommonJS module which exports a remark configuration.
+
+
+
+
+
## Examples
@@ -97,12 +107,9 @@ var noDuplicateHeadings = require( 'remark-lint-no-duplicate-headings' );
var rule = require( '@stdlib/_tools/eslint/rules/jsdoc-markdown-remark' );
var linter = new Linter();
-var config;
-var result;
-var code;
// Generate our source code containing a single lint error (a duplicate heading):
-code = [
+var code = [
'/**',
'* Beep boop.',
'*',
@@ -150,7 +157,7 @@ code = [
].join( '\n' );
// Create a remark configuration:
-config = {
+var config = {
'plugins': [
[ remarkLint ],
[ noDuplicateHeadings, [ 'error' ] ]
@@ -161,7 +168,7 @@ config = {
linter.defineRule( 'jsdoc-markdown-remark', rule );
// Lint the code:
-result = linter.verify( code, {
+var result = linter.verify( code, {
'rules': {
'jsdoc-markdown-remark': [ 'error', {
'config': config
diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/lib/main.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/lib/main.js
index 2081e110d0dd..88bba2133419 100644
--- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/lib/main.js
+++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/lib/main.js
@@ -46,18 +46,19 @@ var rule;
*/
function main( context ) {
var options;
+ var config;
var source;
var lint;
- var opts;
options = context.options[ 0 ];
- opts = {};
- if ( hasOwnProp( options, 'config' ) ) {
- opts.config = options.config;
+ if ( hasOwnProp( options, 'configPath' ) ) {
+ config = require( options.configPath ); // eslint-disable-line stdlib/no-dynamic-require
+ } else if ( hasOwnProp( options, 'config' ) ) {
+ config = options.config;
} else {
- opts.config = {};
+ config = {};
}
- lint = remark().use( opts.config ).processSync;
+ lint = remark().use( config ).processSync;
source = context.sourceCode;
return {
@@ -151,6 +152,9 @@ rule = {
'properties': {
'config': {
'type': 'object'
+ },
+ 'configPath': {
+ 'type': 'string'
}
},
'additionalProperties': false
diff --git a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/invalid.js b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/invalid.js
index 639ad6f1c220..bafee125621c 100644
--- a/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/invalid.js
+++ b/lib/node_modules/@stdlib/_tools/eslint/rules/jsdoc-markdown-remark/test/fixtures/invalid.js
@@ -23,41 +23,49 @@
var config = require( './config.js' );
-// VARIABLES //
-
-var invalid;
-var test;
-
-
// MAIN //
// Create our test cases:
-invalid = [];
+var invalid = [];
-test = {
- 'code': [
- '/**',
- '* Beep boop.',
- '*',
- '* ## Beep',
- '*',
- '* ## Beep',
- '*/',
- 'function beep() {',
- ' console.log( "boop" );',
- '}'
- ].join( '\n' ),
+var code = [
+ '/**',
+ '* Beep boop.',
+ '*',
+ '* ## Beep',
+ '*',
+ '* ## Beep',
+ '*/',
+ 'function beep() {',
+ ' console.log( "boop" );',
+ '}'
+].join( '\n' );
+var errors = [
+ {
+ 'message': '5:1-5:8 error Do not use headings with similar content (3:1) no-duplicate-headings remark-lint',
+ 'type': null
+ }
+];
+
+var test = {
+ 'code': code,
'options': [
{
'config': config
}
],
- 'errors': [
+ 'errors': errors
+};
+invalid.push( test );
+
+test = {
+ 'code': code,
+ 'options': [
{
- 'message': '5:1-5:8 error Do not use headings with similar content (3:1) no-duplicate-headings remark-lint',
- 'type': null
+ 'configPath': require.resolve( './config.js' )
}
- ]
+ ],
+ 'errors': errors
};
invalid.push( test );
diff --git a/package.json b/package.json
index aab0d6a5bace..d6672b72b383 100644
--- a/package.json
+++ b/package.json
@@ -148,6 +148,7 @@
"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",