From 6c43677f8e0e92ec42285dafcaa5ffa4419dea9c Mon Sep 17 00:00:00 2001 From: Radoslav Karaivanov Date: Thu, 28 May 2026 20:00:57 +0300 Subject: [PATCH 1/2] build: Cleanup build scripts and watchers - Dropped node-watch dependency and replaced it with native fs.watch - Updated build-styles.mjs to use a single buildAll function instead of separate buildThemes and buildComponents functions - Improved logging in stories-watcher.js to include timestamps and better error handling - Updated dev dependencies in package.json --- package-lock.json | 549 +++++++++++++++++------------ package.json | 25 +- scripts/build-stories.mjs | 411 +++++++++++---------- scripts/build-styles.mjs | 4 +- scripts/build.mjs | 6 +- scripts/sass.mjs | 118 +++++-- scripts/stories-watcher.js | 34 +- scripts/styles-watcher.mjs | 39 +- stories/date-time-input.stories.ts | 109 +++--- 9 files changed, 722 insertions(+), 573 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd47e29954..b62521e20e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,40 +16,39 @@ "lit": "^3.3.3" }, "devDependencies": { - "@biomejs/biome": "~2.4.15", + "@biomejs/biome": "~2.4.16", "@custom-elements-manifest/analyzer": "^0.11.0", "@igniteui/material-icons-extended": "^3.1.0", "@open-wc/testing": "^4.0.0", - "@storybook/addon-a11y": "^10.4.0", - "@storybook/addon-docs": "^10.4.0", - "@storybook/addon-links": "^10.4.0", - "@storybook/web-components-vite": "^10.4.0", + "@storybook/addon-a11y": "^10.4.1", + "@storybook/addon-docs": "^10.4.1", + "@storybook/addon-links": "^10.4.1", + "@storybook/web-components-vite": "^10.4.1", "@types/mocha": "^10.0.10", "@web/dev-server-esbuild": "^1.0.5", "@web/test-runner": "^0.20.2", "@web/test-runner-playwright": "^0.11.1", "autoprefixer": "^10.5.0", "cem-plugin-expanded-types": "^1.4.0", - "concurrently": "^9.2.1", + "concurrently": "^10.0.0", "custom-element-jet-brains-integration": "^1.7.0", "custom-element-vs-code-integration": "^1.5.0", - "dependency-cruiser": "^17.4.0", + "dependency-cruiser": "^17.4.2", "husky": "^9.1.7", "ig-typedoc-theme": "^7.0.1", "igniteui-i18n-resources": "^1.0.5", "igniteui-theming": "^26.0.1", - "keep-a-changelog": "^3.0.3", + "keep-a-changelog": "^3.0.4", "lint-staged": "^17.0.5", "lit-analyzer": "^2.0.3", - "node-watch": "^0.7.4", "playwright": "^1.60.0", "postcss": "^8.5.15", "prettier": "^3.8.3", "rimraf": "^6.1.3", "sass-embedded": "~1.93.3", "sinon": "^22.0.0", - "storybook": "^10.4.0", - "stylelint": "^17.11.1", + "storybook": "^10.4.1", + "stylelint": "^17.12.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", "stylelint-scss": "^7.1.1", @@ -58,10 +57,10 @@ "typedoc": "~0.28.19", "typedoc-plugin-localization": "^3.1.0", "typescript": "^6.0.3", - "vite": "^8.0.13" + "vite": "^8.0.14" }, "peerDependencies": { - "dompurify": "^3.4.5", + "dompurify": "^3.4.7", "marked": "^18.0.4", "marked-shiki": "^1.2.1", "shiki": "^4.1.0" @@ -110,9 +109,9 @@ } }, "node_modules/@biomejs/biome": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.15.tgz", - "integrity": "sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.16.tgz", + "integrity": "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -126,20 +125,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.4.15", - "@biomejs/cli-darwin-x64": "2.4.15", - "@biomejs/cli-linux-arm64": "2.4.15", - "@biomejs/cli-linux-arm64-musl": "2.4.15", - "@biomejs/cli-linux-x64": "2.4.15", - "@biomejs/cli-linux-x64-musl": "2.4.15", - "@biomejs/cli-win32-arm64": "2.4.15", - "@biomejs/cli-win32-x64": "2.4.15" + "@biomejs/cli-darwin-arm64": "2.4.16", + "@biomejs/cli-darwin-x64": "2.4.16", + "@biomejs/cli-linux-arm64": "2.4.16", + "@biomejs/cli-linux-arm64-musl": "2.4.16", + "@biomejs/cli-linux-x64": "2.4.16", + "@biomejs/cli-linux-x64-musl": "2.4.16", + "@biomejs/cli-win32-arm64": "2.4.16", + "@biomejs/cli-win32-x64": "2.4.16" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.15.tgz", - "integrity": "sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.16.tgz", + "integrity": "sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==", "cpu": [ "arm64" ], @@ -154,9 +153,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.15.tgz", - "integrity": "sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.16.tgz", + "integrity": "sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==", "cpu": [ "x64" ], @@ -171,9 +170,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.15.tgz", - "integrity": "sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.16.tgz", + "integrity": "sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==", "cpu": [ "arm64" ], @@ -191,9 +190,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.15.tgz", - "integrity": "sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.16.tgz", + "integrity": "sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==", "cpu": [ "arm64" ], @@ -211,9 +210,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.15.tgz", - "integrity": "sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.16.tgz", + "integrity": "sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==", "cpu": [ "x64" ], @@ -231,9 +230,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.15.tgz", - "integrity": "sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.16.tgz", + "integrity": "sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==", "cpu": [ "x64" ], @@ -251,9 +250,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.15.tgz", - "integrity": "sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.16.tgz", + "integrity": "sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==", "cpu": [ "arm64" ], @@ -268,9 +267,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.4.15", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.15.tgz", - "integrity": "sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ==", + "version": "2.4.16", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.16.tgz", + "integrity": "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==", "cpu": [ "x64" ], @@ -2516,9 +2515,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.1.tgz", - "integrity": "sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz", + "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==", "cpu": [ "arm64" ], @@ -2533,9 +2532,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.1.tgz", - "integrity": "sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==", "cpu": [ "arm64" ], @@ -2550,9 +2549,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.1.tgz", - "integrity": "sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz", + "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==", "cpu": [ "x64" ], @@ -2567,9 +2566,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.1.tgz", - "integrity": "sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz", + "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==", "cpu": [ "x64" ], @@ -2584,9 +2583,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.1.tgz", - "integrity": "sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz", + "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==", "cpu": [ "arm" ], @@ -2601,9 +2600,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.1.tgz", - "integrity": "sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz", + "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==", "cpu": [ "arm64" ], @@ -2621,9 +2620,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.1.tgz", - "integrity": "sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz", + "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==", "cpu": [ "arm64" ], @@ -2641,9 +2640,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.1.tgz", - "integrity": "sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz", + "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==", "cpu": [ "ppc64" ], @@ -2661,9 +2660,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.1.tgz", - "integrity": "sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz", + "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==", "cpu": [ "s390x" ], @@ -2681,9 +2680,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.1.tgz", - "integrity": "sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.2.tgz", + "integrity": "sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==", "cpu": [ "x64" ], @@ -2701,9 +2700,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.1.tgz", - "integrity": "sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.2.tgz", + "integrity": "sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==", "cpu": [ "x64" ], @@ -2721,9 +2720,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.1.tgz", - "integrity": "sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz", + "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==", "cpu": [ "arm64" ], @@ -2738,9 +2737,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.1.tgz", - "integrity": "sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz", + "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==", "cpu": [ "wasm32" ], @@ -2757,9 +2756,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.1.tgz", - "integrity": "sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz", + "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==", "cpu": [ "arm64" ], @@ -2774,9 +2773,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz", - "integrity": "sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz", + "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==", "cpu": [ "x64" ], @@ -3409,9 +3408,9 @@ } }, "node_modules/@storybook/addon-a11y": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.4.0.tgz", - "integrity": "sha512-N1QRmh+PMe5O81KDf8oPDv/csdLAmDCRCYLByukqdUXpTNlcULHDFUJNXl00/rFpbt7PbOZqzRzs72JJt6nWPA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-10.4.1.tgz", + "integrity": "sha512-MGft/IXjJ20a9KbaSVG9bHTAAoanbucKrgEiJJRNqpim8DsXA01+XTdSk17LmiOCB203Rrq9mWgdQ6+79cc8iA==", "dev": true, "license": "MIT", "dependencies": { @@ -3423,20 +3422,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.4.0" + "storybook": "^10.4.1" } }, "node_modules/@storybook/addon-docs": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.4.0.tgz", - "integrity": "sha512-HJNvYGx/c3jjVwibnmbDgCZMYPI6xGUDjJSRi5CG0G9tpeoeijPo318f5N84RyYWK8LheHUrDN3Jv2UfVv8zwQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.4.1.tgz", + "integrity": "sha512-IYqUdjoZe4VO2LFZlKL/gwy7DsQSWCq6hX+zc1MBmZo04yycDASk1tte57n9pdlW3ajw9yYMF/+lVBi+xQjyvw==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/csf-plugin": "10.4.0", + "@storybook/csf-plugin": "10.4.1", "@storybook/icons": "^2.0.2", - "@storybook/react-dom-shim": "10.4.0", + "@storybook/react-dom-shim": "10.4.1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -3447,7 +3446,7 @@ }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.0" + "storybook": "^10.4.1" }, "peerDependenciesMeta": { "@types/react": { @@ -3456,9 +3455,9 @@ } }, "node_modules/@storybook/addon-links": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.4.0.tgz", - "integrity": "sha512-+NE1NGDoZD7U5XBEuIJvmh/fxjaVxfTxAYMWHcpwb6Qqx9Ew7gYVou5pKpiweW1wjbh+xScIVg0nPw+WyBCsyg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.4.1.tgz", + "integrity": "sha512-h/5D23GwMuHA55sB7XDyhByF9psF7UFmaQOn72pjNAarew5eOpue5A+jXk3AKEYokHbvgQaoz+FrvWo9GEfSKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3471,7 +3470,7 @@ "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.0" + "storybook": "^10.4.1" }, "peerDependenciesMeta": { "@types/react": { @@ -3483,13 +3482,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.0.tgz", - "integrity": "sha512-RCq8uzvTc0vhK2aN0y2Z48DJ9Q7oKXh8A5pdU3YAmkgMcX/+Vi3Ju1nmueLrGIO+tKwYGpYS/ccUtscNt92rCw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.4.1.tgz", + "integrity": "sha512-/oyQrXoNOqN8SW5hNnYP+I1uvgFxKxWXj/EP6NXYzc5SQwImofgru+D2+6gDhL0+Q//+Hx05DJoQO2omvUJ8bQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "10.4.0", + "@storybook/csf-plugin": "10.4.1", "ts-dedent": "^2.0.0" }, "funding": { @@ -3497,14 +3496,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.4.0", + "storybook": "^10.4.1", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.0.tgz", - "integrity": "sha512-iSmrhMyEi2ohCWKu49ZUUf8l+k0OIStbWI1BTWt2FvKySlnqY/aHenus7839SgNL3aUNG5P0y9zlyN6/HlwlEQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.4.1.tgz", + "integrity": "sha512-WdPepGBxDGOUDjYd8KxMtcf+us/2PAcnBczl77XtrnxxHNs0jWesxKkiJ9yiuGrge4BPhDeAj6rxjbBoaHxLBA==", "dev": true, "license": "MIT", "dependencies": { @@ -3517,7 +3516,7 @@ "peerDependencies": { "esbuild": "*", "rollup": "*", - "storybook": "^10.4.0", + "storybook": "^10.4.1", "vite": "*", "webpack": "*" }, @@ -3555,9 +3554,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.0.tgz", - "integrity": "sha512-dcYWzdPaJEHVlyOyyz0/0v3QJXmcnK2sjw4YiFwU9IVJhoJrBlE9lMtmbO3QqIbq4qA0hElYtGkKO7tMLSKDGw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.4.1.tgz", + "integrity": "sha512-6QFqfDNH4DMrt7yHKRfpqRopsVUc/Az+sXIdJ39IetYnHUxL3nW4NVaPc6uy/8Qi8urzUyEXL/nn7cpSIP2aPQ==", "dev": true, "license": "MIT", "funding": { @@ -3569,7 +3568,7 @@ "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.4.0" + "storybook": "^10.4.1" }, "peerDependenciesMeta": { "@types/react": { @@ -3581,9 +3580,9 @@ } }, "node_modules/@storybook/web-components": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-10.4.0.tgz", - "integrity": "sha512-Sq3PuLO6A2Jd26Pjq9Abd7QaHgeEvN3J2T4YkQyBANacumUqe98bqxp9W8bEnVW4yYNt7Trjimu3IBYdeVZ/7w==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-10.4.1.tgz", + "integrity": "sha512-bvvIQZK7vdxoVrBmQtbvtNU5ugFF8dETc0l2j58nPUerDHUook8dFNXUiKfK1KmnLsBZ/7KEjPPmk7sEHygvlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3597,25 +3596,25 @@ }, "peerDependencies": { "lit": "^2.0.0 || ^3.0.0", - "storybook": "^10.4.0" + "storybook": "^10.4.1" } }, "node_modules/@storybook/web-components-vite": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-10.4.0.tgz", - "integrity": "sha512-dExmamVJnfBxB3tiPDJoCXLXGHuMrPQtGrlL5ROklVxYF2LbqtrRXW/CUaehXLDDND0h4usieIrcdPPTLDPiuw==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-10.4.1.tgz", + "integrity": "sha512-i66ublYmQNK9zvSgiT7w9zSHCcXh+g7lHWFoxO+QX7riRLMmtk5uOlWna9P7Ny41fkoQ7POKWJAuZ9PLBPl/Ug==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-vite": "10.4.0", - "@storybook/web-components": "10.4.0" + "@storybook/builder-vite": "10.4.1", + "@storybook/web-components": "10.4.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^10.4.0", + "storybook": "^10.4.1", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, @@ -5905,46 +5904,155 @@ } }, "node_modules/concurrently": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", - "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.0.tgz", + "integrity": "sha512-DRrk10z3sVPpguNe8od2cGNqZGqbT15rwAnxD4dG3b78mdNNb/gJyr8T834Oj518WcBmTktrt4FhdwZn09ZWSg==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "4.1.2", + "chalk": "5.6.2", "rxjs": "7.8.2", - "shell-quote": "1.8.3", - "supports-color": "8.1.1", + "shell-quote": "1.8.4", + "supports-color": "10.2.2", "tree-kill": "1.2.2", - "yargs": "17.7.2" + "yargs": "18.0.0" }, "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" + "conc": "dist/bin/index.js", + "concurrently": "dist/bin/index.js" }, "engines": { - "node": ">=18" + "node": ">=22" }, "funding": { "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, - "node_modules/concurrently/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", "dependencies": { - "has-flag": "^4.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10" + "node": ">=20" + } + }, + "node_modules/concurrently/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/concurrently/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/concurrently/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, "node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", @@ -6297,9 +6405,9 @@ } }, "node_modules/dependency-cruiser": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-17.4.0.tgz", - "integrity": "sha512-+WdFoOb+fT1XNC0iPqOyLpfhLd8xVh7eLXJxPAtiXCS+YmXzGrjqVTte7+L8SZIsnJj0aFhb8LxECIBJY5TTIA==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-17.4.2.tgz", + "integrity": "sha512-XbrWY2EkIRoqvJL3feRlwHiYrPD2h6iYZ+LaMZgMLpxDBFXKb3+rXGVAli3/fV+yd9rgTBtFpuAYMDt4RjHQUA==", "dev": true, "license": "MIT", "dependencies": { @@ -6309,7 +6417,7 @@ "acorn-loose": "8.5.2", "acorn-walk": "8.3.5", "commander": "14.0.3", - "enhanced-resolve": "5.21.0", + "enhanced-resolve": "5.22.0", "ignore": "7.0.5", "interpret": "3.1.1", "is-installed-globally": "1.0.0", @@ -6318,7 +6426,7 @@ "prompts": "2.4.2", "rechoir": "0.8.0", "safe-regex": "2.1.1", - "semver": "7.7.4", + "semver": "7.8.1", "tsconfig-paths-webpack-plugin": "4.2.0", "watskeburt": "5.0.3" }, @@ -6347,6 +6455,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/dependency-cruiser/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", @@ -6455,9 +6576,9 @@ "peer": true }, "node_modules/dompurify": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.5.tgz", - "integrity": "sha512-OrwIBKsdNSVEeubdJ1HBv/wNENRM9ytAVCv7YXt//A3vPdVMNuACRqK9mXCGCBW2ln7BT/A4X0jXHo2Gu89miA==", + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.7.tgz", + "integrity": "sha512-2jBxDJY4RR06tQNy4w5FlFH7kfxsQZlufd0sbv+chfHCxeJwrFw2baUDsSwvBISD4K4RDbd0PTfy3uNXsR6siA==", "license": "(MPL-2.0 OR Apache-2.0)", "peer": true, "optionalDependencies": { @@ -6521,9 +6642,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", - "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.0.tgz", + "integrity": "sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==", "dev": true, "license": "MIT", "dependencies": { @@ -8839,9 +8960,9 @@ } }, "node_modules/keep-a-changelog": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keep-a-changelog/-/keep-a-changelog-3.0.3.tgz", - "integrity": "sha512-eLTf1egh0t+RSe8JTVZwebsDQczPnzcNcslnCjFrcvjcZFgkYygEPWUjVMFwizh55+WKE+UP/dTtpPgrCUYT0w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keep-a-changelog/-/keep-a-changelog-3.0.4.tgz", + "integrity": "sha512-2gqGkQC13frLy7zV8pJ4Tx77efaViaBb2cWb7hXPKgKp1/Bm4BT+xP7h0koV/rHJ0xPe9PmV3lzqcpZzt2CCPQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10458,16 +10579,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-watch": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.4.tgz", - "integrity": "sha512-RinNxoz4W1cep1b928fuFhvAQ5ag/+1UlMDV7rbyGthBIgsiEouS4kvRayvvboxii4m8eolKOIBo3OjDqbc+uQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -10840,9 +10951,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz", - "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==", + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -11292,9 +11403,9 @@ } }, "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "dev": true, "license": "MIT", "engines": { @@ -11726,13 +11837,13 @@ } }, "node_modules/rolldown": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz", - "integrity": "sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.2.tgz", + "integrity": "sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.130.0", + "@oxc-project/types": "=0.132.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -11742,27 +11853,27 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.1", - "@rolldown/binding-darwin-arm64": "1.0.1", - "@rolldown/binding-darwin-x64": "1.0.1", - "@rolldown/binding-freebsd-x64": "1.0.1", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.1", - "@rolldown/binding-linux-arm64-gnu": "1.0.1", - "@rolldown/binding-linux-arm64-musl": "1.0.1", - "@rolldown/binding-linux-ppc64-gnu": "1.0.1", - "@rolldown/binding-linux-s390x-gnu": "1.0.1", - "@rolldown/binding-linux-x64-gnu": "1.0.1", - "@rolldown/binding-linux-x64-musl": "1.0.1", - "@rolldown/binding-openharmony-arm64": "1.0.1", - "@rolldown/binding-wasm32-wasi": "1.0.1", - "@rolldown/binding-win32-arm64-msvc": "1.0.1", - "@rolldown/binding-win32-x64-msvc": "1.0.1" + "@rolldown/binding-android-arm64": "1.0.2", + "@rolldown/binding-darwin-arm64": "1.0.2", + "@rolldown/binding-darwin-x64": "1.0.2", + "@rolldown/binding-freebsd-x64": "1.0.2", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.2", + "@rolldown/binding-linux-arm64-gnu": "1.0.2", + "@rolldown/binding-linux-arm64-musl": "1.0.2", + "@rolldown/binding-linux-ppc64-gnu": "1.0.2", + "@rolldown/binding-linux-s390x-gnu": "1.0.2", + "@rolldown/binding-linux-x64-gnu": "1.0.2", + "@rolldown/binding-linux-x64-musl": "1.0.2", + "@rolldown/binding-openharmony-arm64": "1.0.2", + "@rolldown/binding-wasm32-wasi": "1.0.2", + "@rolldown/binding-win32-arm64-msvc": "1.0.2", + "@rolldown/binding-win32-x64-msvc": "1.0.2" } }, "node_modules/rolldown/node_modules/@oxc-project/types": { - "version": "0.130.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz", - "integrity": "sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==", + "version": "0.132.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.132.0.tgz", + "integrity": "sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==", "dev": true, "license": "MIT", "funding": { @@ -12508,9 +12619,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz", + "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==", "dev": true, "license": "MIT", "engines": { @@ -12780,9 +12891,9 @@ } }, "node_modules/storybook": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.0.tgz", - "integrity": "sha512-zrtctbVa6xEXCXuE3vsiR0At31zLOtzj8QudN/GaBJLZl0Z2DfF1rDPtTxdAbAp11M2J/7JVHaTIQKXauQPbmg==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.4.1.tgz", + "integrity": "sha512-V1Zd2e+gBFufqAQVZ1JR8KLqALsEZ3JYSBnWwQbKa6zCfWWanR6AFMyuOkLt2gZOgGp3h2Riuz88pGNVTQSG0A==", "dev": true, "license": "MIT", "dependencies": { @@ -12859,9 +12970,9 @@ } }, "node_modules/storybook/node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "dev": true, "license": "MIT", "engines": { @@ -12997,9 +13108,9 @@ } }, "node_modules/stylelint": { - "version": "17.11.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.11.1.tgz", - "integrity": "sha512-+smN/HqVTggUx3iuAzOi9fPh8SrH+cJWlZrYVldXoJ06orWBhZ4Ue/QEp64oei6pVrAh4w3tG+Y12Vw7MbCFRQ==", + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.12.0.tgz", + "integrity": "sha512-KIlzWXMHUvgfPUR0R7TK3H80yCIi0uoivUwf+6Az4yrHJD1Q3c1qIkh/H5Z0i/K3QXgtq/UMEkWyBUSUwnpnOg==", "dev": true, "funding": [ { @@ -13027,7 +13138,7 @@ "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.2", + "file-entry-cache": "^11.1.3", "global-modules": "^2.0.0", "globby": "^16.2.0", "globjoin": "^0.1.4", @@ -14082,16 +14193,16 @@ } }, "node_modules/vite": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.13.tgz", - "integrity": "sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==", + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.14.tgz", + "integrity": "sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.14", - "rolldown": "1.0.1", + "postcss": "^8.5.15", + "rolldown": "1.0.2", "tinyglobby": "^0.2.16" }, "bin": { @@ -14399,9 +14510,9 @@ } }, "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index bcaa6b3465..ba64f2925c 100644 --- a/package.json +++ b/package.json @@ -60,40 +60,39 @@ "lit": "^3.3.3" }, "devDependencies": { - "@biomejs/biome": "~2.4.15", + "@biomejs/biome": "~2.4.16", "@custom-elements-manifest/analyzer": "^0.11.0", "@igniteui/material-icons-extended": "^3.1.0", "@open-wc/testing": "^4.0.0", - "@storybook/addon-a11y": "^10.4.0", - "@storybook/addon-docs": "^10.4.0", - "@storybook/addon-links": "^10.4.0", - "@storybook/web-components-vite": "^10.4.0", + "@storybook/addon-a11y": "^10.4.1", + "@storybook/addon-docs": "^10.4.1", + "@storybook/addon-links": "^10.4.1", + "@storybook/web-components-vite": "^10.4.1", "@types/mocha": "^10.0.10", "@web/dev-server-esbuild": "^1.0.5", "@web/test-runner": "^0.20.2", "@web/test-runner-playwright": "^0.11.1", "autoprefixer": "^10.5.0", "cem-plugin-expanded-types": "^1.4.0", - "concurrently": "^9.2.1", + "concurrently": "^10.0.0", "custom-element-jet-brains-integration": "^1.7.0", "custom-element-vs-code-integration": "^1.5.0", - "dependency-cruiser": "^17.4.0", + "dependency-cruiser": "^17.4.2", "husky": "^9.1.7", "ig-typedoc-theme": "^7.0.1", "igniteui-i18n-resources": "^1.0.5", "igniteui-theming": "^26.0.1", - "keep-a-changelog": "^3.0.3", + "keep-a-changelog": "^3.0.4", "lint-staged": "^17.0.5", "lit-analyzer": "^2.0.3", - "node-watch": "^0.7.4", "playwright": "^1.60.0", "postcss": "^8.5.15", "prettier": "^3.8.3", "rimraf": "^6.1.3", "sass-embedded": "~1.93.3", "sinon": "^22.0.0", - "storybook": "^10.4.0", - "stylelint": "^17.11.1", + "storybook": "^10.4.1", + "stylelint": "^17.12.0", "stylelint-config-standard-scss": "^17.0.0", "stylelint-prettier": "^5.0.3", "stylelint-scss": "^7.1.1", @@ -102,10 +101,10 @@ "typedoc": "~0.28.19", "typedoc-plugin-localization": "^3.1.0", "typescript": "^6.0.3", - "vite": "^8.0.13" + "vite": "^8.0.14" }, "peerDependencies": { - "dompurify": "^3.4.5", + "dompurify": "^3.4.7", "marked": "^18.0.4", "marked-shiki": "^1.2.1", "shiki": "^4.1.0" diff --git a/scripts/build-stories.mjs b/scripts/build-stories.mjs index e14b818718..09de0b61e5 100644 --- a/scripts/build-stories.mjs +++ b/scripts/build-stories.mjs @@ -1,200 +1,190 @@ // @ts-check +/** @import { Package, Type, Reference } from 'custom-elements-manifest/schema' */ import { exec } from 'node:child_process'; -import { copyFile, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; -import { tmpdir } from 'node:os'; +import { readFile, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import { promisify } from 'node:util'; import { format } from 'prettier'; +import report from './report.mjs'; const execAsync = promisify(exec); -/** - * @typedef {object} Config - * @property {string} manifestPath - * @property {string} storiesPath - */ +/** Pre-compiled regexes */ +const NULL_UNDEFINED_RE = /undefined|null/; +const ARRAY_TYPE_RE = /\[\]/; +const GENERIC_TYPE_RE = /<.*>/; +const PRETTIFY_NAME_RE = /igc|component/gi; +const STORY_REGION_RE = /\/\/ region default.*?\/\/ endregion/gs; -/** - * @typedef {object} CEMSchema - * @property {ModuleDeclaration[]} modules - */ +/** @typedef {{ manifestPath: string, storiesPath: string }} Config */ /** - * @typedef {object} ModuleDeclaration - * @property {CustomElementDeclaration[]} declarations + * @typedef {{ + * kind: 'field', + * name: string, + * description?: string, + * privacy?: 'public' | 'private' | 'protected', + * attribute?: string, + * default?: string, + * type?: Type, + * expandedType?: Type, + * inheritedFrom?: Reference, + * static?: boolean, + * readonly?: boolean, + * deprecated?: boolean | string, + * }} ComponentField */ /** - * @typedef {object} CustomElementProperty - * @property {'field' | 'method'} kind - * @property {'private' | 'protected' | 'public'} privacy - * @property {string} name - * @property {string} description - * @property {string=} attribute - * @property {string=} default - * @property {{ text: string }=} type - * @property {{ text: string }=} expandedType - * @property {{ name: string }=} inheritedFrom - * @property {boolean=} static - * @property {boolean=} readonly - * @property {boolean=} deprecated + * @typedef {{ + * kind: 'class' | 'mixin', + * name: string, + * description?: string, + * tagName?: string, + * events?: Array<{ name: string }>, + * members?: ComponentField[], + * }} ComponentDeclaration */ /** - * @typedef {object} CustomElementDeclaration - * @property {'class' | 'mixin'} kind - * @property {string} name - * @property {string} description - * @property {string=} tagName - * @property {CustomElementProperty[]} members; - * @property {{ name: string }[]=} events; + * @typedef {{ + * type: string, + * description?: string, + * options?: string[], + * control?: string | { type: string }, + * table?: { defaultValue: { summary: string } }, + * }} ArgTypeEntry */ /** - * - * @param {object} object + * @typedef {{ + * title: string, + * component: string | undefined, + * parameters: { + * docs: { description: { component: string } }, + * actions?: { handles: string[] }, + * }, + * argTypes?: Record, + * args?: Record, + * }} StoriesDefinition */ -function isDefined(object) { - return object !== undefined; -} /** - * - * @param {string} type + * @template T + * @param {T | undefined} val + * @returns {val is T} */ -function isUnion(type) { - return type.includes('|'); +function isDefined(val) { + return val !== undefined; } /** - * * @param {string} name + * @returns {string} */ function prettifyName(name) { - return name.replace(/igc|component/gi, ''); + return name.replace(PRETTIFY_NAME_RE, ''); } class StoriesBuilder { /** @type {Config} */ #config; - /** @type {Map} */ + /** @type {Map} */ #cache = new Map(); - /** @type string */ - #tempDir; - /** - * * @param {string} parentName - * @param {string} name - * @returns {CustomElementProperty=} + * @param {string} memberName + * @returns {ComponentField | undefined} */ - #getMemberFrom(parentName, name) { + #getMemberFrom(parentName, memberName) { return this.#cache .get(parentName) - ?.members.find((member) => member.name === name); + ?.members?.find((m) => m.name === memberName); } /** + * Parses the CEM type string for a field into a normalized type string and + * optional union options in a single pass. * - * @param {CustomElementProperty} property + * @param {ComponentField} property + * @returns {{ type: string, options: string[] | undefined }} */ - #resolveType(property) { - let type = 'string'; + #parseType(property) { + let rawType = 'string'; if (property.expandedType) { - type = property.expandedType.text; + rawType = property.expandedType.text; } else if (property.type) { - type = property.type.text; + rawType = property.type.text; } else if (property.inheritedFrom) { - const parentProperty = this.#getMemberFrom( + const parent = this.#getMemberFrom( property.inheritedFrom.name, property.name ); - type = parentProperty ? this.#resolveType(parentProperty) : 'string'; + if (parent) { + return this.#parseType(parent); + } } - const result = []; + /** @type {string[]} */ + const parts = []; - const isArray = (type) => type.includes('[]'); - const isGeneric = (type) => type.match(/<.*>/); - - type.split('|').map((t) => { - const part = t.trim().replace(/'/g, '"'); + for (const raw of rawType.split('|')) { + const part = raw.trim(); if ( part && - !part.match(/undefined|null/) && - !isArray(part) && - !isGeneric(part) + !NULL_UNDEFINED_RE.test(part) && + !ARRAY_TYPE_RE.test(part) && + !GENERIC_TYPE_RE.test(part) ) { - result.push(part); + parts.push(part); } - }); + } - return result.join(' | '); - } + if (!parts.length) { + return { type: '', options: undefined }; + } - /** - * - * @param {string} type - */ - #resolveOptions(type) { - return isUnion(type) - ? type.split('|').map((t) => { - const part = t.trim(); - if (part && !part.match(/undefined|null/)) { - return part.replace(/"|'/g, ''); - } - }) - : undefined; + const type = parts.map((p) => p.replace(/'/g, '"')).join(' | '); + const options = + parts.length > 1 ? parts.map((p) => p.replace(/"|'/g, '')) : undefined; + + return { type, options }; } /** - * * @param {string} type - * @param {(string | undefined)[]=} options + * @param {string[] | undefined} options + * @returns {string | { type: string }} */ #resolveControl(type, options) { - if (type.startsWith('string')) { - return 'text'; - } - - if (type.startsWith('number')) { - return 'number'; - } - - if (type.startsWith('Date')) { - return 'date'; - } - - if (options) { + if (type.startsWith('string')) return 'text'; + if (type.startsWith('number')) return 'number'; + if (type.startsWith('Date')) return 'date'; + if (options) return { type: options.length > 3 ? 'select' : 'inline-radio' }; - } - return type; } /** - * * @param {string} type - * @param {string} value + * @param {string | undefined} value + * @returns {string | number | boolean | undefined} */ #resolveDefaultValue(type, value) { - const valueDefined = isDefined(value); - switch (type) { case 'boolean': - return valueDefined ? value === 'true' : false; + return isDefined(value) ? value === 'true' : false; case 'number': - return valueDefined ? Number.parseFloat(value) : undefined; + return isDefined(value) ? Number.parseFloat(value) : undefined; default: - return valueDefined ? value.replace(/"|'/g, '') : undefined; + return isDefined(value) ? value.replace(/"|'/g, '') : undefined; } } /** - * * @param {Config} config */ constructor(config) { @@ -202,93 +192,86 @@ class StoriesBuilder { } /** - * @returns {Promise} + * @returns {Promise} */ async #parseManifest() { const file = new URL(this.#config.manifestPath, import.meta.url); try { return JSON.parse(await readFile(file, 'utf8')); - } catch { + } catch (error) { + if ( + !( + error instanceof Error && + /** @type {NodeJS.ErrnoException} */ (error).code === 'ENOENT' + ) + ) { + throw error; + } await execAsync('npm run cem'); return JSON.parse(await readFile(file, 'utf8')); } } /** - * - * @param {ModuleDeclaration[]} modules + * @param {Package['modules']} modules */ #makeCache(modules) { - for (const { declarations } of modules) { - if (!declarations.length) { - continue; - } - - for (const candidate of declarations) { - if (candidate.kind.match(/mixin|class/)) { - this.#cache.set(candidate.name, candidate); + for (const module of modules) { + for (const candidate of module.declarations ?? []) { + if (/mixin|class/.test(candidate.kind)) { + this.#cache.set( + candidate.name, + /** @type {ComponentDeclaration} */ (candidate) + ); } } } } - async #createTmpDir() { - this.#tempDir = await mkdtemp(join(tmpdir(), 'igc-')); - } - - async #clearTmpDir() { - rm(this.#tempDir, { recursive: true, force: true }); - } - async #createDefinitions() { - await this.#createTmpDir(); - await Promise.all( + const results = await Promise.allSettled( Array.from(this.#cache.values()) .filter((element) => element.tagName) .map((element) => this.#writeStory(element.name, this.#makeDefinition(element)) ) ); + + for (const result of results) { + if (result.status === 'rejected') { + const reason = result.reason; + report.error(`Failed to write story: ${reason?.message ?? reason}`); + } + } } /** - * - * @param {CustomElementProperty[]} properties + * @param {ComponentField[]} properties + * @returns {{ args: Record, argTypes: Record }} */ #makeArgs(properties) { + /** @type {Record} */ const argTypes = {}; + /** @type {Record} */ const args = {}; for (const property of properties) { - const parsed = {}; - const type = this.#resolveType(property); - - if (type) { - parsed.type = type; - } else { - continue; - } + const { type, options } = this.#parseType(property); + if (!type) continue; - const options = this.#resolveOptions(type); const control = this.#resolveControl(type, options); - // @ts-ignore const defaultValue = this.#resolveDefaultValue(type, property.default); - if (property.description) { - parsed.description = property.description; - } - - if (options) { - parsed.options = options; - } - if (control) { - parsed.control = control; - } + /** @type {ArgTypeEntry} */ + const entry = { type }; + if (property.description) entry.description = property.description; + if (options) entry.options = options; + if (control) entry.control = control; if (isDefined(defaultValue)) { - parsed.table = { defaultValue: { summary: defaultValue?.toString() } }; + entry.table = { defaultValue: { summary: defaultValue.toString() } }; } - argTypes[property.name] = parsed; + argTypes[property.name] = entry; if (isDefined(defaultValue)) { args[property.name] = defaultValue; @@ -299,56 +282,52 @@ class StoriesBuilder { } /** - * - * @param {CustomElementDeclaration} customElement - * @returns + * @param {ComponentDeclaration} customElement + * @returns {StoriesDefinition} */ #makeDefinition(customElement) { const { description, name, events } = customElement; - const { args, argTypes } = this.#makeArgs(getMembers(customElement)); - - const actions = events - ? events.map(({ name }) => name).filter(Boolean) - : undefined; + const { args, argTypes } = this.#makeArgs(this.#getMembers(customElement)); + const actions = events?.map(({ name }) => name).filter(Boolean); + /** @type {StoriesDefinition} */ const result = { title: prettifyName(name), component: customElement.tagName, parameters: { - docs: { description: { component: description } }, + docs: { description: { component: description ?? '' } }, }, }; - if (actions?.length) { - result.parameters.actions = { handles: actions }; - } - if (Object.keys(argTypes).length) { - result.argTypes = argTypes; - } - if (Object.keys(args).length) { - result.args = args; - } + if (actions?.length) result.parameters.actions = { handles: actions }; + if (Object.keys(argTypes).length) result.argTypes = argTypes; + if (Object.keys(args).length) result.args = args; return result; } /** - * * @param {string} component + * @returns {URL} */ #getFilePath(component) { const name = `${component.replace(/igc-|component/gi, '')}.stories.ts`; return new URL(join(this.#config.storiesPath, name), import.meta.url); } + /** + * @param {string} name + * @param {StoriesDefinition} definition + * @returns {Promise} + */ async #writeStory(name, definition) { - const file = this.#getFilePath(definition.component); - const tmpFile = join(this.#tempDir, `${name}.ts`); + const file = this.#getFilePath(definition.component ?? ''); let data = ''; try { data = await readFile(file, 'utf8'); } catch { + report.warn(`No story file found for ${name}, skipping.`); return; } @@ -359,29 +338,39 @@ class StoriesBuilder { }) ).trim(); - await writeFile( - tmpFile, - data.replace(/\/\/ region default.*\/\/ endregion/gs, storyMeta), - { - encoding: 'utf8', - flush: true, - } - ); + const newContent = data.replace(STORY_REGION_RE, storyMeta); - await copyFile(tmpFile, file); + if (newContent !== data) { + await writeFile(file, newContent, { encoding: 'utf8', flush: true }); + } } async build() { const { modules } = await this.#parseManifest(); this.#makeCache(modules); await this.#createDefinitions(); - await this.#clearTmpDir(); + } + + /** + * @param {ComponentDeclaration} element + * @returns {ComponentField[]} + */ + #getMembers(element) { + return /** @type {ComponentField[]} */ (element.members ?? []).filter( + (member) => + member.privacy === 'public' && + member.kind === 'field' && + member.attribute && + !member.static && + !member.readonly && + !member.deprecated + ); } } /** - * * @param {string} description + * @returns {string} */ function makeComment(description) { if (!description) return ''; @@ -391,18 +380,28 @@ function makeComment(description) { : `/** ${description} */\n`; } +/** + * @param {Array<[string, ArgTypeEntry]>} types + * @returns {string} + */ function buildInterface(types) { return types .map( ([name, { description, type }]) => - `${makeComment(description)}${name}: ${type};` + `${makeComment(description ?? '')}${name}: ${type};` ) .join('\n'); } +/** + * @param {StoriesDefinition} definition + * @returns {string} + */ function templateArgsInterface(definition) { const argsInterface = `Igc${definition.title.replace(/\s/g, '')}Args`; - const types = Array.from(Object.entries(definition.argTypes ?? {})); + const types = /** @type {Array<[string, ArgTypeEntry]>} */ ( + Object.entries(definition.argTypes ?? {}) + ); return types.length ? `interface ${argsInterface} { @@ -412,6 +411,11 @@ function templateArgsInterface(definition) { : 'type Story = StoryObj'; } +/** + * @param {string} name + * @param {StoriesDefinition} definition + * @returns {string} + */ function template(name, definition) { return String.raw` // region default @@ -425,23 +429,14 @@ ${templateArgsInterface(definition)} // endregion`; } -/** - * - * @param {CustomElementDeclaration} element - */ -function getMembers(element) { - return element.members.filter( - (member) => - member.privacy === 'public' && - member.kind === 'field' && - member.attribute && - !member.static && - !member.readonly && - !member.deprecated - ); -} - new StoriesBuilder({ manifestPath: '../custom-elements.json', storiesPath: '../stories/', -}).build(); +}) + .build() + .catch((error) => { + report.error( + `Stories build failed: ${error instanceof Error ? error.message : error}` + ); + process.exit(1); + }); diff --git a/scripts/build-styles.mjs b/scripts/build-styles.mjs index b1af8cf39d..218e313905 100644 --- a/scripts/build-styles.mjs +++ b/scripts/build-styles.mjs @@ -1,3 +1,3 @@ -import { buildComponents, buildThemes } from './sass.mjs'; +import { buildAll } from './sass.mjs'; -await Promise.all([buildThemes(), buildComponents()]); +await buildAll(); diff --git a/scripts/build.mjs b/scripts/build.mjs index 05c82df523..6c9826eb1b 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -10,7 +10,7 @@ import { } from 'custom-element-vs-code-integration'; import customElements from '../custom-elements.json' with { type: 'json' }; import report from './report.mjs'; -import { buildComponents, buildThemes } from './sass.mjs'; +import { buildAll } from './sass.mjs'; const exec = promisify(_exec); @@ -52,9 +52,7 @@ async function runTask(tag, cmd) { (async () => { await runTask('Clean up', () => exec('npm run clean')); - await runTask('Styles', () => - Promise.all([buildComponents(true), buildThemes(true)]) - ); + await runTask('Styles', () => buildAll(true)); // https://github.com/microsoft/TypeScript/issues/14619 await runTask('Components', () => diff --git a/scripts/sass.mjs b/scripts/sass.mjs index b461133446..96253605d6 100644 --- a/scripts/sass.mjs +++ b/scripts/sass.mjs @@ -11,18 +11,20 @@ const toDist = path.join.bind( path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../dist') ); -const stripComments = () => { - return { - postcssPlugin: 'postcss-strip-comments', - OnceExit(root) { - root.walkComments((node) => node.remove()); - }, - }; -}; +const stripComments = () => ({ + postcssPlugin: 'postcss-strip-comments', + OnceExit(root) { + root.walkComments((node) => node.remove()); + }, +}); stripComments.postcss = true; const _postProcessor = postcss([autoprefixer, stripComments]); +const THEME_GLOB = 'src/styles/themes/{light,dark}/*.scss'; +const COMPONENT_GLOB = + 'src/components/**/*.{base,common,shared,material,bootstrap,indigo,fluent}.scss'; + export function fromTemplate(content) { return ` import { css } from 'lit'; @@ -40,12 +42,82 @@ export async function compileSass(src, compiler) { return out.charCodeAt(0) === 0xfeff ? out.slice(1) : out; } +/** + * Builds both themes and component styles using a single shared compiler. + * All I/O (compiler init + both globs) is parallelized. + * + * @param {boolean} isProduction + */ +export async function buildAll(isProduction = false) { + const start = performance.now(); + + const [compiler, themePaths, componentPaths] = await Promise.all([ + sass.initAsyncCompiler(), + Array.fromAsync(glob(THEME_GLOB)), + Array.fromAsync(glob(COMPONENT_GLOB)), + ]); + + // Cache mkdir promises per directory to avoid redundant syscalls. + /** @type {Map>} */ + const mkdirCache = new Map(); + const ensureDir = (dir) => { + if (!mkdirCache.has(dir)) { + mkdirCache.set(dir, mkdir(dir, { recursive: true })); + } + return /** @type {Promise} */ (mkdirCache.get(dir)); + }; + + try { + await Promise.all([ + ...themePaths.map(async (sassFile) => { + if (isProduction) { + const outputFile = toDist( + sassFile.replace(/\.scss$/, '.css').replace('src/styles/', '') + ); + await ensureDir(path.dirname(outputFile)); + await writeFile( + outputFile, + await compileSass(sassFile, compiler), + 'utf-8' + ); + } else { + await writeFile( + sassFile.replace(/\.scss$/, '.css.ts'), + fromTemplate(await compileSass(sassFile, compiler)), + 'utf-8' + ); + } + }), + ...componentPaths.map((filePath) => + compileSass(filePath, compiler).then((css) => + writeFile( + filePath.replace(/\.scss$/, '.css.ts'), + fromTemplate(css), + 'utf-8' + ) + ) + ), + ]); + } catch (err) { + report.error(err.message ?? err.toString()); + process.exit(1); + } finally { + await compiler.dispose(); + } + + if (!isProduction) { + report.success( + `Styles generated in ${((performance.now() - start) / 1000).toFixed(2)}s` + ); + } +} + export async function buildThemes(isProduction = false) { const start = performance.now(); const [compiler, paths] = await Promise.all([ sass.initAsyncCompiler(), - Array.fromAsync(glob('src/styles/themes/{light,dark}/*.scss')), + Array.fromAsync(glob(THEME_GLOB)), ]); try { @@ -74,13 +146,12 @@ export async function buildThemes(isProduction = false) { }) ); } catch (err) { - await compiler.dispose(); report.error(err.message ?? err.toString()); process.exit(1); + } finally { + await compiler.dispose(); } - await compiler.dispose(); - if (!isProduction) { report.success( `Themes generated in ${((performance.now() - start) / 1000).toFixed(2)}s` @@ -92,31 +163,28 @@ export async function buildComponents(isProduction = false) { const start = performance.now(); const [compiler, paths] = await Promise.all([ sass.initAsyncCompiler(), - Array.fromAsync( - glob( - 'src/components/**/*.{base,common,shared,material,bootstrap,indigo,fluent}.scss' - ) - ), + Array.fromAsync(glob(COMPONENT_GLOB)), ]); try { await Promise.all( - paths.map(async (filePath) => - writeFile( - filePath.replace(/\.scss$/, '.css.ts'), - fromTemplate(await compileSass(filePath, compiler)), - 'utf-8' + paths.map((filePath) => + compileSass(filePath, compiler).then((css) => + writeFile( + filePath.replace(/\.scss$/, '.css.ts'), + fromTemplate(css), + 'utf-8' + ) ) ) ); } catch (err) { - await compiler.dispose(); report.error(err.message ?? err.toString()); process.exit(1); + } finally { + await compiler.dispose(); } - await compiler.dispose(); - if (!isProduction) { report.success( `Component styles generated in ${((performance.now() - start) / 1000).toFixed(2)}s` diff --git a/scripts/stories-watcher.js b/scripts/stories-watcher.js index 86254a193b..96a58e64a8 100644 --- a/scripts/stories-watcher.js +++ b/scripts/stories-watcher.js @@ -1,40 +1,28 @@ import { exec as _exec } from 'node:child_process'; import { promisify } from 'node:util'; -import watch from 'node-watch'; +import { watch } from 'node:fs'; import report from './report.mjs'; const exec = promisify(_exec); - -const watchOptions = { - recursive: true, - filter: (path) => { - return /^((?!\.spec|.css\.).)*\.ts$/.test(path); - }, -}; - -watch(['src'], watchOptions, (_, fileName) => { - addToQueue(fileName); -}); +const now = () => `[${new Date().toLocaleTimeString()}]`; let updating = false; -async function addToQueue(fileName) { +watch('custom-elements.json', async () => { if (updating) { return; } - report.info(`Component change detected: ${fileName}`); updating = true; - report.info('Building documentation metadata and updating stories...'); - - const buildDocsPromise = exec('npm run build:meta'); + report.info(`${now()} Manifest updated, rebuilding stories...`); try { - await buildDocsPromise; - updating = false; - report.info('Metadata build completed. Stories updated.'); + await exec('npm run build:meta'); + report.info(`${now()} Stories updated.`); } catch (e) { - report.error('ERROR:', e.message); + report.error(`${now()} ERROR: ${e.message}`); + } finally { + updating = false; } -} +}); -report.info('Metadata watcher started...'); +report.info(`${now()} Metadata watcher started...`); diff --git a/scripts/styles-watcher.mjs b/scripts/styles-watcher.mjs index 2fefd5a1a9..f8e251456b 100644 --- a/scripts/styles-watcher.mjs +++ b/scripts/styles-watcher.mjs @@ -1,41 +1,34 @@ +import { watch } from 'node:fs'; +import { join } from 'node:path'; import { writeFile } from 'node:fs/promises'; -import watch from 'node-watch'; import * as sass from 'sass-embedded'; import report from './report.mjs'; import { compileSass, fromTemplate } from './sass.mjs'; -const watchOptions = { - recursive: true, - filter: (path) => { - return /.(?:scss)$/.test(path); - }, -}; - let updating = false; const compiler = await sass.initAsyncCompiler(); +const filter = (path) => /.(?:scss)$/.test(path); +const now = () => `[${new Date().toLocaleTimeString()}]`; -const watcher = watch(['src'], watchOptions, async (_, fileName) => { - if (updating) { - return; - } +watch('src', { recursive: true }, async (_, fileName) => { + if (!fileName || !filter(fileName) || updating) return; - report.warn(`Change detected: ${fileName}`); + const filePath = join('src', fileName); + report.warn(`${now()} 🎨 change detected: ${filePath}`); updating = true; try { await writeFile( - fileName.replace(/\.scss$/, '.css.ts'), - fromTemplate(await compileSass(fileName, compiler)), + filePath.replace(/\.scss$/, '.css.ts'), + fromTemplate(await compileSass(filePath, compiler)), 'utf8' ); + report.success(`${now()} 🎨 Styles rebuilt`); } catch (err) { - report.error(err.message ?? err.toString()); + report.error(`${now()} ERROR: ${err.message ?? err.toString()}`); + } finally { + updating = false; } +}).on('close', () => compiler.dispose()); - report.success('Styles rebuilt 🎨'); - updating = false; -}); - -watcher.on('close', () => compiler.dispose()); - -report.info('Styles watcher started...'); +report.info(`${now()} Styles watcher started...`); diff --git a/stories/date-time-input.stories.ts b/stories/date-time-input.stories.ts index b770c25dcf..5c2f30daa7 100644 --- a/stories/date-time-input.stories.ts +++ b/stories/date-time-input.stories.ts @@ -27,44 +27,10 @@ const metadata: Meta = { }, argTypes: { value: { - type: 'string | Date', - description: 'The value of the input.', - options: ['string', 'Date'], - control: 'text', - }, - min: { type: 'Date', - description: 'The minimum value required for the input to remain valid.', - control: 'date', - }, - max: { - type: 'Date', - description: 'The maximum value required for the input to remain valid.', + description: 'The value of the input.', control: 'date', }, - inputFormat: { - type: 'string', - description: 'The date format to apply on the input.', - control: 'text', - }, - displayFormat: { - type: 'string', - description: - 'Format to display the value in when not editing.\nDefaults to the locale format if not set.', - control: 'text', - }, - spinLoop: { - type: 'boolean', - description: 'Sets whether to loop over the currently spun segment.', - control: 'boolean', - table: { defaultValue: { summary: 'true' } }, - }, - locale: { - type: 'string', - description: - 'Gets/Sets the locale used for formatting the display value.', - control: 'text', - }, readOnly: { type: 'boolean', description: 'Makes the control a readonly field.', @@ -73,9 +39,8 @@ const metadata: Meta = { }, mask: { type: 'string', - description: 'The masked pattern of the component.', + description: 'The mask pattern of the component.', control: 'text', - table: { defaultValue: { summary: 'CCCCCCCCCC' } }, }, prompt: { type: 'string', @@ -124,16 +89,48 @@ const metadata: Meta = { description: 'The label for the control.', control: 'text', }, + inputFormat: { + type: 'string', + description: 'The date format to apply on the input.', + control: 'text', + }, + min: { + type: 'Date', + description: 'The minimum value required for the input to remain valid.', + control: 'date', + }, + max: { + type: 'Date', + description: 'The maximum value required for the input to remain valid.', + control: 'date', + }, + displayFormat: { + type: 'string', + description: + 'Format to display the value in when not editing.\nDefaults to the locale format if not set.', + control: 'text', + }, + spinLoop: { + type: 'boolean', + description: 'Sets whether to loop over the currently spun segment.', + control: 'boolean', + table: { defaultValue: { summary: 'true' } }, + }, + locale: { + type: 'string', + description: + 'Gets/Sets the locale used for formatting the display value.', + control: 'text', + }, }, args: { - spinLoop: true, readOnly: false, - mask: 'CCCCCCCCCC', prompt: '_', required: false, disabled: false, invalid: false, outlined: false, + spinLoop: true, }, }; @@ -141,25 +138,10 @@ export default metadata; interface IgcDateTimeInputArgs { /** The value of the input. */ - value: string | Date; - /** The minimum value required for the input to remain valid. */ - min: Date; - /** The maximum value required for the input to remain valid. */ - max: Date; - /** The date format to apply on the input. */ - inputFormat: string; - /** - * Format to display the value in when not editing. - * Defaults to the locale format if not set. - */ - displayFormat: string; - /** Sets whether to loop over the currently spun segment. */ - spinLoop: boolean; - /** Gets/Sets the locale used for formatting the display value. */ - locale: string; + value: Date; /** Makes the control a readonly field. */ readOnly: boolean; - /** The masked pattern of the component. */ + /** The mask pattern of the component. */ mask: string; /** The prompt symbol to use for unfilled parts of the mask pattern. */ prompt: string; @@ -177,6 +159,21 @@ interface IgcDateTimeInputArgs { placeholder: string; /** The label for the control. */ label: string; + /** The date format to apply on the input. */ + inputFormat: string; + /** The minimum value required for the input to remain valid. */ + min: Date; + /** The maximum value required for the input to remain valid. */ + max: Date; + /** + * Format to display the value in when not editing. + * Defaults to the locale format if not set. + */ + displayFormat: string; + /** Sets whether to loop over the currently spun segment. */ + spinLoop: boolean; + /** Gets/Sets the locale used for formatting the display value. */ + locale: string; } type Story = StoryObj; From e54e13baa62a294eb275d0ce6fb5d8dd2a06ff2a Mon Sep 17 00:00:00 2001 From: Radoslav Karaivanov Date: Thu, 28 May 2026 20:20:23 +0300 Subject: [PATCH 2/2] fix: Addressed PR feedback on build scripts and stories watcher --- scripts/build-styles.mjs | 6 +++++- scripts/sass.mjs | 9 --------- scripts/stories-watcher.js | 9 +++++++-- scripts/styles-watcher.mjs | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/build-styles.mjs b/scripts/build-styles.mjs index 218e313905..db16052a28 100644 --- a/scripts/build-styles.mjs +++ b/scripts/build-styles.mjs @@ -1,3 +1,7 @@ import { buildAll } from './sass.mjs'; +import report from './report.mjs'; -await buildAll(); +await buildAll().catch((err) => { + report.error(err.message ?? err.toString()); + process.exit(1); +}); diff --git a/scripts/sass.mjs b/scripts/sass.mjs index 96253605d6..2f364620a2 100644 --- a/scripts/sass.mjs +++ b/scripts/sass.mjs @@ -98,9 +98,6 @@ export async function buildAll(isProduction = false) { ) ), ]); - } catch (err) { - report.error(err.message ?? err.toString()); - process.exit(1); } finally { await compiler.dispose(); } @@ -145,9 +142,6 @@ export async function buildThemes(isProduction = false) { } }) ); - } catch (err) { - report.error(err.message ?? err.toString()); - process.exit(1); } finally { await compiler.dispose(); } @@ -178,9 +172,6 @@ export async function buildComponents(isProduction = false) { ) ) ); - } catch (err) { - report.error(err.message ?? err.toString()); - process.exit(1); } finally { await compiler.dispose(); } diff --git a/scripts/stories-watcher.js b/scripts/stories-watcher.js index 96a58e64a8..beb88e43dd 100644 --- a/scripts/stories-watcher.js +++ b/scripts/stories-watcher.js @@ -8,7 +8,12 @@ const now = () => `[${new Date().toLocaleTimeString()}]`; let updating = false; -watch('custom-elements.json', async () => { +watch('.', (_, filename) => { + if (filename !== 'custom-elements.json') return; + trigger(); +}); + +async function trigger() { if (updating) { return; } @@ -23,6 +28,6 @@ watch('custom-elements.json', async () => { } finally { updating = false; } -}); +} report.info(`${now()} Metadata watcher started...`); diff --git a/scripts/styles-watcher.mjs b/scripts/styles-watcher.mjs index f8e251456b..be25d6ebfd 100644 --- a/scripts/styles-watcher.mjs +++ b/scripts/styles-watcher.mjs @@ -7,7 +7,7 @@ import { compileSass, fromTemplate } from './sass.mjs'; let updating = false; const compiler = await sass.initAsyncCompiler(); -const filter = (path) => /.(?:scss)$/.test(path); +const filter = (fileName) => /\.scss$/.test(fileName); const now = () => `[${new Date().toLocaleTimeString()}]`; watch('src', { recursive: true }, async (_, fileName) => {