From 192ce51aa9c6e9a7ca5c5e307be0d5439c54272f Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 09:19:57 +0900 Subject: [PATCH 1/8] Add: Add generate-regex.ts --- package-lock.json | 818 +++++++++++++++++++++++++++++++++++++- package.json | 5 +- scripts/generate-regex.ts | 51 +++ 3 files changed, 867 insertions(+), 7 deletions(-) create mode 100644 scripts/generate-regex.ts diff --git a/package-lock.json b/package-lock.json index 2428938..8d6bc33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,9 @@ "eslint": "^8.46.0", "glob": "^8.1.0", "mocha": "^10.2.0", + "node-fetch": "^3.3.2", "path-browserify": "^1.0.1", + "tsx": "^4.11.0", "typescript": "^5.1.6" }, "engines": { @@ -45,6 +47,22 @@ "node": ">=0.10.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.17", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", @@ -1080,6 +1098,15 @@ "node": ">= 8" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1426,6 +1453,29 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1494,6 +1544,18 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1501,9 +1563,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, @@ -1523,6 +1585,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -2102,6 +2176,43 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2351,6 +2462,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -2581,6 +2701,415 @@ "node": ">=6.10" } }, + "node_modules/tsx": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.11.0.tgz", + "integrity": "sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==", + "dev": true, + "dependencies": { + "esbuild": "~0.20.2", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2692,6 +3221,15 @@ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==" }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2812,6 +3350,13 @@ "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true }, + "@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { "version": "0.18.17", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.17.tgz", @@ -3444,6 +3989,12 @@ "which": "^2.0.1" } }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3708,6 +4259,16 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3758,6 +4319,15 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "requires": { + "fetch-blob": "^3.1.2" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3765,9 +4335,9 @@ "dev": true }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -3777,6 +4347,15 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } + }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -4221,6 +4800,23 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true + }, + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4393,6 +4989,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4554,6 +5156,204 @@ "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" }, + "tsx": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.11.0.tgz", + "integrity": "sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==", + "dev": true, + "requires": { + "esbuild": "~0.20.2", + "fsevents": "~2.3.3", + "get-tsconfig": "^4.7.5" + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + } + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4642,6 +5442,12 @@ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==" }, + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 87943ad..fa65c06 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,8 @@ "watch-tests": "tsc -p . -w --outDir out", "pretest": "npm run compile-tests && npm run compile && npm run lint", "lint": "eslint src --ext ts & tsc --noEmit", - "test": "node ./out/test/runTest.js" + "test": "node ./out/test/runTest.js", + "generate-regex": "tsx scripts/generate-regex.ts" }, "devDependencies": { "@types/glob": "^8.1.0", @@ -83,7 +84,9 @@ "eslint": "^8.46.0", "glob": "^8.1.0", "mocha": "^10.2.0", + "node-fetch": "^3.3.2", "path-browserify": "^1.0.1", + "tsx": "^4.11.0", "typescript": "^5.1.6" }, "dependencies": { diff --git a/scripts/generate-regex.ts b/scripts/generate-regex.ts new file mode 100644 index 0000000..be60e20 --- /dev/null +++ b/scripts/generate-regex.ts @@ -0,0 +1,51 @@ +import fs from "fs/promises"; +import fetch from "node-fetch"; + +type DiagnosticMessages = Record<`${string}_${number}`, string>; + +const getMessageFromCode = ( + diagnosticMessages: DiagnosticMessages, + code: number, +) => { + for (const key in diagnosticMessages) { + if (key.endsWith(`_${code}`)) { + return diagnosticMessages[key]; + } + } + throw new Error(`Could not find message for code ${code}`); +}; + +(async () => { + // diagnosticMessages.json is not exported in typescript library, so we fetch it from the TypeScript repository + const enDiagnosticMessages: Record< + string, + { + category: "Error" | "Suggestion" | "Message" | "Warning"; + code: number; + } + > = await fetch( + "https://raw.githubusercontent.com/microsoft/TypeScript/ef514af2675389d38c793d6cc1945486c367e6fa/src/compiler/diagnosticMessages.json", + ).then((res) => res.json()); + + const tsLibFiles = await fs.readdir("./node_modules/typescript/lib", { + withFileTypes: true, + }); + for (const file of tsLibFiles) { + if ( + file.isDirectory() && + (await fs + .stat( + `./node_modules/typescript/lib/${file.name}/diagnosticMessages.generated.json`, + ) + .catch(() => false)) + ) { + const diagnosticMessages: DiagnosticMessages = await fs + .readFile( + `./node_modules/typescript/lib/${file.name}/diagnosticMessages.generated.json`, + "utf-8", + ) + .then((res) => JSON.parse(res)); + console.log(diagnosticMessages); + } + } +})(); From 60d6998d8987c8d5aab0dfc80ae48b46d3ba95ce Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 09:47:11 +0900 Subject: [PATCH 2/8] Add: Add missing properties regexes --- scripts/generate-regex.ts | 73 +++++++++++++++++----- src/format/diagnosticPatterns.generated.ts | 0 src/format/diagnosticPatterns.ts | 0 3 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 src/format/diagnosticPatterns.generated.ts create mode 100644 src/format/diagnosticPatterns.ts diff --git a/scripts/generate-regex.ts b/scripts/generate-regex.ts index be60e20..4757d0f 100644 --- a/scripts/generate-regex.ts +++ b/scripts/generate-regex.ts @@ -3,6 +3,24 @@ import fetch from "node-fetch"; type DiagnosticMessages = Record<`${string}_${number}`, string>; +const templateToRegex = (template: string, names: string[]) => { + const escapedTemplate = template.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); + let maxIndex = 0; + const regex = escapedTemplate.replace(/\\\{([0-9]+)\\\}/g, (_, index) => { + if (Number(index) > maxIndex) { + maxIndex = Number(index); + } + return `(?<${names[Number(index)]}>.*?)`; + }); + if (maxIndex !== names.length - 1) { + throw new Error( + `Expected ${maxIndex + 1} named groups, got ${names.length}`, + ); + } + + return new RegExp(regex); +}; + const getMessageFromCode = ( diagnosticMessages: DiagnosticMessages, code: number, @@ -16,36 +34,59 @@ const getMessageFromCode = ( }; (async () => { + const regexes = { + propertiesMissingWithoutTruncation: [], + propertiesMissingWithTruncation: [], + } as Record; + // diagnosticMessages.json is not exported in typescript library, so we fetch it from the TypeScript repository - const enDiagnosticMessages: Record< + const enDiagnosticMessages = (await fetch( + "https://raw.githubusercontent.com/microsoft/TypeScript/ef514af2675389d38c793d6cc1945486c367e6fa/src/compiler/diagnosticMessages.json", + ).then((res) => res.json())) as Record< string, { category: "Error" | "Suggestion" | "Message" | "Warning"; code: number; } - > = await fetch( - "https://raw.githubusercontent.com/microsoft/TypeScript/ef514af2675389d38c793d6cc1945486c367e6fa/src/compiler/diagnosticMessages.json", - ).then((res) => res.json()); + >; const tsLibFiles = await fs.readdir("./node_modules/typescript/lib", { withFileTypes: true, }); - for (const file of tsLibFiles) { + for (const dir of tsLibFiles) { + const diagnosticMessagesPath = `./node_modules/typescript/lib/${dir.name}/diagnosticMessages.generated.json`; if ( - file.isDirectory() && - (await fs - .stat( - `./node_modules/typescript/lib/${file.name}/diagnosticMessages.generated.json`, - ) - .catch(() => false)) + dir.isDirectory() && + (await fs.stat(diagnosticMessagesPath).catch(() => false)) ) { const diagnosticMessages: DiagnosticMessages = await fs - .readFile( - `./node_modules/typescript/lib/${file.name}/diagnosticMessages.generated.json`, - "utf-8", - ) + .readFile(diagnosticMessagesPath, "utf-8") .then((res) => JSON.parse(res)); - console.log(diagnosticMessages); + const propertiesMissingWithoutTruncation = getMessageFromCode( + diagnosticMessages, + 2739, + ); + const propertiesMissingWithTruncation = getMessageFromCode( + diagnosticMessages, + 2740, + ); + regexes.propertiesMissingWithoutTruncation.push( + templateToRegex(propertiesMissingWithoutTruncation, [ + "actualType", + "expectedType", + "propertyProperties", + ]), + ); + regexes.propertiesMissingWithTruncation.push( + templateToRegex(propertiesMissingWithTruncation, [ + "actualType", + "expectedType", + "propertyProperties", + "numTruncatedProperties", + ]), + ); } } + + console.log(regexes); })(); diff --git a/src/format/diagnosticPatterns.generated.ts b/src/format/diagnosticPatterns.generated.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/format/diagnosticPatterns.ts b/src/format/diagnosticPatterns.ts new file mode 100644 index 0000000..e69de29 From 0f728e30ac19d85bbe0a5022a16c43e07dc84aa6 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 09:47:44 +0900 Subject: [PATCH 3/8] Add: Add missing properties regexes --- scripts/generate-regex.ts | 2 +- src/format/diagnosticPatterns.generated.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 src/format/diagnosticPatterns.generated.ts diff --git a/scripts/generate-regex.ts b/scripts/generate-regex.ts index 4757d0f..0c88a5b 100644 --- a/scripts/generate-regex.ts +++ b/scripts/generate-regex.ts @@ -88,5 +88,5 @@ const getMessageFromCode = ( } } - console.log(regexes); + console.log(JSON.stringify(regexes, null, 2)); })(); diff --git a/src/format/diagnosticPatterns.generated.ts b/src/format/diagnosticPatterns.generated.ts deleted file mode 100644 index e69de29..0000000 From 03828d68411af53f0e0df5e8f64ac169a32a8b9a Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 10:30:28 +0900 Subject: [PATCH 4/8] Add: Support missing properties error --- scripts/generate-regex.ts | 115 +++++++++++---- src/format/diagnosticPatterns.generated.json | 146 +++++++++++++++++++ src/format/diagnosticPatterns.ts | 0 src/format/formatDiagnosticMessage.ts | 137 +++++++++++++---- tsconfig.json | 3 +- 5 files changed, 346 insertions(+), 55 deletions(-) create mode 100644 src/format/diagnosticPatterns.generated.json delete mode 100644 src/format/diagnosticPatterns.ts diff --git a/scripts/generate-regex.ts b/scripts/generate-regex.ts index 0c88a5b..443de9e 100644 --- a/scripts/generate-regex.ts +++ b/scripts/generate-regex.ts @@ -3,7 +3,13 @@ import fetch from "node-fetch"; type DiagnosticMessages = Record<`${string}_${number}`, string>; -const templateToRegex = (template: string, names: string[]) => { +const templateToRegexAndNamedTemplate = ( + template: string, + names: string[], +): { + regex: string; + template: string; +} => { const escapedTemplate = template.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); let maxIndex = 0; const regex = escapedTemplate.replace(/\\\{([0-9]+)\\\}/g, (_, index) => { @@ -18,7 +24,12 @@ const templateToRegex = (template: string, names: string[]) => { ); } - return new RegExp(regex); + const namedTemplate = template.replace( + /\{([0-9]+)\}/g, + (_, index) => `{${names[Number(index)]}}`, + ); + + return { regex, template: namedTemplate }; }; const getMessageFromCode = ( @@ -33,11 +44,48 @@ const getMessageFromCode = ( throw new Error(`Could not find message for code ${code}`); }; +type Pattern = { lang: string; regex: string; template: string }; + +const generatePatternsFromDiagnosticMessages = ( + lang: string, + diagnosticMessages: DiagnosticMessages, +): Record => { + const ret: Record = {}; + + const propertiesMissingWithoutTruncation = getMessageFromCode( + diagnosticMessages, + 2739, + ); + const propertiesMissingWithTruncation = getMessageFromCode( + diagnosticMessages, + 2740, + ); + ret.propertiesMissingWithoutTruncation = { + ...templateToRegexAndNamedTemplate(propertiesMissingWithoutTruncation, [ + "actualType", + "expectedType", + "propertyProperties", + ]), + lang, + }; + ret.propertiesMissingWithTruncation = { + ...templateToRegexAndNamedTemplate(propertiesMissingWithTruncation, [ + "actualType", + "expectedType", + "propertyProperties", + "numTruncatedProperties", + ]), + lang, + }; + + return ret; +}; + (async () => { - const regexes = { + const patterns = { propertiesMissingWithoutTruncation: [], propertiesMissingWithTruncation: [], - } as Record; + } as Record; // diagnosticMessages.json is not exported in typescript library, so we fetch it from the TypeScript repository const enDiagnosticMessages = (await fetch( @@ -62,31 +110,46 @@ const getMessageFromCode = ( const diagnosticMessages: DiagnosticMessages = await fs .readFile(diagnosticMessagesPath, "utf-8") .then((res) => JSON.parse(res)); - const propertiesMissingWithoutTruncation = getMessageFromCode( - diagnosticMessages, - 2739, - ); - const propertiesMissingWithTruncation = getMessageFromCode( + + const generatedPatterns = generatePatternsFromDiagnosticMessages( + dir.name, diagnosticMessages, - 2740, - ); - regexes.propertiesMissingWithoutTruncation.push( - templateToRegex(propertiesMissingWithoutTruncation, [ - "actualType", - "expectedType", - "propertyProperties", - ]), - ); - regexes.propertiesMissingWithTruncation.push( - templateToRegex(propertiesMissingWithTruncation, [ - "actualType", - "expectedType", - "propertyProperties", - "numTruncatedProperties", - ]), ); + for (const [key, pattern] of Object.entries(generatedPatterns)) { + patterns[key].push(pattern); + } } } - console.log(JSON.stringify(regexes, null, 2)); + // Translate the English diagnostic messages to the format used for other languages, and generate the regexes + const enDiagnosticMessagesTranslated = {} as DiagnosticMessages; + const jaDiagnosticMessages: DiagnosticMessages = JSON.parse( + await fs.readFile( + "./node_modules/typescript/lib/ja/diagnosticMessages.generated.json", + "utf-8", + ), + ); + for (const key of Object.keys(jaDiagnosticMessages)) { + const code = parseInt(key.match(/_(\d+)$/)?.[1]!); + const enMessage = Object.entries(enDiagnosticMessages).find( + ([, value]) => value.code === code, + )?.[0]; + // The translation file has unused messages + if (!enMessage) { + continue; + } + enDiagnosticMessagesTranslated[key] = enMessage; + } + const generatedPatterns = generatePatternsFromDiagnosticMessages( + "en", + enDiagnosticMessagesTranslated, + ); + for (const [key, pattern] of Object.entries(generatedPatterns)) { + patterns[key].unshift(pattern); + } + + await fs.writeFile( + "./src/format/diagnosticPatterns.generated.json", + JSON.stringify(patterns, null, 2), + ); })(); diff --git a/src/format/diagnosticPatterns.generated.json b/src/format/diagnosticPatterns.generated.json new file mode 100644 index 0000000..8cf64fa --- /dev/null +++ b/src/format/diagnosticPatterns.generated.json @@ -0,0 +1,146 @@ +{ + "propertiesMissingWithoutTruncation": [ + { + "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?)", + "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {propertyProperties}", + "lang": "en" + }, + { + "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?)", + "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {propertyProperties}", + "lang": "cs" + }, + { + "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\"\\.", + "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{propertyProperties}\".", + "lang": "de" + }, + { + "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?)", + "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {propertyProperties}", + "lang": "es" + }, + { + "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?)", + "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {propertyProperties}", + "lang": "fr" + }, + { + "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?)", + "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {propertyProperties}", + "lang": "it" + }, + { + "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)", + "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {propertyProperties}", + "lang": "ja" + }, + { + "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 속성이 없습니다\\.", + "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {propertyProperties} 속성이 없습니다.", + "lang": "ko" + }, + { + "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?)", + "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {propertyProperties}", + "lang": "pl" + }, + { + "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?)", + "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {propertyProperties}", + "lang": "pt-br" + }, + { + "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?)", + "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {propertyProperties}", + "lang": "ru" + }, + { + "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?)", + "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {propertyProperties}", + "lang": "tr" + }, + { + "regex": "类型“(?.*?)”缺少类型“(?.*?)”中的以下属性: (?.*?)", + "template": "类型“{actualType}”缺少类型“{expectedType}”中的以下属性: {propertyProperties}", + "lang": "zh-cn" + }, + { + "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?)", + "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {propertyProperties}", + "lang": "zh-tw" + } + ], + "propertiesMissingWithTruncation": [ + { + "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?), and (?.*?) more\\.", + "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {propertyProperties}, and {numTruncatedProperties} more.", + "lang": "en" + }, + { + "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?) a ještě (?.*?)", + "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {propertyProperties} a ještě {numTruncatedProperties}", + "lang": "cs" + }, + { + "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\" und (?.*?) weitere\\.", + "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{propertyProperties}\" und {numTruncatedProperties} weitere.", + "lang": "de" + }, + { + "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?) y (?.*?) más\\.", + "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {propertyProperties} y {numTruncatedProperties} más.", + "lang": "es" + }, + { + "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?) et de (?.*?) autres\\.", + "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {propertyProperties} et de {numTruncatedProperties} autres.", + "lang": "fr" + }, + { + "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?) e altre (?.*?)\\.", + "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {propertyProperties} e altre {numTruncatedProperties}.", + "lang": "it" + }, + { + "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)、(?.*?) など。", + "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {propertyProperties}、{numTruncatedProperties} など。", + "lang": "ja" + }, + { + "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 외 (?.*?)개 속성이 없습니다\\.", + "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {propertyProperties} 외 {numTruncatedProperties}개 속성이 없습니다.", + "lang": "ko" + }, + { + "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?) i jeszcze (?.*?)\\.", + "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {propertyProperties} i jeszcze {numTruncatedProperties}.", + "lang": "pl" + }, + { + "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?) e mais (?.*?)\\.", + "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {propertyProperties} e mais {numTruncatedProperties}.", + "lang": "pt-br" + }, + { + "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?) и еще (?.*?)\\.", + "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {propertyProperties} и еще {numTruncatedProperties}.", + "lang": "ru" + }, + { + "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?) ve diğer (?.*?) özellik\\.", + "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {propertyProperties} ve diğer {numTruncatedProperties} özellik.", + "lang": "tr" + }, + { + "regex": "类型“(?.*?)”缺少类型“(?.*?)”的以下属性: (?.*?) 及其他 (?.*?) 项。", + "template": "类型“{actualType}”缺少类型“{expectedType}”的以下属性: {propertyProperties} 及其他 {numTruncatedProperties} 项。", + "lang": "zh-cn" + }, + { + "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?),以及另外 (?.*?) 個。", + "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {propertyProperties},以及另外 {numTruncatedProperties} 個。", + "lang": "zh-tw" + } + ] +} \ No newline at end of file diff --git a/src/format/diagnosticPatterns.ts b/src/format/diagnosticPatterns.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/format/formatDiagnosticMessage.ts b/src/format/formatDiagnosticMessage.ts index 2d2d766..11a7123 100644 --- a/src/format/formatDiagnosticMessage.ts +++ b/src/format/formatDiagnosticMessage.ts @@ -1,5 +1,6 @@ import { inlineCodeBlock, unStyledCodeBlock } from "../components"; import { formatTypeBlock } from "./formatTypeBlock"; +import diagnosticPatterns from "./diagnosticPatterns.generated.json"; const formatTypeScriptBlock = (_: string, code: string) => inlineCodeBlock(code, "typescript"); @@ -7,29 +8,106 @@ const formatTypeScriptBlock = (_: string, code: string) => const formatSimpleTypeBlock = (_: string, code: string) => inlineCodeBlock(code, "type"); +type Pattern = { lang: string; regex: string; template: string }; + +type PatternName = keyof typeof diagnosticPatterns; +type Lang = (typeof diagnosticPatterns)[PatternName][number]["lang"]; +type Translation = Partial> & { fallback: string }; + +const nMore: Translation = { + fallback: "+ {numTruncatedProperties} ...", + en: "and {numTruncatedProperties} more...", + ja: "その他 {numTruncatedProperties} 個...", +}; + +const getPattern = (name: PatternName, lang: Lang): Pattern => { + const pattern = diagnosticPatterns[name]; + const matchedPattern = pattern.find((p) => p.lang === lang); + if (!matchedPattern) { + throw new Error(`Could not find pattern for ${name} in ${lang}`); + } + return matchedPattern; +}; + +const tryReplaceWithAllPatterns = ( + message: string, + patterns: Pattern[], + replaceWith: (captures: Record, lang: Lang) => string, +) => { + for (const pattern of patterns) { + let isMatched = false; + const replaced = message.replace( + new RegExp(pattern.regex, "g"), + (_, ...captures) => { + const groups = captures.at(-1)!; + isMatched = true; + return replaceWith(groups, pattern.lang); + }, + ); + if (isMatched) { + return replaced; + } + } + return message; +}; + export const formatDiagnosticMessage = ( message: string, - format: (type: string) => string -) => - message + format: (type: string) => string, +) => { + // format missing props error + const formattedTemp1 = tryReplaceWithAllPatterns( + message, + diagnosticPatterns.propertiesMissingWithoutTruncation, + ({ actualType, expectedType, propertyProperties }, lang) => { + const pattern = getPattern("propertiesMissingWithoutTruncation", lang); + return pattern.template + .replace("{actualType}", actualType) + .replace("{expectedType}", expectedType) + .replace( + "{propertyProperties}", + `
    ${propertyProperties + .split(", ") + .filter(Boolean) + .map((prop: string) => `
  • ${prop}
  • `) + .join("")}
`, + ); + }, + ); + const formattedTemp2 = tryReplaceWithAllPatterns( + formattedTemp1, + diagnosticPatterns.propertiesMissingWithTruncation, + ( + { actualType, expectedType, propertyProperties, numTruncatedProperties }, + lang, + ) => { + const pattern = getPattern("propertiesMissingWithoutTruncation", lang); + return pattern.template + .replace("{actualType}", actualType) + .replace("{expectedType}", expectedType) + .replace( + "{propertyProperties}", + `
    ${[ + ...propertyProperties.split(", ").filter(Boolean), + (nMore[lang] || nMore.fallback).replace( + "{numTruncatedProperties}", + numTruncatedProperties, + ), + ] + .map((prop: string) => `
  • ${prop}
  • `) + .join("")}
\n`, + ); + }, + ); + const formattedTemp3 = formattedTemp2 .replaceAll(/(?:\s)'"(.*?)(? - formatTypeBlock("", `"${p1}"`, format) + formatTypeBlock("", `"${p1}"`, format), ) // format declare module snippet .replaceAll( /['“](declare module )['”](.*)['“];['”]/g, (_: string, p1: string, p2: string) => - formatTypeScriptBlock(_, `${p1} "${p2}"`) - ) - // format missing props error - .replaceAll( - /(is missing the following properties from type\s?)'(.*)': ((?:#?\w+, )*(?:(?!and)\w+)?)/g, - (_, pre, type, post) => - `${pre}${formatTypeBlock("", type, format)}:
    ${post - .split(", ") - .filter(Boolean) - .map((prop: string) => `
  • ${prop}
  • `) - .join("")}
` + formatTypeScriptBlock(_, `${p1} "${p2}"`), ) // Format type pairs .replaceAll( @@ -38,8 +116,8 @@ export const formatDiagnosticMessage = ( `${formatTypeBlock(p1, p2, format)} and ${formatTypeBlock( "", p3, - format - )}` + format, + )}`, ) // Format type annotation options .replaceAll( @@ -48,54 +126,57 @@ export const formatDiagnosticMessage = ( `${formatTypeBlock(p1, p2, format)} or ${formatTypeBlock( "", p3, - format - )}` + format, + )}`, ) .replaceAll( /(Overload \d of \d), ['“](.*?)['”], /gi, - (_, p1: string, p2: string) => `${p1}${formatTypeBlock("", p2, format)}` + (_, p1: string, p2: string) => `${p1}${formatTypeBlock("", p2, format)}`, ) // format simple strings .replaceAll(/^['“]"[^"]*"['”]$/g, formatTypeScriptBlock) // Replace module 'x' by module "x" for ts error #2307 .replaceAll( /(module )'([^"]*?)'/gi, - (_, p1: string, p2: string) => `${p1}"${p2}"` + (_, p1: string, p2: string) => `${p1}"${p2}"`, ) // Format string types .replaceAll( /(module|file|file name) "(.*?)"(?=[\s(.|,)])/gi, - (_, p1: string, p2: string) => formatTypeBlock(p1, `"${p2}"`, format) + (_, p1: string, p2: string) => formatTypeBlock(p1, `"${p2}"`, format), ) // Format types .replaceAll( /(type|type alias|interface|module|file|file name|method's|subtype of constraint) ['“](.*?)['“](?=[\s(.|,)]|$)/gi, - (_, p1: string, p2: string) => formatTypeBlock(p1, p2, format) + (_, p1: string, p2: string) => formatTypeBlock(p1, p2, format), ) // Format reversed types .replaceAll( /(.*)['“]([^>]*)['”] (type|interface|return type|file|module|is (not )?assignable)/gi, (_: string, p1: string, p2: string, p3: string) => - `${p1}${formatTypeBlock("", p2, format)} ${p3}` + `${p1}${formatTypeBlock("", p2, format)} ${p3}`, ) // Format simple types that didn't captured before .replaceAll( /['“]((void|null|undefined|any|boolean|string|number|bigint|symbol)(\[\])?)['”]/g, - formatSimpleTypeBlock + formatSimpleTypeBlock, ) // Format some typescript key words .replaceAll( /['“](import|export|require|in|continue|break|let|false|true|const|new|throw|await|for await|[0-9]+)( ?.*?)['”]/g, (_: string, p1: string, p2: string) => - formatTypeScriptBlock(_, `${p1}${p2}`) + formatTypeScriptBlock(_, `${p1}${p2}`), ) // Format return values .replaceAll( /(return|operator) ['“](.*?)['”]/gi, - (_, p1: string, p2: string) => `${p1} ${formatTypeScriptBlock("", p2)}` + (_, p1: string, p2: string) => `${p1} ${formatTypeScriptBlock("", p2)}`, ) // Format regular code blocks .replaceAll( /(? ` ${unStyledCodeBlock(p1)} ` + (_: string, p1: string) => ` ${unStyledCodeBlock(p1)} `, ); + + return formattedTemp3; +}; diff --git a/tsconfig.json b/tsconfig.json index aa205de..957ba0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,8 @@ /* Additional Checks */ "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, - "esModuleInterop": true + "esModuleInterop": true, + "resolveJsonModule": true }, "include": ["src/**/*.ts"] } From 0ba8d5b9464cab4b059d6f9371ba373af87233a5 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 10:40:56 +0900 Subject: [PATCH 5/8] Fix: generate-regex -> generate-pattern --- package.json | 2 +- scripts/{generate-regex.ts => generate-pattern.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{generate-regex.ts => generate-pattern.ts} (100%) diff --git a/package.json b/package.json index fa65c06..1bd3c96 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "pretest": "npm run compile-tests && npm run compile && npm run lint", "lint": "eslint src --ext ts & tsc --noEmit", "test": "node ./out/test/runTest.js", - "generate-regex": "tsx scripts/generate-regex.ts" + "generate-pattern": "tsx scripts/generate-pattern.ts" }, "devDependencies": { "@types/glob": "^8.1.0", diff --git a/scripts/generate-regex.ts b/scripts/generate-pattern.ts similarity index 100% rename from scripts/generate-regex.ts rename to scripts/generate-pattern.ts From 857d16680b03c530d53ea19a5ad2b8356d6117b5 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 11:34:54 +0900 Subject: [PATCH 6/8] Fix: Fix patterns --- scripts/generate-pattern.ts | 31 ++- src/format/diagnosticPatterns.generated.json | 184 +++++++++---- src/format/formatDiagnosticMessage.ts | 263 +++++++++++-------- 3 files changed, 299 insertions(+), 179 deletions(-) diff --git a/scripts/generate-pattern.ts b/scripts/generate-pattern.ts index 443de9e..aa066c3 100644 --- a/scripts/generate-pattern.ts +++ b/scripts/generate-pattern.ts @@ -12,12 +12,13 @@ const templateToRegexAndNamedTemplate = ( } => { const escapedTemplate = template.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); let maxIndex = 0; - const regex = escapedTemplate.replace(/\\\{([0-9]+)\\\}/g, (_, index) => { - if (Number(index) > maxIndex) { - maxIndex = Number(index); - } - return `(?<${names[Number(index)]}>.*?)`; - }); + const regex = + escapedTemplate.replace(/\\\{([0-9]+)\\\}/g, (_, index) => { + if (Number(index) > maxIndex) { + maxIndex = Number(index); + } + return `(?<${names[Number(index)]}>.*?)`; + }) + "(?=$|)"; if (maxIndex !== names.length - 1) { throw new Error( `Expected ${maxIndex + 1} named groups, got ${names.length}`, @@ -52,19 +53,24 @@ const generatePatternsFromDiagnosticMessages = ( ): Record => { const ret: Record = {}; + // Type '...' is missing from the following properties from type '...': foo, bar const propertiesMissingWithoutTruncation = getMessageFromCode( diagnosticMessages, 2739, ); + // Type '...' is missing from the following properties from type '...': foo, bar, and N more. const propertiesMissingWithTruncation = getMessageFromCode( diagnosticMessages, 2740, ); + // Overload N of M, '...', gave the following error. + const overloadError = getMessageFromCode(diagnosticMessages, 2772); + ret.propertiesMissingWithoutTruncation = { ...templateToRegexAndNamedTemplate(propertiesMissingWithoutTruncation, [ "actualType", "expectedType", - "propertyProperties", + "properties", ]), lang, }; @@ -72,11 +78,19 @@ const generatePatternsFromDiagnosticMessages = ( ...templateToRegexAndNamedTemplate(propertiesMissingWithTruncation, [ "actualType", "expectedType", - "propertyProperties", + "properties", "numTruncatedProperties", ]), lang, }; + ret.overloadError = { + ...templateToRegexAndNamedTemplate(overloadError, [ + "overloadIndex", + "numOverloads", + "signature", + ]), + lang, + }; return ret; }; @@ -85,6 +99,7 @@ const generatePatternsFromDiagnosticMessages = ( const patterns = { propertiesMissingWithoutTruncation: [], propertiesMissingWithTruncation: [], + overloadError: [], } as Record; // diagnosticMessages.json is not exported in typescript library, so we fetch it from the TypeScript repository diff --git a/src/format/diagnosticPatterns.generated.json b/src/format/diagnosticPatterns.generated.json index 8cf64fa..8c13a55 100644 --- a/src/format/diagnosticPatterns.generated.json +++ b/src/format/diagnosticPatterns.generated.json @@ -1,145 +1,217 @@ { "propertiesMissingWithoutTruncation": [ { - "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?)", - "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {propertyProperties}", + "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?)(?=$|)", + "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {properties}", "lang": "en" }, { - "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?)", - "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {propertyProperties}", + "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?)(?=$|)", + "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {properties}", "lang": "cs" }, { - "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\"\\.", - "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{propertyProperties}\".", + "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\"\\.(?=$|)", + "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{properties}\".", "lang": "de" }, { - "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?)", - "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {propertyProperties}", + "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?)(?=$|)", + "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {properties}", "lang": "es" }, { - "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?)", - "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {propertyProperties}", + "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?)(?=$|)", + "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {properties}", "lang": "fr" }, { - "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?)", - "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {propertyProperties}", + "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?)(?=$|)", + "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {properties}", "lang": "it" }, { - "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)", - "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {propertyProperties}", + "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)(?=$|)", + "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {properties}", "lang": "ja" }, { - "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 속성이 없습니다\\.", - "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {propertyProperties} 속성이 없습니다.", + "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 속성이 없습니다\\.(?=$|)", + "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {properties} 속성이 없습니다.", "lang": "ko" }, { - "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?)", - "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {propertyProperties}", + "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?)(?=$|)", + "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {properties}", "lang": "pl" }, { - "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?)", - "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {propertyProperties}", + "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?)(?=$|)", + "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {properties}", "lang": "pt-br" }, { - "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?)", - "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {propertyProperties}", + "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?)(?=$|)", + "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {properties}", "lang": "ru" }, { - "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?)", - "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {propertyProperties}", + "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?)(?=$|)", + "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {properties}", "lang": "tr" }, { - "regex": "类型“(?.*?)”缺少类型“(?.*?)”中的以下属性: (?.*?)", - "template": "类型“{actualType}”缺少类型“{expectedType}”中的以下属性: {propertyProperties}", + "regex": "类型“(?.*?)”缺少类型“(?.*?)”中的以下属性: (?.*?)(?=$|)", + "template": "类型“{actualType}”缺少类型“{expectedType}”中的以下属性: {properties}", "lang": "zh-cn" }, { - "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?)", - "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {propertyProperties}", + "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?)(?=$|)", + "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {properties}", "lang": "zh-tw" } ], "propertiesMissingWithTruncation": [ { - "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?), and (?.*?) more\\.", - "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {propertyProperties}, and {numTruncatedProperties} more.", + "regex": "Type '(?.*?)' is missing the following properties from type '(?.*?)': (?.*?), and (?.*?) more\\.(?=$|)", + "template": "Type '{actualType}' is missing the following properties from type '{expectedType}': {properties}, and {numTruncatedProperties} more.", "lang": "en" }, { - "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?) a ještě (?.*?)", - "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {propertyProperties} a ještě {numTruncatedProperties}", + "regex": "V typu (?.*?) chybí následující vlastnosti z typu (?.*?): (?.*?) a ještě (?.*?)(?=$|)", + "template": "V typu {actualType} chybí následující vlastnosti z typu {expectedType}: {properties} a ještě {numTruncatedProperties}", "lang": "cs" }, { - "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\" und (?.*?) weitere\\.", - "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{propertyProperties}\" und {numTruncatedProperties} weitere.", + "regex": "Im Typ \"(?.*?)\" fehlen die folgenden Eigenschaften von Typ \"(?.*?)\": \"(?.*?)\" und (?.*?) weitere\\.(?=$|)", + "template": "Im Typ \"{actualType}\" fehlen die folgenden Eigenschaften von Typ \"{expectedType}\": \"{properties}\" und {numTruncatedProperties} weitere.", "lang": "de" }, { - "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?) y (?.*?) más\\.", - "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {propertyProperties} y {numTruncatedProperties} más.", + "regex": "Al tipo \"(?.*?)\" le faltan las propiedades siguientes del tipo \"(?.*?)\": (?.*?) y (?.*?) más\\.(?=$|)", + "template": "Al tipo \"{actualType}\" le faltan las propiedades siguientes del tipo \"{expectedType}\": {properties} y {numTruncatedProperties} más.", "lang": "es" }, { - "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?) et de (?.*?) autres\\.", - "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {propertyProperties} et de {numTruncatedProperties} autres.", + "regex": "Le type '(?.*?)' n'a pas les propriétés suivantes du type '(?.*?)': (?.*?) et de (?.*?) autres\\.(?=$|)", + "template": "Le type '{actualType}' n'a pas les propriétés suivantes du type '{expectedType}': {properties} et de {numTruncatedProperties} autres.", "lang": "fr" }, { - "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?) e altre (?.*?)\\.", - "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {propertyProperties} e altre {numTruncatedProperties}.", + "regex": "Nel tipo '(?.*?)' mancano le proprietà seguenti del tipo '(?.*?)': (?.*?) e altre (?.*?)\\.(?=$|)", + "template": "Nel tipo '{actualType}' mancano le proprietà seguenti del tipo '{expectedType}': {properties} e altre {numTruncatedProperties}.", "lang": "it" }, { - "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)、(?.*?) など。", - "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {propertyProperties}、{numTruncatedProperties} など。", + "regex": "型 '(?.*?)' には 型 '(?.*?)' からの次のプロパティがありません: (?.*?)、(?.*?) など。(?=$|)", + "template": "型 '{actualType}' には 型 '{expectedType}' からの次のプロパティがありません: {properties}、{numTruncatedProperties} など。", "lang": "ja" }, { - "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 외 (?.*?)개 속성이 없습니다\\.", - "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {propertyProperties} 외 {numTruncatedProperties}개 속성이 없습니다.", + "regex": "'(?.*?)' 형식에 '(?.*?)' 형식의 (?.*?) 외 (?.*?)개 속성이 없습니다\\.(?=$|)", + "template": "'{actualType}' 형식에 '{expectedType}' 형식의 {properties} 외 {numTruncatedProperties}개 속성이 없습니다.", "lang": "ko" }, { - "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?) i jeszcze (?.*?)\\.", - "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {propertyProperties} i jeszcze {numTruncatedProperties}.", + "regex": "W typie „(?.*?)” brakuje następujących właściwości z typu „(?.*?)”: (?.*?) i jeszcze (?.*?)\\.(?=$|)", + "template": "W typie „{actualType}” brakuje następujących właściwości z typu „{expectedType}”: {properties} i jeszcze {numTruncatedProperties}.", "lang": "pl" }, { - "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?) e mais (?.*?)\\.", - "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {propertyProperties} e mais {numTruncatedProperties}.", + "regex": "O tipo '(?.*?)' não tem as propriedades a seguir do tipo '(?.*?)': (?.*?) e mais (?.*?)\\.(?=$|)", + "template": "O tipo '{actualType}' não tem as propriedades a seguir do tipo '{expectedType}': {properties} e mais {numTruncatedProperties}.", "lang": "pt-br" }, { - "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?) и еще (?.*?)\\.", - "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {propertyProperties} и еще {numTruncatedProperties}.", + "regex": "В типе \"(?.*?)\" отсутствуют следующие свойства из типа \"(?.*?)\": (?.*?) и еще (?.*?)\\.(?=$|)", + "template": "В типе \"{actualType}\" отсутствуют следующие свойства из типа \"{expectedType}\": {properties} и еще {numTruncatedProperties}.", "lang": "ru" }, { - "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?) ve diğer (?.*?) özellik\\.", - "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {propertyProperties} ve diğer {numTruncatedProperties} özellik.", + "regex": "'(?.*?)' türünde, '(?.*?)' türündeki şu özellikler eksik: (?.*?) ve diğer (?.*?) özellik\\.(?=$|)", + "template": "'{actualType}' türünde, '{expectedType}' türündeki şu özellikler eksik: {properties} ve diğer {numTruncatedProperties} özellik.", "lang": "tr" }, { - "regex": "类型“(?.*?)”缺少类型“(?.*?)”的以下属性: (?.*?) 及其他 (?.*?) 项。", - "template": "类型“{actualType}”缺少类型“{expectedType}”的以下属性: {propertyProperties} 及其他 {numTruncatedProperties} 项。", + "regex": "类型“(?.*?)”缺少类型“(?.*?)”的以下属性: (?.*?) 及其他 (?.*?) 项。(?=$|)", + "template": "类型“{actualType}”缺少类型“{expectedType}”的以下属性: {properties} 及其他 {numTruncatedProperties} 项。", "lang": "zh-cn" }, { - "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?),以及另外 (?.*?) 個。", - "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {propertyProperties},以及另外 {numTruncatedProperties} 個。", + "regex": "類型 '(?.*?)' 在類型 '(?.*?)' 中缺少下列屬性: (?.*?),以及另外 (?.*?) 個。(?=$|)", + "template": "類型 '{actualType}' 在類型 '{expectedType}' 中缺少下列屬性: {properties},以及另外 {numTruncatedProperties} 個。", + "lang": "zh-tw" + } + ], + "overloadError": [ + { + "regex": "Overload (?.*?) of (?.*?), '(?.*?)', gave the following error\\.(?=$|)", + "template": "Overload {overloadIndex} of {numOverloads}, '{signature}', gave the following error.", + "lang": "en" + }, + { + "regex": "Přetížení (?.*?) z (?.*?), (?.*?), vrátilo následující chybu\\.(?=$|)", + "template": "Přetížení {overloadIndex} z {numOverloads}, {signature}, vrátilo následující chybu.", + "lang": "cs" + }, + { + "regex": "Die Überladung (?.*?) von (?.*?) \\((?.*?)\\) hat den folgenden Fehler verursacht\\.(?=$|)", + "template": "Die Überladung {overloadIndex} von {numOverloads} ({signature}) hat den folgenden Fehler verursacht.", + "lang": "de" + }, + { + "regex": "La sobrecarga (?.*?) de (?.*?), \"(?.*?)\", dio el error siguiente\\.(?=$|)", + "template": "La sobrecarga {overloadIndex} de {numOverloads}, \"{signature}\", dio el error siguiente.", + "lang": "es" + }, + { + "regex": "La surcharge (?.*?) sur (?.*?), '(?.*?)', a généré l'erreur suivante\\.(?=$|)", + "template": "La surcharge {overloadIndex} sur {numOverloads}, '{signature}', a généré l'erreur suivante.", + "lang": "fr" + }, + { + "regex": "L'overload (?.*?) di (?.*?),'(?.*?)', ha restituito l'errore seguente\\.(?=$|)", + "template": "L'overload {overloadIndex} di {numOverloads},'{signature}', ha restituito l'errore seguente.", + "lang": "it" + }, + { + "regex": "(?.*?) 中 (?.*?) のオーバーロード, '(?.*?)' により、次のエラーが発生しました。(?=$|)", + "template": "{numOverloads} 中 {overloadIndex} のオーバーロード, '{signature}' により、次のエラーが発生しました。", + "lang": "ja" + }, + { + "regex": "오버로드 (?.*?)\\/(?.*?)\\('(?.*?)'\\)에서 다음 오류가 발생했습니다\\.(?=$|)", + "template": "오버로드 {overloadIndex}/{numOverloads}('{signature}')에서 다음 오류가 발생했습니다.", + "lang": "ko" + }, + { + "regex": "Przeciążenie (?.*?) z (?.*?), „(?.*?)”, zwróciło następujący błąd\\.(?=$|)", + "template": "Przeciążenie {overloadIndex} z {numOverloads}, „{signature}”, zwróciło następujący błąd.", + "lang": "pl" + }, + { + "regex": "A sobrecarga (?.*?) de (?.*?), '(?.*?)', gerou o seguinte erro\\.(?=$|)", + "template": "A sobrecarga {overloadIndex} de {numOverloads}, '{signature}', gerou o seguinte erro.", + "lang": "pt-br" + }, + { + "regex": "Перегрузка (?.*?) из (?.*?), \"(?.*?)\", возвратила следующую ошибку\\.(?=$|)", + "template": "Перегрузка {overloadIndex} из {numOverloads}, \"{signature}\", возвратила следующую ошибку.", + "lang": "ru" + }, + { + "regex": "(?.*?)\\/(?.*?) aşırı yükleme '(?.*?)' imzası, aşağıdaki hatayı verdi\\.(?=$|)", + "template": "{overloadIndex}/{numOverloads} aşırı yükleme '{signature}' imzası, aşağıdaki hatayı verdi.", + "lang": "tr" + }, + { + "regex": "第 (?.*?) 个重载\\(共 (?.*?) 个\\),“(?.*?)”,出现以下错误。(?=$|)", + "template": "第 {overloadIndex} 个重载(共 {numOverloads} 个),“{signature}”,出现以下错误。", + "lang": "zh-cn" + }, + { + "regex": "多載 (?.*?) \\(共 (?.*?)\\),'(?.*?)',發生下列錯誤。(?=$|)", + "template": "多載 {overloadIndex} (共 {numOverloads}),'{signature}',發生下列錯誤。", "lang": "zh-tw" } ] diff --git a/src/format/formatDiagnosticMessage.ts b/src/format/formatDiagnosticMessage.ts index 11a7123..f7670bb 100644 --- a/src/format/formatDiagnosticMessage.ts +++ b/src/format/formatDiagnosticMessage.ts @@ -20,6 +20,14 @@ const nMore: Translation = { ja: "その他 {numTruncatedProperties} 個...", }; +const createPatternWithQuotesAround = (pattern: string) => { + const escapedPattern = pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); + return new RegExp( + `\\p{QMark}${escapedPattern}\\p{QMark}|${escapedPattern}`, + "gu", + ); +}; + const getPattern = (name: PatternName, lang: Lang): Pattern => { const pattern = diagnosticPatterns[name]; const matchedPattern = pattern.find((p) => p.lang === lang); @@ -37,7 +45,7 @@ const tryReplaceWithAllPatterns = ( for (const pattern of patterns) { let isMatched = false; const replaced = message.replace( - new RegExp(pattern.regex, "g"), + new RegExp(pattern.regex, "gm"), (_, ...captures) => { const groups = captures.at(-1)!; isMatched = true; @@ -51,6 +59,29 @@ const tryReplaceWithAllPatterns = ( return message; }; +const formatMissingProps = ( + lang: Lang, + format: (type: string) => string, + actualType: string, + expectedType: string, + properties: string[], +) => { + const pattern = getPattern("propertiesMissingWithoutTruncation", lang); + return pattern.template + .replace( + createPatternWithQuotesAround("{actualType}"), + formatTypeBlock("", actualType, format), + ) + .replace( + createPatternWithQuotesAround("{expectedType}"), + formatTypeBlock("", expectedType, format), + ) + .replace( + "{properties}", + `
    ${properties.map((prop) => `
  • ${prop}
  • `).join("")}
\n`, + ); +}; + export const formatDiagnosticMessage = ( message: string, format: (type: string) => string, @@ -58,125 +89,127 @@ export const formatDiagnosticMessage = ( // format missing props error const formattedTemp1 = tryReplaceWithAllPatterns( message, - diagnosticPatterns.propertiesMissingWithoutTruncation, - ({ actualType, expectedType, propertyProperties }, lang) => { - const pattern = getPattern("propertiesMissingWithoutTruncation", lang); - return pattern.template - .replace("{actualType}", actualType) - .replace("{expectedType}", expectedType) - .replace( - "{propertyProperties}", - `
    ${propertyProperties - .split(", ") - .filter(Boolean) - .map((prop: string) => `
  • ${prop}
  • `) - .join("")}
`, - ); - }, - ); - const formattedTemp2 = tryReplaceWithAllPatterns( - formattedTemp1, diagnosticPatterns.propertiesMissingWithTruncation, ( - { actualType, expectedType, propertyProperties, numTruncatedProperties }, + { actualType, expectedType, properties, numTruncatedProperties }, lang, ) => { - const pattern = getPattern("propertiesMissingWithoutTruncation", lang); - return pattern.template - .replace("{actualType}", actualType) - .replace("{expectedType}", expectedType) - .replace( - "{propertyProperties}", - `
    ${[ - ...propertyProperties.split(", ").filter(Boolean), - (nMore[lang] || nMore.fallback).replace( - "{numTruncatedProperties}", - numTruncatedProperties, - ), - ] - .map((prop: string) => `
  • ${prop}
  • `) - .join("")}
\n`, - ); + return formatMissingProps(lang, format, actualType, expectedType, [ + ...properties.split(", ").filter(Boolean), + (nMore[lang] || nMore.fallback).replace( + "{numTruncatedProperties}", + numTruncatedProperties, + ), + ]); + }, + ); + const formattedTemp2 = tryReplaceWithAllPatterns( + formattedTemp1, + diagnosticPatterns.propertiesMissingWithoutTruncation, + ({ actualType, expectedType, properties }, lang) => { + return formatMissingProps( + lang, + format, + actualType, + expectedType, + properties.split(", ").filter(Boolean), + ); }, ); - const formattedTemp3 = formattedTemp2 - .replaceAll(/(?:\s)'"(.*?)(? - formatTypeBlock("", `"${p1}"`, format), - ) - // format declare module snippet - .replaceAll( - /['“](declare module )['”](.*)['“];['”]/g, - (_: string, p1: string, p2: string) => - formatTypeScriptBlock(_, `${p1} "${p2}"`), - ) - // Format type pairs - .replaceAll( - /(types) ['“](.*?)['”] and ['“](.*?)['”][\.]?/gi, - (_: string, p1: string, p2: string, p3: string) => - `${formatTypeBlock(p1, p2, format)} and ${formatTypeBlock( - "", - p3, - format, - )}`, - ) - // Format type annotation options - .replaceAll( - /type annotation must be ['“](.*?)['”] or ['“](.*?)['”][\.]?/gi, - (_: string, p1: string, p2: string, p3: string) => - `${formatTypeBlock(p1, p2, format)} or ${formatTypeBlock( - "", - p3, - format, - )}`, - ) - .replaceAll( - /(Overload \d of \d), ['“](.*?)['”], /gi, - (_, p1: string, p2: string) => `${p1}${formatTypeBlock("", p2, format)}`, - ) - // format simple strings - .replaceAll(/^['“]"[^"]*"['”]$/g, formatTypeScriptBlock) - // Replace module 'x' by module "x" for ts error #2307 - .replaceAll( - /(module )'([^"]*?)'/gi, - (_, p1: string, p2: string) => `${p1}"${p2}"`, - ) - // Format string types - .replaceAll( - /(module|file|file name) "(.*?)"(?=[\s(.|,)])/gi, - (_, p1: string, p2: string) => formatTypeBlock(p1, `"${p2}"`, format), - ) - // Format types - .replaceAll( - /(type|type alias|interface|module|file|file name|method's|subtype of constraint) ['“](.*?)['“](?=[\s(.|,)]|$)/gi, - (_, p1: string, p2: string) => formatTypeBlock(p1, p2, format), - ) - // Format reversed types - .replaceAll( - /(.*)['“]([^>]*)['”] (type|interface|return type|file|module|is (not )?assignable)/gi, - (_: string, p1: string, p2: string, p3: string) => - `${p1}${formatTypeBlock("", p2, format)} ${p3}`, - ) - // Format simple types that didn't captured before - .replaceAll( - /['“]((void|null|undefined|any|boolean|string|number|bigint|symbol)(\[\])?)['”]/g, - formatSimpleTypeBlock, - ) - // Format some typescript key words - .replaceAll( - /['“](import|export|require|in|continue|break|let|false|true|const|new|throw|await|for await|[0-9]+)( ?.*?)['”]/g, - (_: string, p1: string, p2: string) => - formatTypeScriptBlock(_, `${p1}${p2}`), - ) - // Format return values - .replaceAll( - /(return|operator) ['“](.*?)['”]/gi, - (_, p1: string, p2: string) => `${p1} ${formatTypeScriptBlock("", p2)}`, - ) - // Format regular code blocks - .replaceAll( - /(? ` ${unStyledCodeBlock(p1)} `, - ); - return formattedTemp3; + // Format overloads + const formattedTemp3 = tryReplaceWithAllPatterns( + formattedTemp2, + diagnosticPatterns.overloadError, + ({ overloadIndex, numOverloads, signature }, lang) => { + const pattern = getPattern("overloadError", lang); + return ( + pattern.template + .replace("{overloadIndex}", overloadIndex) + .replace("{numOverloads}", numOverloads) + // Remove quotes around signature + .replace( + createPatternWithQuotesAround("{signature}"), + formatTypeBlock("", signature, format), + ) + ); + }, + ); + + return ( + formattedTemp3 + .replaceAll(/(?:\s)'"(.*?)(? + formatTypeBlock("", `"${p1}"`, format), + ) + // format declare module snippet + .replaceAll( + /['“](declare module )['”](.*)['“];['”]/g, + (_: string, p1: string, p2: string) => + formatTypeScriptBlock(_, `${p1} "${p2}"`), + ) + // Format type pairs + .replaceAll( + /(types) ['“](.*?)['”] and ['“](.*?)['”][\.]?/gi, + (_: string, p1: string, p2: string, p3: string) => + `${formatTypeBlock(p1, p2, format)} and ${formatTypeBlock( + "", + p3, + format, + )}`, + ) + // Format type annotation options + .replaceAll( + /type annotation must be ['“](.*?)['”] or ['“](.*?)['”][\.]?/gi, + (_: string, p1: string, p2: string, p3: string) => + `${formatTypeBlock(p1, p2, format)} or ${formatTypeBlock( + "", + p3, + format, + )}`, + ) + // format simple strings + .replaceAll(/^['“]"[^"]*"['”]$/g, formatTypeScriptBlock) + // Replace module 'x' by module "x" for ts error #2307 + .replaceAll( + /(module )'([^"]*?)'/gi, + (_, p1: string, p2: string) => `${p1}"${p2}"`, + ) + // Format string types + .replaceAll( + /(module|file|file name) "(.*?)"(?=[\s(.|,)])/gi, + (_, p1: string, p2: string) => formatTypeBlock(p1, `"${p2}"`, format), + ) + // Format types + .replaceAll( + /(type|type alias|interface|module|file|file name|method's|subtype of constraint) ['“](.*?)['“](?=[\s(.|,)]|$)/gi, + (_, p1: string, p2: string) => formatTypeBlock(p1, p2, format), + ) + // Format reversed types + .replaceAll( + /(.*)['“]([^>]*)['”] (type|interface|return type|file|module|is (not )?assignable)/gi, + (_: string, p1: string, p2: string, p3: string) => + `${p1}${formatTypeBlock("", p2, format)} ${p3}`, + ) + // Format simple types that didn't captured before + .replaceAll( + /['“]((void|null|undefined|any|boolean|string|number|bigint|symbol)(\[\])?)['”]/g, + formatSimpleTypeBlock, + ) + // Format some typescript key words + .replaceAll( + /['“](import|export|require|in|continue|break|let|false|true|const|new|throw|await|for await|[0-9]+)( ?.*?)['”]/g, + (_: string, p1: string, p2: string) => + formatTypeScriptBlock(_, `${p1}${p2}`), + ) + // Format return values + .replaceAll( + /(return|operator) ['“](.*?)['”]/gi, + (_, p1: string, p2: string) => `${p1} ${formatTypeScriptBlock("", p2)}`, + ) + // Format regular code blocks + .replaceAll( + /(? ` ${unStyledCodeBlock(p1)} `, + ) + ); }; From 486f040c28b086b4d36b25df01b6697388b7f5a8 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 11:35:34 +0900 Subject: [PATCH 7/8] Add: Add gitattributes --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8bd5fdc --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.generated.* linguist-generated From 3a5953038c409528427cb1302987099ff28d975d Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Mon, 3 Jun 2024 11:49:44 +0900 Subject: [PATCH 8/8] Add: Add types keywords for Japanese --- src/format/formatDiagnosticMessage.ts | 13 +++++------ src/format/translations.ts | 32 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 src/format/translations.ts diff --git a/src/format/formatDiagnosticMessage.ts b/src/format/formatDiagnosticMessage.ts index f7670bb..174961f 100644 --- a/src/format/formatDiagnosticMessage.ts +++ b/src/format/formatDiagnosticMessage.ts @@ -1,6 +1,7 @@ import { inlineCodeBlock, unStyledCodeBlock } from "../components"; import { formatTypeBlock } from "./formatTypeBlock"; import diagnosticPatterns from "./diagnosticPatterns.generated.json"; +import { nMore, typeKeywords } from "./translations"; const formatTypeScriptBlock = (_: string, code: string) => inlineCodeBlock(code, "typescript"); @@ -12,13 +13,6 @@ type Pattern = { lang: string; regex: string; template: string }; type PatternName = keyof typeof diagnosticPatterns; type Lang = (typeof diagnosticPatterns)[PatternName][number]["lang"]; -type Translation = Partial> & { fallback: string }; - -const nMore: Translation = { - fallback: "+ {numTruncatedProperties} ...", - en: "and {numTruncatedProperties} more...", - ja: "その他 {numTruncatedProperties} 個...", -}; const createPatternWithQuotesAround = (pattern: string) => { const escapedPattern = pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"); @@ -181,7 +175,10 @@ export const formatDiagnosticMessage = ( ) // Format types .replaceAll( - /(type|type alias|interface|module|file|file name|method's|subtype of constraint) ['“](.*?)['“](?=[\s(.|,)]|$)/gi, + new RegExp( + `(${typeKeywords.join("|")}) ['“](.*?)['”](?=[\\s(.|,)]|$)`, + "gi", + ), (_, p1: string, p2: string) => formatTypeBlock(p1, p2, format), ) // Format reversed types diff --git a/src/format/translations.ts b/src/format/translations.ts new file mode 100644 index 0000000..21dc24e --- /dev/null +++ b/src/format/translations.ts @@ -0,0 +1,32 @@ +import diagnosticPatterns from "./diagnosticPatterns.generated.json"; + +type Lang = + (typeof diagnosticPatterns)[keyof typeof diagnosticPatterns][number]["lang"]; +export type Translation = Partial> & { fallback: string }; + +export const nMore: Translation = { + fallback: "+ {numTruncatedProperties} ...", + en: "and {numTruncatedProperties} more...", + ja: "その他 {numTruncatedProperties} 個...", +}; + +export const typeKeywords = [ + // English + "type", + "type alias", + "interface", + "module", + "file", + "file name", + "method's", + "subtype of constraint", + // Japanese + "型", + "型エイリアス", + "型のエイリアス", + "インターフェイス", + "モジュール", + "ファイル", + "ファイル名", + "メソッド", +];