diff --git a/eslint.config.mjs b/eslint.config.mjs index b146b0c68..c5ce0999d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -20,7 +20,7 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import path from 'node:path' import { fileURLToPath } from 'node:url' -import { default as baseCfg, globals } from './tools/code-style/eslint.config.mjs' +import baseCfg, { globals } from './tools/code-style/eslint.config.mjs' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -36,7 +36,7 @@ export default [ { name: 'project-specific', rules: { - "complexity": ["error", { "max": 15 }] + complexity: ['error', { max: 15 }] } }, { @@ -55,7 +55,7 @@ export default [ { files: [ '**/*.{test,spec}.{js,mjs,cjs,ts}', - 'tests/**.{js,mjs,cjs,ts}' + 'tests/**/*.{js,mjs,cjs,ts}' ], languageOptions: { globals: globals.mocha diff --git a/tests/_data/models.js b/tests/_data/models.js index bde30996c..6974ff932 100644 --- a/tests/_data/models.js +++ b/tests/_data/models.js @@ -301,7 +301,7 @@ function createComplexStructure () { ['encode anyUri: mailto', 'mailto:info@example.org'], ['encode anyUri: relative path', '../foo/bar'], ['encode anyUri: space', 'https://example.org/foo bar bazz%20again+again'], - ['encode anyUri: quotation', `https://example.org/this"test"isa'test'`], + ['encode anyUri: quotation', 'https://example.org/this"test"isa\'test\''], ['encode anyUri: []', 'https://example.org/?bar[test]=baz[again]'], ['encode anyUri: <>', 'https://example.org/#'], ['encode anyUri: {}', 'https://example.org/#{test}{again}'], @@ -609,7 +609,6 @@ function createComplexStructure () { return bom } - /** * @returns {Models.Bom} */ @@ -671,7 +670,6 @@ function createAllTools () { return bom } - module.exports = { createAllTools, createComplexStructure diff --git a/tests/_data/specLoader.spec.js b/tests/_data/specLoader.spec.js index c63107f15..8bb361ec7 100644 --- a/tests/_data/specLoader.spec.js +++ b/tests/_data/specLoader.spec.js @@ -24,8 +24,7 @@ const { suite, test } = require('mocha') const { getSpecElement, getSpecEnum, loadSpec } = require('./specLoader') suite('test helpers: specLoader', () => { - - const expected_definitions_affectedStatus_enum = [ + const expectedDefinitionsAffectedStatusEnum = [ 'affected', 'unaffected', 'unknown' @@ -42,7 +41,7 @@ suite('test helpers: specLoader', () => { test('happy path', () => { const loaded = loadSpec('bom-1.4.SNAPSHOT.schema.json') // dummy test to see if loading worked somehow ... - assert.deepStrictEqual(loaded.definitions.affectedStatus.enum, expected_definitions_affectedStatus_enum) + assert.deepStrictEqual(loaded.definitions.affectedStatus.enum, expectedDefinitionsAffectedStatusEnum) }) }) @@ -59,7 +58,7 @@ suite('test helpers: specLoader', () => { 'bom-1.4.SNAPSHOT.schema.json', 'definitions', 'affectedStatus', 'enum') // dummy test to see if loading worked somehow ... - assert.deepStrictEqual(loaded, expected_definitions_affectedStatus_enum) + assert.deepStrictEqual(loaded, expectedDefinitionsAffectedStatusEnum) }) }) @@ -69,7 +68,7 @@ suite('test helpers: specLoader', () => { 'bom-1.4.SNAPSHOT.schema.json', 'affectedStatus') // dummy test to see if loading worked somehow ... - assert.deepStrictEqual(loaded, expected_definitions_affectedStatus_enum) + assert.deepStrictEqual(loaded, expectedDefinitionsAffectedStatusEnum) }) }) }) diff --git a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js index d63f09ac1..f96b5f34f 100644 --- a/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js +++ b/tests/integration/Builders.FromNodePackageJson.ComponentBuilder.test.js @@ -60,8 +60,8 @@ suite('integration: Builders.FromNodePackageJson.ComponentBuilder', () => { } ], repository: { - type: "git", - url: "https://github.com/foo/bar.git" + type: 'git', + url: 'https://github.com/foo/bar.git' } // to be continued }, diff --git a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js b/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js index 6c16daa73..e2d53c252 100644 --- a/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js +++ b/tests/integration/Factories.FromNodePackageJson.ExternalReferenceFactory.test.js @@ -104,7 +104,7 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () ExternalReferenceType.VCS, { comment: 'as detected from PackageJson property "repository"' } )] - const data = { repository: '../foo/bar' } + const data = { repository: '../foo/bar' } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) @@ -114,7 +114,7 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () ExternalReferenceType.VCS, { comment: 'as detected from PackageJson property "repository"' } )] - const data = { repository: 'git@example.com:foo/bar'} + const data = { repository: 'git@example.com:foo/bar' } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) @@ -134,19 +134,19 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () ExternalReferenceType.VCS, { comment: 'as detected from PackageJson property "repository"' } )] - const data = { repository: 'svn://example.com/foo/trunk' } + const data = { repository: 'svn://example.com/foo/trunk' } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) test('empty string', () => { const expected = [] - const data = { repository: '' } + const data = { repository: '' } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) test('undefined', () => { const expected = [] - const data = { } + const data = { } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) @@ -168,7 +168,7 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () ExternalReferenceType.VCS, { comment: 'as detected from PackageJson property "repository.url"' } )] - const data = { repository: { url: 'git@example.com:foo/bar'} } + const data = { repository: { url: 'git@example.com:foo/bar' } } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) @@ -200,7 +200,7 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () }) test('undefined', () => { const expected = [] - const data = { repository: { } } + const data = { repository: { } } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) @@ -222,7 +222,7 @@ suite('integration: Factories.FromNodePackageJson.ExternalReferenceFactory', () ExternalReferenceType.VCS, { comment: 'as detected from PackageJson property "repository.url" and "repository.directory"' } )] - const data = { repository: { url: 'git@example.com:foo/bar', directory: 'some/other#23/dir#42'} } + const data = { repository: { url: 'git@example.com:foo/bar', directory: 'some/other#23/dir#42' } } const actual = sut.makeExternalReferences(data) assert.deepEqual(actual, expected) }) diff --git a/tests/integration/Serialize.JsonSerialize.test.js b/tests/integration/Serialize.JsonSerialize.test.js index 978e4462f..dff54df0c 100644 --- a/tests/integration/Serialize.JsonSerialize.test.js +++ b/tests/integration/Serialize.JsonSerialize.test.js @@ -37,7 +37,7 @@ const { createAllTools, createComplexStructure } = require('../_data/models') const { loadSerializeResult, writeSerializeResult } = require('../_data/serialize') describe('integration.Serialize.JsonSerialize', function () { - this.timeout(60000); + this.timeout(60000) Object.entries({ complex: createComplexStructure, diff --git a/tests/integration/Serialize.XmlSerialize.test.js b/tests/integration/Serialize.XmlSerialize.test.js index b74c36342..28e709146 100644 --- a/tests/integration/Serialize.XmlSerialize.test.js +++ b/tests/integration/Serialize.XmlSerialize.test.js @@ -37,7 +37,7 @@ const { loadSerializeResult, writeSerializeResult } = require('../_data/serializ describe('integration.Serialize.XmlSerialize', function () { const expectMissingDepError = xmlStringify.fails ?? false - this.timeout(60000); + this.timeout(60000) Object.entries({ complex: createComplexStructure, @@ -100,7 +100,6 @@ describe('integration.Serialize.XmlSerialize', function () { // TODO add more tests })) - })) describe('make bom-refs unique', () => { diff --git a/tests/unit/Models.bomLink.spec.js b/tests/unit/Models.bomLink.spec.js index 34bb9ba10..13921e88b 100644 --- a/tests/unit/Models.bomLink.spec.js +++ b/tests/unit/Models.bomLink.spec.js @@ -25,7 +25,6 @@ const { Models: { BomLinkDocument, BomLinkElement } } = require('../../') - suite('unit: Models.BomLinkDocument', () => { suite('isValid()', () => { test('pass', () => { diff --git a/tests/unit/Serialize.BomRefDiscriminator.spec.js b/tests/unit/Serialize.BomRefDiscriminator.spec.js index 581a5eb33..89367e229 100644 --- a/tests/unit/Serialize.BomRefDiscriminator.spec.js +++ b/tests/unit/Serialize.BomRefDiscriminator.spec.js @@ -33,7 +33,6 @@ suite('unit: Serialize.BomRefDiscriminator', () => { const bomRef2 = new BomRef('foo') const prefix = randomString(10) - const actual = new BomRefDiscriminator([bomRef1, bomRef2], prefix) assert.strictEqual(actual.prefix, prefix) @@ -65,7 +64,6 @@ suite('unit: Serialize.BomRefDiscriminator', () => { assert.strictEqual(bomRef1.value, 'foo') assert.strictEqual(bomRef2.value, 'foo') - const discriminator = new BomRefDiscriminator([bomRef1, bomRef2]) discriminator.discriminate() diff --git a/tests/unit/Serialize.JsonSerializer.spec.js b/tests/unit/Serialize.JsonSerializer.spec.js index eb3c5e263..c2bd55576 100644 --- a/tests/unit/Serialize.JsonSerializer.spec.js +++ b/tests/unit/Serialize.JsonSerializer.spec.js @@ -40,7 +40,7 @@ suite('unit: Serialize.JsonSerializer', () => { const normalizerFactoryDummy = { spec: { supportsFormat: f => f !== Format.JSON } } assert.throws( () => { - + /* eslint-disable-next-line no-new -- needed to test constructor */ new JsonSerializer(normalizerFactoryDummy) }, UnsupportedFormatError, diff --git a/tests/unit/Serialize.XML._xsd.spec.js b/tests/unit/Serialize.XML._xsd.spec.js index 8ef2a51e8..a2827a71e 100644 --- a/tests/unit/Serialize.XML._xsd.spec.js +++ b/tests/unit/Serialize.XML._xsd.spec.js @@ -29,14 +29,14 @@ const { suite('unit: Serialize.XML._xsd', () => { const normalizedStringCases = { '': '', - '123': '123', + 123: '123', ' 0 1\r\n2\t3\n4\t': ' 0 1 2 3 4 ', ' 0 1\r\n 2 \t3 \n 4 \t': ' 0 1 2 3 4 ', } const tokenCases = { '': '', - '123': '123', + 123: '123', ' 0 1 \r\n2\t 3 \n4\n ': '0 1 2 3 4', ' 0 1\r\n 2 \t3 \n 4 \t ': '0 1 2 3 4', } @@ -45,7 +45,7 @@ suite('unit: Serialize.XML._xsd', () => { * @param {string} s * @return {string} */ - function escapeTNR(s) { + function escapeTNR (s) { return s .replace(/\t/g, '\\t') .replace(/\n/g, '\\n') diff --git a/tests/unit/Serialize.XmlBaseSerializer.spec.js b/tests/unit/Serialize.XmlBaseSerializer.spec.js index c94edb57d..f8fbc2f10 100644 --- a/tests/unit/Serialize.XmlBaseSerializer.spec.js +++ b/tests/unit/Serialize.XmlBaseSerializer.spec.js @@ -41,7 +41,7 @@ suite('unit: Serialize.XmlBaseSerializer', () => { const normalizerFactoryDummy = { spec: { supportsFormat: f => f !== Format.XML } } assert.throws( () => { - + /* eslint-disable-next-line no-new -- needed to test constructor */ new MySerializer(normalizerFactoryDummy) }, UnsupportedFormatError, diff --git a/tests/unit/Serialize.XmlSerializer.spec.js b/tests/unit/Serialize.XmlSerializer.spec.js index 376a3e290..50287aaf8 100644 --- a/tests/unit/Serialize.XmlSerializer.spec.js +++ b/tests/unit/Serialize.XmlSerializer.spec.js @@ -40,7 +40,7 @@ suite('unit: Serialize.XmlSerializer', () => { const normalizerFactoryDummy = { spec: { supportsFormat: f => f !== Format.XML } } assert.throws( () => { - + /* eslint-disable-next-line no-new -- needed to test constructor */ new XmlSerializer(normalizerFactoryDummy) }, UnsupportedFormatError, diff --git a/tools/code-style/eslint.config.mjs b/tools/code-style/eslint.config.mjs index 58eeb0210..1df070842 100644 --- a/tools/code-style/eslint.config.mjs +++ b/tools/code-style/eslint.config.mjs @@ -20,9 +20,8 @@ Copyright (c) OWASP Foundation. All Rights Reserved. import path from 'node:path' import { fileURLToPath } from 'node:url' -import plugin_js from '@eslint/js' +/* eslint-disable camelcase -- readability */ import config_love from 'eslint-config-love' -import plugin_editorconfig from 'eslint-plugin-editorconfig' import plugin_import from 'eslint-plugin-import' import plugin_jsdoc from 'eslint-plugin-jsdoc' import plugin_header from 'eslint-plugin-license-header' @@ -30,6 +29,7 @@ import plugin_n from 'eslint-plugin-n' import plugin_simpleImportSort from 'eslint-plugin-simple-import-sort' import plugin_tsdoc from 'eslint-plugin-tsdoc' import globals from 'globals' +import config_neostandard from 'neostandard' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -40,28 +40,41 @@ const licenseHeaderFile = path.join(projectRoot, '.license-header.js') /* eslint-disable jsdoc/valid-types -- type-import not supported yet */ /** - * @type {import('eslint').Linter.Config[]} + * @typedef {import('eslint').Linter.Config} Config + */ + +/** + * @param {Array} files + * @param {Config[]} cs + * @return {Config[]} + */ +function configSetFiles (files, cs) { + for (const c of cs) { + c.files = files + } + return cs +} + +/** + * @type {Config[]} * @see https://eslint.org/ */ export default [ { name: 'general', plugins: { - 'import': plugin_import, + import: plugin_import, 'simple-import-sort': plugin_simpleImportSort, 'license-header': plugin_header, - 'editorconfig': plugin_editorconfig, - 'n': plugin_n, + n: plugin_n, }, rules: { - ...plugin_editorconfig.configs.all.rules, - 'editorconfig/indent': 'off', 'n/prefer-node-protocol': 'error', 'sort-imports': 'off', 'import/order': [ // https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md 'error', { - 'groups': [ + groups: [ 'builtin', 'external', /* and then all the rest */ @@ -76,98 +89,97 @@ export default [ 'license-header/header': ['error', licenseHeaderFile], }, }, + ...configSetFiles(['**/*.{js,mjs,cjs}'], [ + ...config_neostandard({ noJsx: true, ts: false }), + { + ...plugin_jsdoc.configs['flat/recommended'], + }, + { + name: 'jsdoc-override', + plugins: { + jsdoc: plugin_jsdoc, + }, + settings: { + jsdoc: { + mode: 'jsdoc', + }, + }, + rules: { + 'jsdoc/no-undefined-types': 'error', + 'jsdoc/check-tag-names': 0, + 'jsdoc/check-types': 'error', + 'jsdoc/require-hyphen-before-param-description': ['error', 'always'], + 'jsdoc/require-jsdoc': 0, + 'jsdoc/require-param': 0, + 'jsdoc/require-param-description': 0, + 'jsdoc/require-param-name': 'error', + 'jsdoc/require-param-type': 'error', + 'jsdoc/require-property': 0, + 'jsdoc/require-property-description': 0, + 'jsdoc/require-property-name': 'error', + 'jsdoc/require-property-type': 'error', + 'jsdoc/require-returns': 0, + 'jsdoc/require-returns-check': 'error', + 'jsdoc/require-returns-description': 0, + 'jsdoc/require-returns-type': 'error', + 'jsdoc/require-throws': 'error', + 'jsdoc/require-yields': 0, + 'jsdoc/require-yields-check': 'error', + 'jsdoc/sort-tags': 'warn', + } + }, + ]), { + name: 'import order for commonjs', files: ['**/*.{js,cjs}'], rules: { + // rules dont support mjs properly 'simple-import-sort/imports': 'off', 'import/order': [ // https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md 'error', { - 'groups': [ + groups: [ 'builtin', 'external', /* and then all the rest */ ], - 'alphabetize': { order: "asc" }, - 'named': true, + alphabetize: { order: 'asc' }, + named: true, 'newlines-between': 'always', }], } }, - { - files: ['**/*.{js,mjs,cjs}'], - rules: plugin_js.configs.recommended.rules, - }, - { - ...plugin_jsdoc.configs['flat/recommended'], - files: ['**/*.{js,mjs,cjs}'], - }, - { - name: 'jsdoc-override', - files: ['**/*.{js,mjs,cjs}'], - plugins: { - 'jsdoc': plugin_jsdoc, + ...configSetFiles(['**/*.ts'], [ + { + ...config_love }, - settings: { - jsdoc: { - mode: 'jsdoc', + { + plugins: { + tsdoc: plugin_tsdoc, }, - }, - rules: { - 'jsdoc/no-undefined-types': 'error', - 'jsdoc/check-tag-names': 0, - 'jsdoc/check-types': 'error', - 'jsdoc/require-hyphen-before-param-description': ['error', 'always'], - 'jsdoc/require-jsdoc': 0, - 'jsdoc/require-param': 0, - 'jsdoc/require-param-description': 0, - 'jsdoc/require-param-name': 'error', - 'jsdoc/require-param-type': 'error', - 'jsdoc/require-property': 0, - 'jsdoc/require-property-description': 0, - 'jsdoc/require-property-name': 'error', - 'jsdoc/require-property-type': 'error', - 'jsdoc/require-returns': 0, - 'jsdoc/require-returns-check': 'error', - 'jsdoc/require-returns-description': 0, - 'jsdoc/require-returns-type': 'error', - 'jsdoc/require-throws': 'error', - 'jsdoc/require-yields': 0, - 'jsdoc/require-yields-check': 'error', - 'jsdoc/sort-tags': 'warn', - } - }, - { - ...config_love, - files: ['**/*.ts'] - }, - { - files: ['**/*.ts'], - plugins: { - 'tsdoc': plugin_tsdoc, - }, - languageOptions: { - parserOptions: { - // override - project: false, + languageOptions: { + parserOptions: { + // override + project: false, + }, + }, + rules: { + '@typescript-eslint/consistent-type-imports': ['error', { + fixStyle: 'separate-type-imports', + }], + '@typescript-eslint/unbound-method': ['error', { + ignoreStatic: true, + }], + 'class-methods-use-this': 'off', + '@typescript-eslint/class-methods-use-this': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-magic-numbers': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/prefer-destructuring': 'off', + 'tsdoc/syntax': 'error', }, }, - rules: { - '@typescript-eslint/consistent-type-imports': ['error', { - fixStyle: 'separate-type-imports', - }], - '@typescript-eslint/unbound-method': ['error', { - ignoreStatic: true, - }], - 'class-methods-use-this': 'off', - '@typescript-eslint/class-methods-use-this': 'off', - '@typescript-eslint/no-redundant-type-constituents': 'off', - '@typescript-eslint/no-magic-numbers': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/prefer-destructuring': 'off', - 'tsdoc/syntax': 'error', - }, - }, + ]), { files: [ '**/eslint.config.{js,mjs,cjs}', diff --git a/tools/code-style/package.json b/tools/code-style/package.json index 43ad3a0a2..2fc436021 100644 --- a/tools/code-style/package.json +++ b/tools/code-style/package.json @@ -9,7 +9,6 @@ "@eslint/js": "9.22.0", "eslint": "9.14.0", "eslint-config-love": "119.0.0", - "eslint-plugin-editorconfig": "4.0.3", "eslint-plugin-import": "2.31.0", "eslint-plugin-jsdoc": "50.6.6", "eslint-plugin-license-header": "0.8.0", @@ -18,6 +17,7 @@ "eslint-plugin-simple-import-sort": "12.1.1", "eslint-plugin-tsdoc": "0.4.0", "globals": "^16.0.0", + "neostandard": "0.12.1", "typescript-eslint": "8.26.1" }, "scripts": { diff --git a/tools/docs-gen/package.json b/tools/docs-gen/package.json index 08f7799f0..c78eaee76 100644 --- a/tools/docs-gen/package.json +++ b/tools/docs-gen/package.json @@ -8,5 +8,8 @@ "dependencies": { "typedoc": "^0.28.1", "typedoc-plugin-missing-exports": "^4.0.0" + }, + "scripts": { + "cs-fix": "npm --prefix ../code-style exec -- eslint --fix ." } } diff --git a/tools/schema-downloader/download.js b/tools/schema-downloader/download.js index 539be4563..de303708b 100644 --- a/tools/schema-downloader/download.js +++ b/tools/schema-downloader/download.js @@ -21,8 +21,6 @@ import { writeFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -/* eslint-disable no-unused-vars */ - const SOURCE_ROOT = 'https://raw.githubusercontent.com/CycloneDX/specification/refs/tags/1.6.1/schema/' const TARGET_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'res', 'schema') diff --git a/tools/schema-downloader/eslint.config.mjs b/tools/schema-downloader/eslint.config.mjs index 8f2f0c6dd..6483e71a7 100644 --- a/tools/schema-downloader/eslint.config.mjs +++ b/tools/schema-downloader/eslint.config.mjs @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 Copyright (c) OWASP Foundation. All Rights Reserved. */ -import { default as baseCfg, globals } from '../code-style/eslint.config.mjs' +import baseCfg, { globals } from '../code-style/eslint.config.mjs' /* eslint-disable jsdoc/valid-types */