diff --git a/common/web/eslint-plugin-keyman/README.md b/common/web/eslint-plugin-keyman/README.md new file mode 100644 index 0000000000..e6c84ea6f8 --- /dev/null +++ b/common/web/eslint-plugin-keyman/README.md @@ -0,0 +1,3 @@ +# eslint-plugin-keyman + +Lint tests for keymanapp/keyman. See developer/src/.eslintrc.cjs for example usage. diff --git a/common/web/eslint-plugin-keyman/eslint.config.mjs b/common/web/eslint-plugin-keyman/eslint.config.mjs new file mode 100644 index 0000000000..0e6599d4da --- /dev/null +++ b/common/web/eslint-plugin-keyman/eslint.config.mjs @@ -0,0 +1,28 @@ +import { defineConfig } from "eslint/config"; +import pluginJs from "@eslint/js"; +import pluginNode from "eslint-plugin-n"; +import eslintPlugin from "eslint-plugin-eslint-plugin"; + +export default defineConfig([ + { + name: "eslint/js", + plugins: { + js: pluginJs, + }, + extends: ["js/recommended"], + }, + { + name: "eslint/node", + plugins: { + n: pluginNode, + }, + extends: ["n/flat/mixed-esm-and-cjs"], + }, + { + name: "eslint/eslint-plugin", + plugins: { + "eslint-plugin": eslintPlugin, + }, + extends: ["eslint-plugin/recommended"], + } +]); diff --git a/common/web/eslint-plugin-keyman/lib/index.js b/common/web/eslint-plugin-keyman/lib/index.js new file mode 100644 index 0000000000..eaa88580e3 --- /dev/null +++ b/common/web/eslint-plugin-keyman/lib/index.js @@ -0,0 +1,19 @@ +/** + * @fileoverview Lint tests for keymanapp/keyman + * @author Marc Durdin + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const requireIndex = require("requireindex"); + +//------------------------------------------------------------------------------ +// Plugin Definition +//------------------------------------------------------------------------------ + + +// import all rules in lib/rules +module.exports.rules = requireIndex(__dirname + "/rules"); diff --git a/common/web/eslint-plugin-keyman/lib/rules/prohibit-unitTestEndpoints.js b/common/web/eslint-plugin-keyman/lib/rules/prohibit-unitTestEndpoints.js new file mode 100644 index 0000000000..faba1c058d --- /dev/null +++ b/common/web/eslint-plugin-keyman/lib/rules/prohibit-unitTestEndpoints.js @@ -0,0 +1,49 @@ +/* + * Keyman is copyright (C) SIL Global. MIT License. + * + * Created by mcdurdin on 2026-10-09 + * + * Enforce restrictions on use of unitTestEndpoints -- only for use in + * unit tests + */ + +// import { RuleDefinition } from "@eslint/core"; + +module.exports = /*: RuleDefinition*/ { + meta: { + type: "problem", + docs: { + description: "Do not use unitTestEndpoints except in unit tests", + }, + schema: [], // no options + }, + create: function (context) { + return { + // callback functions + "Identifier[name=/^unitTestEndpoints$/]"(node) { + if(node.parent?.type == 'PropertyDefinition' || node.parent?.type == 'VariableDeclarator') { + // These are valid places to have endpoints + } else if(node.parent?.type == 'MemberExpression') { + context.report({ + node, + message: 'Use of `unitTestEndpoints` outside unit tests.', + }); + + } else { + context.report({ + node, + message: 'Unexpected `unitTestEndpoints` -- context is unclear', + }); + } + } + }; + }, +}; + +// const plugin = { +// rules: { +// "prohibit-unitTestEndpoints": rule +// } +// }; + +// module.exports = plugin; \ No newline at end of file diff --git a/common/web/eslint-plugin-keyman/package.json b/common/web/eslint-plugin-keyman/package.json new file mode 100644 index 0000000000..dc6d696e69 --- /dev/null +++ b/common/web/eslint-plugin-keyman/package.json @@ -0,0 +1,15 @@ +{ + "name": "@keymanapp/eslint-plugin-keyman", + "private": "true", + "description": "Lint tests for keymanapp/keyman", + "author": "Marc Durdin", + "main": "./lib/index.js", + "exports": "./lib/index.js", + "files": [ + "lib" + ], + "dependencies": { + "requireindex": "^1.2.0" + }, + "license": "MIT" +} diff --git a/developer/src/.eslintrc.cjs b/developer/src/.eslintrc.cjs index 0b4001b572..b6dd890c19 100644 --- a/developer/src/.eslintrc.cjs +++ b/developer/src/.eslintrc.cjs @@ -1,4 +1,18 @@ module.exports = { ignorePatterns: ["**/build/**/*", "**/coverage/**/*"], - rules: {}, + plugins: [ + '@keymanapp/eslint-plugin-keyman', + ], + rules: { + "@keymanapp/keyman/prohibit-unitTestEndpoints": "error", + }, + overrides: [ + { + files: ["**/*.tests.ts"], + rules: { + "@keymanapp/keyman/prohibit-unitTestEndpoints": "off", + }, + } + ] + // rules: {}, }; diff --git a/package-lock.json b/package-lock.json index 33e0732824..14880e321b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "developer/src/server", "developer/src/tike/xml/layoutbuilder", "common/test/resources", + "common/web/eslint-plugin-keyman", "common/web/keyman-version", "common/web/langtags", "common/web/sentry-manager", @@ -40,6 +41,7 @@ "@keymanapp/common-types": "file:common/web/types", "@keymanapp/developer-test-helpers": "file:developer/src/common/web/test-helpers", "@keymanapp/developer-utils": "file:developer/src/common/web/utils", + "@keymanapp/eslint-plugin-keyman": "file:common/web/eslint-plugin-keyman", "@keymanapp/hextobin": "file:common/tools/hextobin", "@keymanapp/keyman-version": "file:common/web/keyman-version", "@keymanapp/langtags": "file:common/web/langtags", @@ -120,6 +122,13 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, + "common/web/eslint-plugin-keyman": { + "name": "@keymanapp/eslint-plugin-keyman", + "license": "MIT", + "dependencies": { + "requireindex": "^1.2.0" + } + }, "common/web/keyman-version": { "name": "@keymanapp/keyman-version", "license": "MIT", @@ -2154,6 +2163,10 @@ "resolved": "developer/src/common/web/utils", "link": true }, + "node_modules/@keymanapp/eslint-plugin-keyman": { + "resolved": "common/web/eslint-plugin-keyman", + "link": true + }, "node_modules/@keymanapp/hextobin": { "resolved": "common/tools/hextobin", "link": true @@ -3102,16 +3115,6 @@ "node": ">=18" } }, - "node_modules/@puppeteer/browsers/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@puppeteer/browsers/node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3165,19 +3168,6 @@ "node": ">=8" } }, - "node_modules/@puppeteer/browsers/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@puppeteer/browsers/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -5740,6 +5730,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "license": "MIT", @@ -6690,14 +6689,6 @@ "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -6719,17 +6710,6 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", @@ -8013,6 +7993,23 @@ "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -8068,15 +8065,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -8089,22 +8077,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -8123,18 +8095,6 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -10407,15 +10367,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -10439,18 +10390,6 @@ "node": ">=8" } }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -10844,16 +10783,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/brace-expansion": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz", @@ -11065,19 +10994,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "dev": true, @@ -12296,6 +12212,15 @@ "node": ">=0.10.0" } }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "license": "MIT", + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/requires-port": { "version": "1.0.0", "dev": true, @@ -13170,15 +13095,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -13188,18 +13104,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.codepointat": { "version": "0.2.1", "license": "MIT" @@ -13252,6 +13156,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", @@ -13265,15 +13181,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -13597,25 +13504,6 @@ "typescript": "*" } }, - "node_modules/tsc-watch/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/tsc-watch/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -14614,15 +14502,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -14646,25 +14525,6 @@ "node": ">=8" } }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "license": "MIT", @@ -14684,16 +14544,6 @@ "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "license": "ISC" @@ -14834,14 +14684,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -14863,17 +14705,6 @@ "node": ">=8" } }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yauzl": { "version": "2.10.0", "dev": true, @@ -14940,14 +14771,6 @@ "undici-types": "~7.21.0" } }, - "resources/build/version/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, "resources/build/version/node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -14992,17 +14815,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "resources/build/version/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "resources/build/version/node_modules/undici-types": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.21.0.tgz", diff --git a/package.json b/package.json index 07b3bf7f98..ba2a199a55 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "developer/src/server", "developer/src/tike/xml/layoutbuilder", "common/test/resources", + "common/web/eslint-plugin-keyman", "common/web/keyman-version", "common/web/langtags", "common/web/sentry-manager", @@ -68,7 +69,8 @@ "@keymanapp/hextobin": "file:common/tools/hextobin", "@keymanapp/keyman-version": "file:common/web/keyman-version", "@keymanapp/langtags": "file:common/web/langtags", - "@keymanapp/ldml-keyboard-constants": "file:core/include/ldml" + "@keymanapp/ldml-keyboard-constants": "file:core/include/ldml", + "@keymanapp/eslint-plugin-keyman": "file:common/web/eslint-plugin-keyman" }, "overrides": { "ajv-cli": {