diff --git a/CHANGELOG.md b/CHANGELOG.md index 025eac9323..e69e1f177c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -318,6 +318,7 @@ Notes: web developers are advised to use [`~` (tilde range)](https://github.com/ - Fixed Composer props types not resolving correctly in React 16 in PR [#5580](https://github.com/microsoft/BotFramework-WebChat/pull/5580), by [@lexi-taylor](https://github.com/lexi-taylor) - Fixed `npm start` may fail subsequently as builds are not fully flushed to `/dist/`, in PR [#5599](https://github.com/microsoft/BotFramework-WebChat/pull/5599), by [@compulim](https://github.com/compulim) +- Fixed published package types containing internal package references, in PR [#5610](https://github.com/microsoft/BotFramework-WebChat/pull/5610), by [@OEvgeny](https://github.com/OEvgeny) ### Removed diff --git a/package-lock.json b/package-lock.json index 5779cc2cf3..dee9274e47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,6 +71,7 @@ "cross-env": "^10.0.0", "diff": "^8.0.2", "dotenv": "^17.2.1", + "dtsroll": "^1.4.1", "eslint": "^8.57.1", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", @@ -3332,6 +3333,67 @@ "version": "1.2.1", "license": "MIT" }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.2.tgz", + "integrity": "sha512-tCtHJ2BlhSoK4cCs25NMXfV7EALKr0jyasmqVCq3y9cBrKdmJhtsy1iTz36Xhk/O+pDJbzawxF4K6ZblqCnITQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.46.2", "cpu": [ @@ -3818,6 +3880,13 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/scheduler": { "version": "0.16.8", "license": "MIT" @@ -5442,6 +5511,24 @@ "dev": true, "license": "MIT" }, + "node_modules/byte-size": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-9.0.1.tgz", + "integrity": "sha512-YLe9x3rabBrcI0cueCdLS2l5ONUKywcRpTs02B8KP9/Cimhj7o3ZccGrPnRvcbyHMbb7W79/3MUJl7iGgTXKEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + }, + "peerDependencies": { + "@75lb/nature": "latest" + }, + "peerDependenciesMeta": { + "@75lb/nature": { + "optional": true + } + } + }, "node_modules/bytes": { "version": "3.1.2", "dev": true, @@ -5835,6 +5922,20 @@ "node_modules/cldrjs": { "version": "0.5.5" }, + "node_modules/cleye": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/cleye/-/cleye-1.3.4.tgz", + "integrity": "sha512-Rd6M8ecBDtdYdPR22h6gG37lPqqJ3hSOaplaGwuGYey9xKmEElOvTgupqfyLSlISshroRpVhYjDtW3vwNUNBaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "terminal-columns": "^1.4.1", + "type-flag": "^3.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/cleye?sponsor=1" + } + }, "node_modules/cli-boxes": { "version": "3.0.0", "dev": true, @@ -6796,6 +6897,38 @@ "url": "https://dotenvx.com" } }, + "node_modules/dtsroll": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dtsroll/-/dtsroll-1.4.1.tgz", + "integrity": "sha512-Ih6dWLx/6DGpPMIODGzaeGYYW/L/A4bAk0/5j+XPKYQ9D2vHKyDZt86GaKCAjd2uhLDwHrr4HwGzoBzdl0EQ2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/plugin-node-resolve": "^16.0.0", + "byte-size": "^9.0.1", + "cleye": "^1.3.2", + "rollup": "^4.29.1", + "rollup-plugin-dts": "6.1.1" + }, + "bin": { + "dtsroll": "dist/cli.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/privatenumber/dtsroll?sponsor=1" + }, + "peerDependencies": { + "typescript": "^4.5 || ^5.0", + "vite": "5 || 6" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "dev": true, @@ -7932,6 +8065,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "dev": true, @@ -9672,6 +9812,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" + }, "node_modules/is-negative-zero": { "version": "2.0.3", "dev": true, @@ -15178,6 +15325,29 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-dts": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.1.tgz", + "integrity": "sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==", + "dev": true, + "license": "LGPL-3.0-only", + "dependencies": { + "magic-string": "^0.30.10" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.24.2" + }, + "peerDependencies": { + "rollup": "^3.29.4 || ^4", + "typescript": "^4.5 || ^5.0" + } + }, "node_modules/router": { "version": "2.2.0", "dev": true, @@ -16584,6 +16754,16 @@ "node": ">=6" } }, + "node_modules/terminal-columns": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terminal-columns/-/terminal-columns-1.4.1.tgz", + "integrity": "sha512-IKVL/itiMy947XWVv4IHV7a0KQXvKjj4ptbi7Ew9MPMcOLzkiQeyx3Gyvh62hKrfJ0RZc4M1nbhzjNM39Kyujw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/terminal-columns?sponsor=1" + } + }, "node_modules/terser": { "version": "5.39.0", "dev": true, @@ -17151,6 +17331,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/type-flag/-/type-flag-3.0.0.tgz", + "integrity": "sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/type-flag?sponsor=1" + } + }, "node_modules/type-is": { "version": "2.0.1", "dev": true, @@ -18428,7 +18618,6 @@ "@types/dom-speech-recognition": "^0.0.6", "@types/jest": "^30.0.0", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "core-js": "^3.44.0", @@ -18440,6 +18629,7 @@ "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6", "react-dom": ">= 16.8.6" } @@ -18450,7 +18640,6 @@ "license": "MIT", "dependencies": { "handler-chain": "^0.1.0", - "react-chain-of-responsibility": "0.4.0-main.c2f17da", "react-wrap-with": "0.1.0", "valibot": "1.1.0" }, @@ -18465,7 +18654,8 @@ "typescript": "^5.7.3" }, "peerDependencies": { - "react": ">= 16.8.6" + "react": ">= 16.8.6", + "react-chain-of-responsibility": "0.4.0-main.c2f17da" } }, "packages/api-middleware/node_modules/@types/node": { @@ -18887,7 +19077,6 @@ "@types/dom-speech-recognition": "^0.0.6", "@types/mdast": "^4.0.4", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "@types/uuid": "^10.0.0", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", @@ -18900,7 +19089,9 @@ "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6", + "react-chain-of-responsibility": "0.4.0-main.c2f17da", "react-dom": ">= 16.8.6" } }, @@ -19049,7 +19240,6 @@ "@types/jest": "^30.0.0", "@types/mdast": "^4.0.4", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "core-js": "^3.44.0", @@ -19058,6 +19248,7 @@ "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6", "react-dom": ">= 16.8.6" } @@ -19750,11 +19941,11 @@ "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", "@types/math-random": "^1.0.2", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6" } }, @@ -19806,18 +19997,16 @@ "name": "@msinternal/botframework-webchat-react-valibot", "version": "0.0.0-0", "license": "MIT", - "dependencies": { - "valibot": "1.1.0" - }, "devDependencies": { "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", "@types/jest": "^30.0.0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, "peerDependencies": { - "react": ">= 16.8.6" + "@types/react": "^16.14.65", + "react": ">= 16.8.6", + "valibot": "1.1.0" } }, "packages/react-valibot/node_modules/@jest/expect-utils": { @@ -20090,11 +20279,11 @@ "devDependencies": { "@msinternal/botframework-webchat-react-valibot": "^0.0.0-0", "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6" } }, diff --git a/package.json b/package.json index a613de1ff7..738013a548 100644 --- a/package.json +++ b/package.json @@ -233,6 +233,7 @@ "cross-env": "^10.0.0", "diff": "^8.0.2", "dotenv": "^17.2.1", + "dtsroll": "^1.4.1", "eslint": "^8.57.1", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", diff --git a/packages/api-middleware/legacy.js b/packages/api-middleware/legacy.js deleted file mode 100644 index 838d60e936..0000000000 --- a/packages/api-middleware/legacy.js +++ /dev/null @@ -1,3 +0,0 @@ -// This is required for Webpack 4 which does not support named exports. -// eslint-disable-next-line no-undef -module.exports = require('./dist/botframework-webchat-api-middleware.legacy.js'); diff --git a/packages/api-middleware/package.json b/packages/api-middleware/package.json index 1754e7ea57..3dd420c571 100644 --- a/packages/api-middleware/package.json +++ b/packages/api-middleware/package.json @@ -85,11 +85,11 @@ "typescript": "^5.7.3" }, "peerDependencies": { + "react-chain-of-responsibility": "0.4.0-main.c2f17da", "react": ">= 16.8.6" }, "dependencies": { "handler-chain": "^0.1.0", - "react-chain-of-responsibility": "0.4.0-main.c2f17da", "react-wrap-with": "0.1.0", "valibot": "1.1.0" } diff --git a/packages/api/package.json b/packages/api/package.json index 633d4a8ad2..603c173d60 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -75,9 +75,12 @@ ], "homepage": "https://github.com/microsoft/BotFramework-WebChat/tree/main/packages/component#readme", "scripts": { - "build": "npm run build:globalize && npm run build:tsup", + "build": "npm run build:globalize && npm run build:tsup && npm run build:dtsroll && npm run build:validate", "build:globalize": "node scripts/createPrecompiledGlobalize.mjs", "build:tsup": "tsup", + "build:dtsroll": "dtsroll ./dist/*.d.*", + "build:validate": "npm run build:validate:dts", + "build:validate:dts": "if grep -q -P '@msinternal\\/' dist/*.d.* 2>/dev/null; then echo \"Error: dist/*.d.* is not compiled by dtsroll\" >&2; exit 1; fi", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -128,7 +131,6 @@ "@types/dom-speech-recognition": "^0.0.6", "@types/jest": "^30.0.0", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "core-js": "^3.44.0", @@ -153,6 +155,7 @@ "valibot": "1.1.0" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6", "react-dom": ">= 16.8.6" } diff --git a/packages/base/utils.js b/packages/base/utils.js deleted file mode 100644 index 534ba435dd..0000000000 --- a/packages/base/utils.js +++ /dev/null @@ -1,3 +0,0 @@ -// This is required for Webpack 4 which does not support named exports. -// eslint-disable-next-line no-undef -module.exports = require('./dist/botframework-webchat-base.utils.js'); diff --git a/packages/bundle/package.json b/packages/bundle/package.json index b8ede8bd6a..e155d31ac3 100644 --- a/packages/bundle/package.json +++ b/packages/bundle/package.json @@ -90,6 +90,7 @@ "allowSyntheticDefaultImports": true, "downlevelIteration": true, "jsx": "react", + "module": "NodeNext", "noImplicitAny": false, "resolveJsonModule": true, "skipLibCheck": true, @@ -97,9 +98,12 @@ } }, "scripts": { - "build": "npm run build:static && npm run build:tsup", + "build": "npm run build:static && npm run build:tsup && npm run build:dtsroll && npm run build:validate", "build:static": "node ./esbuild.static.mjs", "build:tsup": "tsup", + "build:dtsroll": "dtsroll ./dist/*.d.*", + "build:validate": "npm run build:validate:dts", + "build:validate:dts": "if grep -q -P '@msinternal\\/' dist/*.d.* 2>/dev/null; then echo \"Error: dist/*.d.* is not compiled by dtsroll\" >&2; exit 1; fi", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -223,7 +227,6 @@ "@types/dom-speech-recognition": "^0.0.6", "@types/mdast": "^4.0.4", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "@types/uuid": "^10.0.0", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", @@ -236,6 +239,8 @@ "typescript": "~5.8.3" }, "peerDependencies": { + "@types/react": "^16.14.65", + "react-chain-of-responsibility": "0.4.0-main.c2f17da", "react": ">= 16.8.6", "react-dom": ">= 16.8.6" } diff --git a/packages/component/package.json b/packages/component/package.json index 725cb81dae..627b00782b 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -75,9 +75,12 @@ ], "homepage": "https://github.com/microsoft/BotFramework-WebChat/tree/main/packages/component#readme", "scripts": { - "build": "npm run build:tsup && npm run build:validate", + "build": "npm run build:tsup && npm run build:dtsroll && npm run build:validate", "build:tsup": "tsup", - "build:validate": "grep -q -P '\\.webchat \\.w([a-zA-Z-]){6}_' dist/*.css 2>/dev/null || { echo \"Error: dist/*.css is not compiled by Lightning CSS\" >&2; exit 1; }", + "build:dtsroll": "dtsroll ./dist/*.d.*", + "build:validate": "npm run build:validate:css && npm run build:validate:dts", + "build:validate:css": "grep -q -P '\\.webchat \\.w([a-zA-Z-]){6}_' dist/*.css 2>/dev/null || { echo \"Error: dist/*.css is not compiled by Lightning CSS\" >&2; exit 1; }", + "build:validate:dts": "if grep -q -P '@msinternal\\/' dist/*.d.* 2>/dev/null; then echo \"Error: dist/*.d.* is not compiled by dtsroll\" >&2; exit 1; fi", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -136,7 +139,6 @@ "@types/jest": "^30.0.0", "@types/mdast": "^4.0.4", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-transform-inline-environment-variables": "^0.4.4", "core-js": "^3.44.0", @@ -175,6 +177,7 @@ "valibot": "1.1.0" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6", "react-dom": ">= 16.8.6" } diff --git a/packages/component/src/Utils/createIconComponent.tsx b/packages/component/src/Utils/createIconComponent.tsx index a6b054edd8..6410f0f6a7 100644 --- a/packages/component/src/Utils/createIconComponent.tsx +++ b/packages/component/src/Utils/createIconComponent.tsx @@ -1,9 +1,21 @@ import { useStyles } from '@msinternal/botframework-webchat-styles/react'; import { validateProps } from '@msinternal/botframework-webchat-react-valibot'; import cx from 'classnames'; -import { object, optional, picklist, pipe, readonly, type OptionalSchema, type PicklistSchema } from 'valibot'; +import { + object, + optional, + picklist, + pipe, + readonly, + type BaseIssue, + type BaseSchema, + type OptionalSchema, + type PicklistSchema +} from 'valibot'; import React, { type ComponentType } from 'react'; +type CSSModuleClasses = { readonly [key: string]: any }; + type Prefixes = T extends `${infer P}--${string}` ? P : never; type SuffixesOf = T extends `${Prefix}--${infer S}` ? S : never; @@ -12,46 +24,86 @@ type ModifierMap = { [P in Prefixes]?: SuffixesOf; }; -type SafeModifierList = keyof ModifierMap extends never +type SafeModifierList = keyof ModifierMap extends never ? string - : keyof ModifierMap; + : keyof ModifierMap; -function createPropsSchema< - const TCSSModfuleClasses extends CSSModuleClasses, - const TModifiers extends SafeModifierList ->(styles: TCSSModfuleClasses, modifiers: TModifiers[]) { - type CSSModuleModifiers = ModifierMap; +type ModifierSchemaEntry = OptionalSchema, undefined>; +export type IconModifierPropsSchema = BaseSchema< + Partial>, + Readonly>>, + BaseIssue +> & { + readonly entries: Partial>; +}; + +function createPropsSchema< + const TCSSModuleClasses extends CSSModuleClasses, + const TModifiers extends SafeModifierList +>(styles: TCSSModuleClasses, modifiers: TModifiers[]): IconModifierPropsSchema { const props = Object.keys(styles).reduce((acc, key) => { - const [base, modifier] = key.split('--') as [keyof CSSModuleModifiers, string | undefined]; - if (modifier && modifiers.includes(base as unknown as TModifiers)) { - acc.has(base) || acc.set(base, new Set()); - acc.get(base).add(modifier); + const [rawBase, modifier] = key.split('--') as [string, string | undefined]; + + if (!modifier) { + return acc; } + + const base = rawBase as TModifiers; + + if (!modifiers.includes(base)) { + return acc; + } + + let modifierSet = acc.get(base); + + if (!modifierSet) { + modifierSet = new Set(); + acc.set(base, modifierSet); + } + + modifierSet.add(modifier); + return acc; - }, new Map>()); - - return pipe( - object( - Object.fromEntries( - Array.from(props.entries()).map(([base, modifiers]) => [base, optional(picklist(Array.from(modifiers)))]) - ) as unknown as { - [key in TModifiers]: OptionalSchema< - PicklistSchema, undefined>, - undefined - >; + }, new Map>()); + + const schemaEntries = Array.from(props.entries()).reduce>>( + (acc, [base, modifierSet]) => { + const values = Array.from(modifierSet); + + if (values.length) { + // eslint-disable-next-line security/detect-object-injection + acc[base] = optional(picklist(values as unknown as readonly [string, ...string[]])) as ModifierSchemaEntry; } - ), - readonly() + + return acc; + }, + {} ); + + const schema = object(schemaEntries as Partial>); + + return pipe(schema, readonly()) as IconModifierPropsSchema; } export default function createIconComponent< const TProps extends { className?: string | undefined }, - const TModifiers extends SafeModifierList, - const TCSSModfuleClasses extends CSSModuleClasses ->(styles: TCSSModfuleClasses, modifiers: TModifiers[], BaseIcon: ComponentType) { - type CSSModuleModifiers = ModifierMap; + const TModifiers extends SafeModifierList, + const TCSSModuleClasses extends CSSModuleClasses +>( + styles: TCSSModuleClasses, + modifiers: TModifiers[], + BaseIcon: ComponentType +): { + component: ComponentType< + (TModifiers extends Prefixes + ? Pick, TModifiers> + : Partial>) & + TProps + >; + modifierPropsSchema: IconModifierPropsSchema; +} { + type CSSModuleModifiers = ModifierMap; // Do not bail if no CSS modules TypeScript plugin is provided. type FinalCSSModuleModifiers = TModifiers extends keyof CSSModuleModifiers diff --git a/packages/core/package.json b/packages/core/package.json index 387f10ade3..3f50c39bee 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -49,6 +49,7 @@ "allowSyntheticDefaultImports": true, "downlevelIteration": true, "jsx": "react", + "module": "NodeNext", "noImplicitAny": false, "resolveJsonModule": true, "skipLibCheck": true, @@ -56,7 +57,11 @@ } }, "scripts": { - "build": "tsup", + "build": "npm run build:tsup && npm run build:dtsroll && npm run build:validate", + "build:dtsroll": "dtsroll ./dist/*.d.*", + "build:tsup": "tsup", + "build:validate": "npm run build:validate:dts", + "build:validate:dts": "if grep -q -P '@msinternal\\/' dist/*.d.* 2>/dev/null; then echo \"Error: dist/*.d.* is not compiled by dtsroll\" >&2; exit 1; fi", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -66,7 +71,8 @@ "precommit:eslint": "../../node_modules/.bin/eslint --report-unused-disable-directives --max-warnings 0", "precommit:typecheck": "tsc --project ./src --emitDeclarationOnly false --esModuleInterop true --noEmit --pretty false", "preversion": "cat package.json | jq '(.localDependencies // {} | to_entries | map([if .value == \"production\" then \"dependencies\" else \"devDependencies\" end, .key])) as $P | delpaths($P)' > package-temp.json && mv package-temp.json package.json", - "start": "npm run build -- --watch 200" + "start": "npm run build:tsup -- --watch 200", + "test:tsd": "tsd" }, "engines": { "node": ">=12.0.0" diff --git a/packages/fluent-theme/package.json b/packages/fluent-theme/package.json index a1448fa6f3..e6954c665a 100644 --- a/packages/fluent-theme/package.json +++ b/packages/fluent-theme/package.json @@ -40,10 +40,13 @@ "static/**/*" ], "scripts": { - "build": "npm run build:static && npm run build:tsup && npm run build:validate", + "build": "npm run build:static && npm run build:tsup && npm run build:dtsroll && npm run build:validate", + "build:dtsroll": "dtsroll ./dist/*.d.*", "build:static": "node ./esbuild.static.mjs", "build:tsup": "tsup", - "build:validate": "grep -q -P '\\.webchat-fluent \\.w([a-zA-Z-]){6}_' dist/*.css 2>/dev/null || { echo \"Error: dist/*.css is not compiled by Lightning CSS\" >&2; exit 1; }", + "build:validate": "npm run build:validate:css && npm run build:validate:dts", + "build:validate:css": "grep -q -P '\\.webchat-fluent \\.w([a-zA-Z-]){6}_' dist/*.css 2>/dev/null || { echo \"Error: dist/*.css is not compiled by Lightning CSS\" >&2; exit 1; }", + "build:validate:dts": "if grep -q -P '@msinternal\\/' dist/*.d.* 2>/dev/null; then echo \"Error: dist/*.d.* is not compiled by dtsroll\" >&2; exit 1; fi", "bump": "npm run bump:prod && npm run bump:dev && (npm audit fix || exit 0)", "bump:dev": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.devDependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install $PACKAGES_TO_BUMP || true", "bump:prod": "PACKAGES_TO_BUMP=$(cat package.json | jq -r '(.pinDependencies // {}) as $P | (.localDependencies // {} | keys) as $L | (.dependencies // {}) | to_entries | map(select(.key as $K | $L | contains([$K]) | not)) | map(.key + \"@\" + ($P[.key] // [\"latest\"])[0]) | join(\" \")') && [ ! -z \"$PACKAGES_TO_BUMP\" ] && npm install --save-exact $PACKAGES_TO_BUMP || true", @@ -75,7 +78,6 @@ "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", "@types/math-random": "^1.0.2", "@types/node": "^24.1.0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, @@ -88,6 +90,7 @@ "valibot": "1.1.0" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6" } } diff --git a/packages/fluent-theme/src/components/icon/FluentIcon.tsx b/packages/fluent-theme/src/components/icon/FluentIcon.tsx index 865b337e64..d0e46ccf67 100644 --- a/packages/fluent-theme/src/components/icon/FluentIcon.tsx +++ b/packages/fluent-theme/src/components/icon/FluentIcon.tsx @@ -3,7 +3,7 @@ import { useStyles } from '@msinternal/botframework-webchat-styles/react'; import { createIconComponent } from 'botframework-webchat/internal'; import cx from 'classnames'; import React, { memo, useMemo, type CSSProperties } from 'react'; -import { object, optional, pipe, readonly, string, type InferInput } from 'valibot'; +import { object, optional, pipe, readonly, string, union, type InferInput } from 'valibot'; import styles from './FluentIcon.module.css'; @@ -37,13 +37,7 @@ const { component: FluentIcon, modifierPropsSchema } = createIconComponent( FluentIcon.displayName = 'FluentIcon'; -const fluentIconPropsSchema = pipe( - object({ - ...baseFluentIconPropsSchema.entries, - ...modifierPropsSchema.entries - }), - readonly() -); +const fluentIconPropsSchema = pipe(union([baseFluentIconPropsSchema, modifierPropsSchema]), readonly()); type FluentIconProps = InferInput; diff --git a/packages/react-valibot/package.json b/packages/react-valibot/package.json index 260a4fe4c4..45b0e0453b 100644 --- a/packages/react-valibot/package.json +++ b/packages/react-valibot/package.json @@ -2,6 +2,7 @@ "name": "@msinternal/botframework-webchat-react-valibot", "version": "0.0.0-0", "description": "The botframework-webchat react-valibot package", + "main": "./dist/botframework-webchat-react-valibot.js", "types": "./dist/botframework-webchat-react-valibot.d.ts", "exports": { ".": { @@ -58,15 +59,12 @@ "devDependencies": { "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", "@types/jest": "^30.0.0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, - "dependencies": { - "valibot": "1.1.0" - }, "peerDependencies": { - "react": ">= 16.8.6" - }, - "main": "index.js" + "@types/react": "^16.14.65", + "react": ">= 16.8.6", + "valibot": "1.1.0" + } } diff --git a/packages/redux-store/package.json b/packages/redux-store/package.json index 056ea9f944..24fa0343d9 100644 --- a/packages/redux-store/package.json +++ b/packages/redux-store/package.json @@ -60,7 +60,6 @@ "devDependencies": { "@msinternal/botframework-webchat-react-valibot": "^0.0.0-0", "@msinternal/botframework-webchat-tsconfig": "^0.0.0-0", - "@types/react": "^16.14.65", "tsup": "^8.5.0", "typescript": "~5.8.3" }, @@ -69,6 +68,7 @@ "valibot": "1.1.0" }, "peerDependencies": { + "@types/react": "^16.14.65", "react": ">= 16.8.6" } }