diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f6f66a0..0c681ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,3 +32,4 @@ jobs: - run: npm ci - run: npm run build - run: npm test + - run: npm run lint diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..8ad454c --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,66 @@ +import globals from "globals"; +import eslint from '@eslint/js'; +import jestPlugin from 'eslint-plugin-jest'; + +export default [ + eslint.configs.recommended, + { + ignores: ["tmp/", "coverage/", "node_modules/"], + }, + { + files: ["src/**/*.js"], + languageOptions: { + globals: { + ...globals.browser, + "jQuery": true, + "I18n": true, + "_": true + } + }, + rules: { + "no-cond-assign": "off", + "no-unused-vars": [ + "error", + { + // "args": "all", + "argsIgnorePattern": "^_", + // "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_", + // "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_", + // "ignoreRestSiblings": true + } + ], + "no-undef": "error" + } + }, + { + files: ["jest.setup.js", "tests/**/*.js"], + plugins: { + jest: jestPlugin + }, + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.jest + } + }, + rules: { + "no-unused-vars": "error", + "no-undef": "error" + } + }, + { + files: ["jest.config.js", 'babel.config.js', 'webpack.config.js'], + languageOptions: { + globals: { + ...globals.node + } + }, + rules: { + "no-unused-vars": "error", + "no-undef": "error" + } + }, +]; diff --git a/package-lock.json b/package-lock.json index 56955a4..3cf6058 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,9 +44,12 @@ "@ckeditor/ckeditor5-upload": "43.0.0", "@ckeditor/ckeditor5-watchdog": "43.0.0", "@ckeditor/ckeditor5-widget": "43.0.0", + "@eslint/js": "^9.10.0", "babel-jest": "^29.7.0", "css-loader": "^7.1.2", "eslint": "^9.9.0", + "eslint-plugin-jest": "^28.8.3", + "globals": "^15.9.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -1117,6 +1120,15 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", @@ -1979,6 +1991,15 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { "version": "7.25.6", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", @@ -3497,11 +3518,10 @@ } }, "node_modules/@eslint/js": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", - "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", "dev": true, - "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -4268,6 +4288,127 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", + "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", + "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", + "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", + "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", + "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.6.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -6167,6 +6308,31 @@ } } }, + "node_modules/eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "engines": { + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -6201,6 +6367,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/eslint/node_modules/eslint-scope": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", @@ -6442,9 +6617,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6736,12 +6911,15 @@ "license": "BSD-2-Clause" }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { @@ -10662,6 +10840,18 @@ "node": ">=12" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/turndown": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", @@ -10699,6 +10889,20 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -11995,6 +12199,14 @@ "@babel/helper-replace-supers": "^7.25.0", "@babel/traverse": "^7.25.4", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/plugin-transform-computed-properties": { @@ -12552,6 +12764,14 @@ "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/types": { @@ -13706,9 +13926,9 @@ } }, "@eslint/js": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", - "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", "dev": true }, "@eslint/object-schema": { @@ -14340,6 +14560,80 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, + "@typescript-eslint/scope-manager": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", + "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0" + } + }, + "@typescript-eslint/types": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", + "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", + "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", + "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", + "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.6.0", + "eslint-visitor-keys": "^3.4.3" + } + }, "@webassemblyjs/ast": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", @@ -15736,6 +16030,12 @@ "text-table": "^0.2.0" }, "dependencies": { + "@eslint/js": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", + "dev": true + }, "eslint-scope": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", @@ -15791,6 +16091,15 @@ } } }, + "eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -15919,9 +16228,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -16147,9 +16456,9 @@ "dev": true }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true }, "globby": { @@ -18897,6 +19206,13 @@ "punycode": "^2.1.1" } }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "requires": {} + }, "turndown": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz", @@ -18927,6 +19243,13 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "typescript": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "dev": true, + "peer": true + }, "uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", diff --git a/package.json b/package.json index c13ae18..b304108 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,9 @@ "babel-jest": "^29.7.0", "css-loader": "^7.1.2", "eslint": "^9.9.0", + "@eslint/js": "^9.10.0", + "eslint-plugin-jest": "^28.8.3", + "globals": "^15.9.0", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -88,6 +91,7 @@ "preversion": "npm run build; if [ -n \"$(git status src/ckeditor.js build/ --porcelain)\" ]; then git add -u src/ckeditor.js build/ && git commit -m 'Internal: Build.'; fi", "prewatch": "sh bin/clean.sh", "watch": "NODE_ENV=development ./node_modules/.bin/webpack --watch --stats-error-details", + "lint": "eslint .", "test": "jest ." } } diff --git a/src/mentions/user-mentions.js b/src/mentions/user-mentions.js index 706e3d5..553c1ad 100644 --- a/src/mentions/user-mentions.js +++ b/src/mentions/user-mentions.js @@ -2,7 +2,6 @@ import { getOPResource, getOPPath, getPluginContext, - getOPHelper, } from "../plugins/op-context/op-context"; export function userMentions(queryText) { @@ -22,7 +21,7 @@ export function userMentions(queryText) { const pluginContext = getPluginContext(editor); const base = window.OpenProject.urlRoot; - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { jQuery.getJSON(url, collection => { resolve(_.uniqBy(collection._embedded.elements, (el) => el.id).map(mention => { const type = mention._type.toLowerCase(); diff --git a/src/mentions/work-package-mentions.js b/src/mentions/work-package-mentions.js index c6ba172..19f09ae 100644 --- a/src/mentions/work-package-mentions.js +++ b/src/mentions/work-package-mentions.js @@ -7,7 +7,7 @@ export function workPackageMentions(query) { return []; } - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { jQuery.getJSON(url, {q: query, scope: 'all'}, collection => { resolve(collection.map(wp => { const id = `#${wp.id}`; diff --git a/src/plugins/code-block/widget.js b/src/plugins/code-block/widget.js index 3a22a35..21bc0bc 100644 --- a/src/plugins/code-block/widget.js +++ b/src/plugins/code-block/widget.js @@ -1,6 +1,4 @@ -import { ViewPosition } from '@ckeditor/ckeditor5-engine'; import {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils'; -import {setContent} from './widget'; const codeBlockSymbol = Symbol( 'isOPCodeBlock' ); diff --git a/src/plugins/op-content-revisions/op-content-revisions.js b/src/plugins/op-content-revisions/op-content-revisions.js index c217b08..f1f3df9 100644 --- a/src/plugins/op-content-revisions/op-content-revisions.js +++ b/src/plugins/op-content-revisions/op-content-revisions.js @@ -1,6 +1,6 @@ import {Plugin} from "ckeditor5/src/core"; import OpContentRevisionsUI from "./ui"; -import {loadFromLocalStorage, saveInLocalStorage} from "./storage"; +import {loadFromLocalStorage} from "./storage"; import OpContentRevisionsCommand from "./command"; import {getOPFieldName, getOPResource} from "../op-context/op-context"; import {Autosave} from "@ckeditor/ckeditor5-autosave"; diff --git a/src/plugins/op-content-revisions/ui.js b/src/plugins/op-content-revisions/ui.js index 88d9be9..8012265 100644 --- a/src/plugins/op-content-revisions/ui.js +++ b/src/plugins/op-content-revisions/ui.js @@ -2,7 +2,7 @@ * @file registers the history_log toolbar button and binds functionality to it. */ import {Plugin} from "ckeditor5/src/core"; -import {addListToDropdown, createDropdown, Notification} from "ckeditor5/src/ui"; +import {addListToDropdown, createDropdown} from "ckeditor5/src/ui"; import {Collection} from "ckeditor5/src/utils"; import {loadFromLocalStorage} from "./storage"; import {countWords, generateHash} from "./utils"; diff --git a/src/plugins/op-custom-css-classes-plugin.js b/src/plugins/op-custom-css-classes-plugin.js index 422a51b..49f055d 100644 --- a/src/plugins/op-custom-css-classes-plugin.js +++ b/src/plugins/op-custom-css-classes-plugin.js @@ -304,8 +304,6 @@ export default class OpCustomCssClassesPlugin extends Plugin { const listType = modelElement.getAttribute('listType'); const listTypeClass = config.attributesWithCustomClassesMap[listType]; - const previousElement = listElement.previousSibling; - const nextElement = listElement.nextSibling; if (listType === 'todo') { viewWriter.addClass(listTypeClass, listElement); diff --git a/src/plugins/op-help-link-plugin/op-help-link-plugin.js b/src/plugins/op-help-link-plugin/op-help-link-plugin.js index 0c203b5..250bc99 100644 --- a/src/plugins/op-help-link-plugin/op-help-link-plugin.js +++ b/src/plugins/op-help-link-plugin/op-help-link-plugin.js @@ -14,7 +14,6 @@ export default class OPHelpLinkPlugin extends Plugin { init() { const editor = this.editor; - const model = editor.model; const helpURL = editor.config.get('openProject.helpURL'); editor.ui.componentFactory.add( 'openProjectShowFormattingHelp', locale => { diff --git a/src/plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin.js b/src/plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin.js index 004c95a..8995b0d 100644 --- a/src/plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin.js +++ b/src/plugins/op-image-attachment-lookup/op-image-attachment-lookup-plugin.js @@ -9,7 +9,7 @@ export function replaceImageAttachmentsByName(resource) { dispatcher.on('attribute:src:imageInline', converter, { priority: 'highest' } ); }; - function converter( evt, data, conversionApi ) { + function converter( evt, data, _conversionApi ) { // We do not consume the attribute since we want the regular attribute // converter to run as well. diff --git a/src/plugins/op-macro-child-pages/op-macro-child-pages-editing.js b/src/plugins/op-macro-child-pages/op-macro-child-pages-editing.js index 1808156..6e83938 100644 --- a/src/plugins/op-macro-child-pages/op-macro-child-pages-editing.js +++ b/src/plugins/op-macro-child-pages/op-macro-child-pages-editing.js @@ -1,10 +1,6 @@ import { ButtonView } from '@ckeditor/ckeditor5-ui'; - import { Plugin } from '@ckeditor/ckeditor5-core'; -import { ViewPosition } from '@ckeditor/ckeditor5-engine'; -import { ViewRange } from '@ckeditor/ckeditor5-engine'; - import {toChildPagesMacroWidget} from './utils'; export default class OPChildPagesEditing extends Plugin { diff --git a/src/plugins/op-macro-child-pages/op-macro-child-pages-toolbar.js b/src/plugins/op-macro-child-pages/op-macro-child-pages-toolbar.js index 7b02079..551553c 100644 --- a/src/plugins/op-macro-child-pages/op-macro-child-pages-toolbar.js +++ b/src/plugins/op-macro-child-pages/op-macro-child-pages-toolbar.js @@ -7,7 +7,7 @@ import {createEditToolbar} from '../../helpers/create-toolbar'; import {getPluginContext} from '../op-context/op-context'; -const balloonClassName = 'ck-toolbar-container'; +// const balloonClassName = 'ck-toolbar-container'; export default class OPChildPagesToolbar extends Plugin { static get requires() { diff --git a/src/plugins/op-macro-embedded-table/embedded-table-editing.js b/src/plugins/op-macro-embedded-table/embedded-table-editing.js index 5ccd785..4cbc0a7 100644 --- a/src/plugins/op-macro-embedded-table/embedded-table-editing.js +++ b/src/plugins/op-macro-embedded-table/embedded-table-editing.js @@ -3,7 +3,6 @@ import { ButtonView } from '@ckeditor/ckeditor5-ui'; import { Plugin } from '@ckeditor/ckeditor5-core'; import {toEmbeddedTableWidget} from './utils'; -import { ViewPosition } from '@ckeditor/ckeditor5-engine'; import {getPluginContext} from '../op-context/op-context'; export default class EmbeddedTableEditing extends Plugin { diff --git a/src/plugins/op-macro-embedded-table/embedded-table-toolbar.js b/src/plugins/op-macro-embedded-table/embedded-table-toolbar.js index 944c9a9..9c14491 100644 --- a/src/plugins/op-macro-embedded-table/embedded-table-toolbar.js +++ b/src/plugins/op-macro-embedded-table/embedded-table-toolbar.js @@ -7,7 +7,7 @@ import {createEditToolbar} from '../../helpers/create-toolbar'; import {getPluginContext} from '../op-context/op-context'; -const balloonClassName = 'ck-toolbar-container'; +// const balloonClassName = 'ck-toolbar-container'; export default class EmbeddedTableToolbar extends Plugin { static get requires() { diff --git a/src/plugins/op-macro-embedded-table/utils.js b/src/plugins/op-macro-embedded-table/utils.js index f7d5293..e76c141 100644 --- a/src/plugins/op-macro-embedded-table/utils.js +++ b/src/plugins/op-macro-embedded-table/utils.js @@ -1,7 +1,7 @@ const embeddedTableSymbol = Symbol( 'isOPEmbeddedTable' ); import {toWidget, isWidget} from '@ckeditor/ckeditor5-widget/src/utils'; -export function toEmbeddedTableWidget( viewElement, writer, label ) { +export function toEmbeddedTableWidget( viewElement, writer, _label ) { writer.setCustomProperty( embeddedTableSymbol, true, viewElement ); return toWidget( viewElement, writer, { label: 'your label here' } ); } diff --git a/src/plugins/op-macro-wp-button/op-macro-wp-button-editing.js b/src/plugins/op-macro-wp-button/op-macro-wp-button-editing.js index aba9e26..bc83343 100644 --- a/src/plugins/op-macro-wp-button/op-macro-wp-button-editing.js +++ b/src/plugins/op-macro-wp-button/op-macro-wp-button-editing.js @@ -110,7 +110,7 @@ export default class OPMacroWpButtonEditing extends Plugin { } createMacroViewElement(modelElement, writer) { - const type = modelElement.getAttribute('type'); + // const type = modelElement.getAttribute('type'); const classes = modelElement.getAttribute('classes') || ''; const label = this.macroLabel(); // TODO: Pass type, it is not updated on coming back from the modal.. const placeholder = writer.createText( label ); diff --git a/src/plugins/op-macro-wp-button/op-macro-wp-button-toolbar.js b/src/plugins/op-macro-wp-button/op-macro-wp-button-toolbar.js index cba7271..f7c4f21 100644 --- a/src/plugins/op-macro-wp-button/op-macro-wp-button-toolbar.js +++ b/src/plugins/op-macro-wp-button/op-macro-wp-button-toolbar.js @@ -7,7 +7,7 @@ import {createEditToolbar} from '../../helpers/create-toolbar'; import {getPluginContext} from '../op-context/op-context'; -const balloonClassName = 'ck-toolbar-container'; +// const balloonClassName = 'ck-toolbar-container'; export default class OPMacroWpButtonToolbar extends Plugin { static get requires() { @@ -20,7 +20,6 @@ export default class OPMacroWpButtonToolbar extends Plugin { init() { const editor = this.editor; - const model = this.editor.model; const pluginContext = getPluginContext(editor); // Add editing button diff --git a/src/plugins/op-source-code.plugin.js b/src/plugins/op-source-code.plugin.js index 81a0321..f5fe103 100644 --- a/src/plugins/op-source-code.plugin.js +++ b/src/plugins/op-source-code.plugin.js @@ -6,7 +6,6 @@ import wysiwygIcon from '../icons/wysiwyg.svg'; import { ButtonView } from '@ckeditor/ckeditor5-ui'; import { Plugin } from '@ckeditor/ckeditor5-core'; -import {getOPPath, getOPPreviewContext, getOPService} from './op-context/op-context'; import {enableItems, disableItems} from '../helpers/button-disabler'; export default class OPSourceCodePlugin extends Plugin { @@ -35,7 +34,7 @@ export default class OPSourceCodePlugin extends Plugin { } ); - let showSource = function(preview) { + let showSource = function(_preview) { let $mainEditor = jQuery(editor.ui.getEditableElement()).parent(); let $reference;