diff --git a/.changeset/changesets-cli-v3-migration-5296.md b/.changeset/changesets-cli-v3-migration-5296.md new file mode 100644 index 000000000..edcb41f78 --- /dev/null +++ b/.changeset/changesets-cli-v3-migration-5296.md @@ -0,0 +1,31 @@ +--- +--- + +Release-tooling only, no published package changes (objectui#5296). + +`@changesets/cli` moves from `^2.31.1` to `^3.0.0`, together with the +`.changeset/config.json` changes v3's defaults require — the two halves are +broken apart, and each half is broken silently until the next release, so they +land in one commit. + +- `privatePackages` is now declared explicitly as `{ "version": true, + "tag": false }`. Omitting it used to mean exactly that under v2 and means + `{ "version": false, "tag": false }` under v3, and `version: false` marks + private packages *ignored* rather than merely unbumped. This repo keeps one + private package inside the `fixed` group — `object-ui` + (`packages/vscode-extension`), which ships to the VS Code marketplace instead + of npm — and one pending changeset names it beside four published packages, + which under the new default makes the release plan a rejected "mixed + changeset". Measured: `changeset status` and `changeset version` both exit 1 + on the bump alone, and green PR CI cannot see it, because no PR workflow runs + either command. +- `___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH.onlyUpdatePeerDependentsWhenOutOfRange` + is removed. `@changesets/assemble-release-plan@6` reads it in six places and + `@7` in none, so it is load-bearing under v2 and inert under v3 — removable + only in the commit that lands the bump. +- `$schema` moves from `@changesets/config@3.1.2` to `@changesets/config@4.0.0`. +- `scripts/check-changeset-fixed.mjs` gains the two rules that make the above + mechanical: `privatePackages` must be declared, and a private package in the + `fixed` group must not be paired with `version: false`. Rehearsed against the + real pending stock in a throwaway clone; the v3 release plan is identical to + the v2 one, package for package. diff --git a/.changeset/config.json b/.changeset/config.json index f1d29d49f..b99edbdc6 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,5 +1,5 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json", "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [ @@ -53,7 +53,8 @@ "@object-ui/site", "@object-ui/test-support" ], - "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { - "onlyUpdatePeerDependentsWhenOutOfRange": true + "privatePackages": { + "version": true, + "tag": false } } diff --git a/package.json b/package.json index 94896e5c6..2eeb9b74e 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "test:e2e:import-console": "playwright test --config=playwright.import-console.config.ts" }, "devDependencies": { - "@changesets/cli": "^2.31.1", + "@changesets/cli": "^3.0.0", "@eslint/js": "^10.0.1", "@objectstack/spec": "^17.0.0", "@playwright/test": "^1.62.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dba5b2a8b..3d798da7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: version: 0.0.1-security devDependencies: '@changesets/cli': - specifier: ^2.31.1 - version: 2.31.1(@types/node@26.2.0) + specifier: ^3.0.0 + version: 3.0.1 '@eslint/js': specifier: ^10.0.1 version: 10.0.1(eslint@10.8.1(jiti@2.7.0)) @@ -3176,64 +3176,78 @@ packages: resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true - '@changesets/apply-release-plan@7.1.1': - resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} + '@changesets/apply-release-plan@8.0.0': + resolution: {integrity: sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/assemble-release-plan@6.0.10': - resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} + '@changesets/assemble-release-plan@7.0.0': + resolution: {integrity: sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/changelog-git@0.2.1': - resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + '@changesets/changelog-git@1.0.0': + resolution: {integrity: sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/cli@2.31.1': - resolution: {integrity: sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==} + '@changesets/cli@3.0.1': + resolution: {integrity: sha512-3IVpRSgiKDj2aRbBHKtWTXSRH2/iR3bWxau9iQUoEsZjDhRIj9nhl90k7FWMxZAJvLgJBbgMq8+qS0xQsenYsQ==} + engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'} hasBin: true - '@changesets/config@3.1.4': - resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} + '@changesets/config@4.0.0': + resolution: {integrity: sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/errors@0.2.0': - resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + '@changesets/errors@1.0.0': + resolution: {integrity: sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/get-dependents-graph@2.1.4': - resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + '@changesets/format@0.1.2': + resolution: {integrity: sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/get-release-plan@4.0.16': - resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + '@changesets/get-dependents-graph@3.0.0': + resolution: {integrity: sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/get-version-range-type@0.4.0': - resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + '@changesets/git@4.0.0': + resolution: {integrity: sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/git@3.0.4': - resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + '@changesets/parse@1.0.0': + resolution: {integrity: sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/logger@0.1.1': - resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + '@changesets/pre@3.0.0': + resolution: {integrity: sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/parse@0.4.3': - resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + '@changesets/read@1.0.0': + resolution: {integrity: sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/pre@2.0.2': - resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + '@changesets/should-skip-package@1.0.0': + resolution: {integrity: sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/read@0.6.7': - resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + '@changesets/types@7.0.0': + resolution: {integrity: sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==} + engines: {node: ^22.11 || ^24 || >=26} - '@changesets/should-skip-package@0.1.2': - resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} - - '@changesets/types@4.1.0': - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - - '@changesets/types@6.1.0': - resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} - - '@changesets/write@0.4.0': - resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@changesets/write@1.0.1': + resolution: {integrity: sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==} + engines: {node: ^22.11 || ^24 || >=26} '@chevrotain/types@11.1.2': resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + '@csstools/color-helpers@6.1.0': resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==} engines: {node: '>=20.19.0'} @@ -3946,15 +3960,6 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/figures@2.0.7': resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -3984,11 +3989,17 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@manypkg/find-root@1.1.0': - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + '@manypkg/find-root@3.1.0': + resolution: {integrity: sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==} + engines: {node: '>=20.0.0'} + + '@manypkg/get-packages@3.1.0': + resolution: {integrity: sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==} + engines: {node: '>=20.0.0'} - '@manypkg/get-packages@1.1.3': - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@manypkg/tools@2.1.2': + resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==} + engines: {node: '>=20.0.0'} '@mapbox/jsonlint-lines-primitives@2.0.3': resolution: {integrity: sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg==} @@ -4207,6 +4218,10 @@ packages: engines: {node: '>=20'} hasBin: true + '@pnpm/deps.graph-sequencer@1100.0.1': + resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} + engines: {node: '>=22.13'} + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} @@ -5773,9 +5788,6 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - '@types/node@14.18.63': resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} @@ -6281,10 +6293,6 @@ packages: array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -6428,10 +6436,6 @@ packages: zod: optional: true - better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} - better-sqlite3@12.9.0: resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} @@ -6546,6 +6550,10 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -6602,9 +6610,6 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chardet@2.2.0: - resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} - cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -7108,10 +7113,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -7129,10 +7130,6 @@ packages: dijkstrajs@1.0.3: resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -7454,9 +7451,6 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - fast-csv@4.3.6: resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==} engines: {node: '>=10.0.0'} @@ -7623,14 +7617,6 @@ packages: resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==} engines: {node: '>=14.14'} - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -7840,10 +7826,6 @@ packages: resolution: {integrity: sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==} engines: {node: '>=18'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - globby@14.1.0: resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} @@ -8199,10 +8181,6 @@ packages: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} - is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} - is-unicode-supported@1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} @@ -8211,10 +8189,6 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - is-wsl@2.2.0: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} @@ -8281,10 +8255,6 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.15.1: - resolution: {integrity: sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==} - hasBin: true - js-yaml@4.3.1: resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} hasBin: true @@ -8345,9 +8315,6 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.2.1: resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} @@ -8395,6 +8362,9 @@ packages: resolution: {integrity: sha512-ooa+eSbBNPTo3MycPEuW5jdrxQdQwdtB3LC3h43FiXQbIry5tR0C5lDG7eealK0E4D7XjrnOP5DIUg/LyjRMYQ==} engines: {node: '>=22.0.0'} + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} @@ -8649,9 +8619,6 @@ packages: lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} @@ -9104,10 +9071,6 @@ packages: react-dom: optional: true - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -9300,16 +9263,9 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -9330,10 +9286,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - p-map@7.0.4: resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} engines: {node: '>=18'} @@ -9342,9 +9294,6 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - package-manager-detector@0.2.11: - resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} @@ -9431,10 +9380,6 @@ packages: path-to-regexp@8.4.2: resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - path-type@6.0.0: resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} engines: {node: '>=18'} @@ -9460,10 +9405,6 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -9567,11 +9508,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -9839,10 +9775,6 @@ packages: resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} engines: {node: '>=18'} - read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} - read@1.0.7: resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} engines: {node: '>=0.8'} @@ -10223,10 +10155,6 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - slash@5.1.0: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} @@ -10287,9 +10215,6 @@ packages: sparse-bitfield@3.0.3: resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} - spawndamnit@3.0.1: - resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} - spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -10493,10 +10418,6 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - terminal-link@4.0.0: resolution: {integrity: sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA==} engines: {node: '>=18'} @@ -10771,10 +10692,6 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -11664,150 +11581,123 @@ snapshots: dependencies: css-tree: 3.2.1 - '@changesets/apply-release-plan@7.1.1': - dependencies: - '@changesets/config': 3.1.4 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 + '@changesets/apply-release-plan@8.0.0': + dependencies: + '@changesets/config': 4.0.0 + '@changesets/format': 0.1.2 + '@changesets/git': 4.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + import-meta-resolve: 4.2.0 + jsonc-parser: 3.3.1 semver: 7.8.5 - '@changesets/assemble-release-plan@6.0.10': + '@changesets/assemble-release-plan@7.0.0': dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 semver: 7.8.5 - '@changesets/changelog-git@0.2.1': - dependencies: - '@changesets/types': 6.1.0 - - '@changesets/cli@2.31.1(@types/node@26.2.0)': - dependencies: - '@changesets/apply-release-plan': 7.1.1 - '@changesets/assemble-release-plan': 6.0.10 - '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.4 - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/get-release-plan': 4.0.16 - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@26.2.0) - '@manypkg/get-packages': 1.1.3 - ansi-colors: 4.1.3 - enquirer: 2.4.1 - fs-extra: 7.0.1 - mri: 1.2.0 - package-manager-detector: 0.2.11 - picocolors: 1.1.1 - resolve-from: 5.0.0 + '@changesets/changelog-git@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/cli@3.0.1': + dependencies: + '@changesets/apply-release-plan': 8.0.0 + '@changesets/assemble-release-plan': 7.0.0 + '@changesets/changelog-git': 1.0.0 + '@changesets/config': 4.0.0 + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/git': 4.0.0 + '@changesets/pre': 3.0.0 + '@changesets/read': 1.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@changesets/write': 1.0.1 + '@clack/prompts': 1.7.0 + '@manypkg/get-packages': 3.1.0 + '@pnpm/deps.graph-sequencer': 1100.0.1 + cac: 7.0.0 + import-meta-resolve: 4.2.0 + launch-editor: 2.14.1 + package-manager-detector: 1.8.0 semver: 7.8.5 - spawndamnit: 3.0.1 - term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' + tinyexec: 1.3.0 - '@changesets/config@3.1.4': + '@changesets/config@4.0.0': dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.4 - '@changesets/logger': 0.1.1 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.8 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.5 + + '@changesets/errors@1.0.0': {} - '@changesets/errors@0.2.0': + '@changesets/format@0.1.2': dependencies: - extendable-error: 0.1.7 + package-manager-detector: 1.8.0 + tinyexec: 1.3.0 - '@changesets/get-dependents-graph@2.1.4': + '@changesets/get-dependents-graph@3.0.0': dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 + '@changesets/types': 7.0.0 semver: 7.8.5 - '@changesets/get-release-plan@4.0.16': + '@changesets/git@4.0.0': dependencies: - '@changesets/assemble-release-plan': 6.0.10 - '@changesets/config': 3.1.4 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.7 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/get-version-range-type@0.4.0': {} + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.5 + tinyexec: 1.3.0 - '@changesets/git@3.0.4': + '@changesets/parse@1.0.0': dependencies: - '@changesets/errors': 0.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.8 - spawndamnit: 3.0.1 + '@changesets/types': 7.0.0 + yaml: 2.9.0 - '@changesets/logger@0.1.1': + '@changesets/pre@3.0.0': dependencies: - picocolors: 1.1.1 + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 - '@changesets/parse@0.4.3': + '@changesets/read@1.0.0': dependencies: - '@changesets/types': 6.1.0 - js-yaml: 4.3.1 + '@changesets/git': 4.0.0 + '@changesets/parse': 1.0.0 + '@changesets/types': 7.0.0 - '@changesets/pre@2.0.2': + '@changesets/should-skip-package@1.0.0': dependencies: - '@changesets/errors': 0.2.0 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 + '@changesets/types': 7.0.0 - '@changesets/read@0.6.7': - dependencies: - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.3 - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - p-filter: 2.1.0 - picocolors: 1.1.1 + '@changesets/types@7.0.0': {} - '@changesets/should-skip-package@0.1.2': + '@changesets/write@1.0.1': dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/types@4.1.0': {} + '@changesets/format': 0.1.2 + '@changesets/types': 7.0.0 + human-id: 4.2.0 - '@changesets/types@6.1.0': {} + '@chevrotain/types@11.1.2': {} - '@changesets/write@0.4.0': + '@clack/core@1.4.3': dependencies: - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - human-id: 4.2.0 - prettier: 2.8.8 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 - '@chevrotain/types@11.1.2': {} + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 '@csstools/color-helpers@6.1.0': {} @@ -12309,13 +12199,6 @@ snapshots: optionalDependencies: '@types/node': 26.2.0 - '@inquirer/external-editor@1.0.3(@types/node@26.2.0)': - dependencies: - chardet: 2.2.0 - iconv-lite: 0.7.3 - optionalDependencies: - '@types/node': 26.2.0 - '@inquirer/figures@2.0.7': {} '@inquirer/type@4.0.7(@types/node@26.2.0)': @@ -12341,21 +12224,20 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@manypkg/find-root@1.1.0': + '@manypkg/find-root@3.1.0': dependencies: - '@babel/runtime': 7.29.7 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 + '@manypkg/tools': 2.1.2 - '@manypkg/get-packages@1.1.3': + '@manypkg/get-packages@3.1.0': dependencies: - '@babel/runtime': 7.29.7 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 + '@manypkg/find-root': 3.1.0 + '@manypkg/tools': 2.1.2 + + '@manypkg/tools@2.1.2': + dependencies: + jju: 1.4.0 + tinyglobby: 0.2.17 + yaml: 2.9.0 '@mapbox/jsonlint-lines-primitives@2.0.3': {} @@ -12633,6 +12515,8 @@ snapshots: dependencies: playwright: 1.62.1 + '@pnpm/deps.graph-sequencer@1100.0.1': {} + '@polka/url@1.0.0-next.29': {} '@radix-ui/number@1.1.3': {} @@ -14177,8 +14061,6 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@12.20.55': {} - '@types/node@14.18.63': {} '@types/node@26.2.0': @@ -14737,6 +14619,7 @@ snapshots: argparse@1.0.10: dependencies: sprintf-js: 1.0.3 + optional: true argparse@2.0.1: {} @@ -14754,8 +14637,6 @@ snapshots: array-flatten@1.1.1: {} - array-union@2.1.0: {} - assertion-error@2.0.1: {} assign-symbols@1.0.0: {} @@ -14857,10 +14738,6 @@ snapshots: optionalDependencies: zod: 4.4.3 - better-path-resolve@1.0.0: - dependencies: - is-windows: 1.0.2 - better-sqlite3@12.9.0: dependencies: bindings: 1.5.0 @@ -15005,6 +14882,8 @@ snapshots: cac@6.7.14: {} + cac@7.0.0: {} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -15048,8 +14927,6 @@ snapshots: character-reference-invalid@2.0.1: {} - chardet@2.2.0: {} - cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -15544,8 +15421,6 @@ snapshots: destroy@1.2.0: {} - detect-indent@6.1.0: {} - detect-libc@2.1.2: {} detect-node-es@1.1.0: {} @@ -15558,10 +15433,6 @@ snapshots: dijkstrajs@1.0.3: {} - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -16046,8 +15917,6 @@ snapshots: extend@3.0.2: {} - extendable-error@0.1.7: {} - fast-csv@4.3.6: dependencies: '@fast-csv/format': 4.3.5 @@ -16215,18 +16084,6 @@ snapshots: jsonfile: 6.2.1 universalify: 2.0.1 - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - fs.realpath@1.0.0: {} fsevents@2.3.2: @@ -16420,15 +16277,6 @@ snapshots: globals@17.11.0: {} - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - globby@14.1.0: dependencies: '@sindresorhus/merge-streams': 2.3.0 @@ -16822,16 +16670,10 @@ snapshots: is-stream@4.0.1: {} - is-subdir@1.2.0: - dependencies: - better-path-resolve: 1.0.0 - is-unicode-supported@1.3.0: {} is-unicode-supported@2.1.0: {} - is-windows@1.0.2: {} - is-wsl@2.2.0: dependencies: is-docker: 2.2.1 @@ -16872,8 +16714,7 @@ snapshots: jiti@2.7.0: {} - jju@1.4.0: - optional: true + jju@1.4.0: {} joi@18.2.3: dependencies: @@ -16893,11 +16734,6 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@3.15.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - js-yaml@4.3.1: dependencies: argparse: 2.0.1 @@ -16958,10 +16794,6 @@ snapshots: jsonc-parser@3.3.1: {} - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - jsonfile@6.2.1: dependencies: universalify: 2.0.1 @@ -17025,6 +16857,11 @@ snapshots: kysely@0.29.5: {} + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.9.0 + layout-base@1.0.2: {} layout-base@2.0.1: {} @@ -17207,8 +17044,6 @@ snapshots: lodash.once@4.1.1: {} - lodash.startcase@4.4.0: {} - lodash.truncate@4.4.2: {} lodash.union@4.6.0: {} @@ -17940,8 +17775,6 @@ snapshots: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - mri@1.2.0: {} - mrmime@2.0.1: {} ms@2.0.0: {} @@ -18149,14 +17982,8 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 - outdent@0.5.0: {} - outvariant@1.4.3: {} - p-filter@2.1.0: - dependencies: - p-map: 2.1.0 - p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -18177,16 +18004,10 @@ snapshots: dependencies: p-limit: 3.1.0 - p-map@2.1.0: {} - p-map@7.0.4: {} p-try@2.2.0: {} - package-manager-detector@0.2.11: - dependencies: - quansync: 0.2.11 - package-manager-detector@1.8.0: {} pako@1.0.11: {} @@ -18271,8 +18092,6 @@ snapshots: path-to-regexp@8.4.2: {} - path-type@4.0.0: {} - path-type@6.0.0: {} pathe@2.0.3: {} @@ -18289,8 +18108,6 @@ snapshots: picomatch@4.0.5: {} - pify@4.0.1: {} - pirates@4.0.7: {} pkce-challenge@5.0.1: {} @@ -18389,8 +18206,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier@2.8.8: {} - pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -18664,13 +18479,6 @@ snapshots: type-fest: 4.41.0 unicorn-magic: 0.1.0 - read-yaml-file@1.1.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.15.1 - pify: 4.0.1 - strip-bom: 3.0.0 - read@1.0.7: dependencies: mute-stream: 0.0.8 @@ -19289,8 +19097,6 @@ snapshots: sisteransi@1.0.5: {} - slash@3.0.0: {} - slash@5.1.0: {} slice-ansi@4.0.0: @@ -19341,11 +19147,6 @@ snapshots: memory-pager: 1.5.0 optional: true - spawndamnit@3.0.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -19364,7 +19165,8 @@ snapshots: dependencies: extend-shallow: 3.0.2 - sprintf-js@1.0.3: {} + sprintf-js@1.0.3: + optional: true stackback@0.0.2: {} @@ -19562,8 +19364,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - term-size@2.2.1: {} - terminal-link@4.0.0: dependencies: ansi-escapes: 7.3.0 @@ -19846,8 +19646,6 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 - universalify@0.1.2: {} - universalify@2.0.1: {} unpipe@1.0.0: {} diff --git a/scripts/__tests__/check-changeset-fixed.test.ts b/scripts/__tests__/check-changeset-fixed.test.ts new file mode 100644 index 000000000..58904d0be --- /dev/null +++ b/scripts/__tests__/check-changeset-fixed.test.ts @@ -0,0 +1,176 @@ +import { describe, expect, it } from 'vitest'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +// Plain-JS CI helper. Its types are INFERRED from the .mjs source by +// `tsconfig.scripts.json` (`allowJs`), so no `@ts-expect-error` here — +// re-adding one is now itself an error (TS2578). See objectui#3494. +import { analyze, globMatcher, normalizePrivatePackages } from '../check-changeset-fixed.mjs'; + +/** + * `scripts/check-changeset-fixed.mjs` used to answer one question — is every + * workspace package in `fixed` or `ignore`? — and that question was complete + * only while private packages released like public ones. + * + * `@changesets/cli@3` ended that. Measured against `@changesets/config@4.0.0`: + * an omitted `privatePackages` defaulted to `{ version: true, tag: false }` + * under v2 and defaults to `{ version: false, tag: false }` under v3, and + * `version: false` marks private packages IGNORED rather than merely unbumped. + * This repo keeps one private package inside the 40-name `fixed` group — + * `object-ui` at `packages/vscode-extension`, which ships to the VS Code + * marketplace instead of npm — so under the new default a changeset naming it + * next to a published package becomes a "mixed changeset" and both + * `changeset status` and `changeset version` exit 1. + * + * The stock pending during the v3 migration contained exactly one such file, + * `.changeset/no-console-lint-rule.md` (`object-ui` plus four published + * packages), so the bump alone would have stopped the release lane on the very + * next push to `main`. Nothing in PR CI could have reported it: no PR workflow + * runs `changeset status` or `changeset version`, the only invocation being + * `.github/workflows/changeset-release.yml`. + * + * These tests are the lock on the two rules added for that: the key must be + * declared, and `fixed` membership must not contradict it. + */ +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); + +const pkg = (name: string, isPrivate = false) => ({ + name, + path: `packages/${name}/package.json`, + private: isPrivate, +}); + +describe('normalizePrivatePackages', () => { + it('reports an absent key as absent rather than defaulting it', () => { + // The whole point of rule 2: v2 and v3 default the same silence to opposite + // values, so "not written down" has to be distinguishable from "written + // down as false". + expect(normalizePrivatePackages(undefined)).toBeNull(); + expect(normalizePrivatePackages(null)).toBeNull(); + }); + + it('expands the boolean shorthand to both fields, as @changesets/config@4 does', () => { + expect(normalizePrivatePackages(true)).toEqual({ version: true, tag: true }); + expect(normalizePrivatePackages(false)).toEqual({ version: false, tag: false }); + }); + + it('defaults each missing field of an object form to false', () => { + expect(normalizePrivatePackages({ version: true })).toEqual({ version: true, tag: false }); + expect(normalizePrivatePackages({ version: true, tag: false })).toEqual({ + version: true, + tag: false, + }); + }); +}); + +describe('globMatcher', () => { + it('expands a `*` the way changesets expands `ignore` and `fixed` entries', () => { + const matches = globMatcher(['@object-ui/example-*', '@object-ui/site']); + expect(matches('@object-ui/example-hello-world')).toBe(true); + expect(matches('@object-ui/site')).toBe(true); + expect(matches('@object-ui/core')).toBe(false); + }); + + it('does not let regex metacharacters in a package name match loosely', () => { + expect(globMatcher(['@object-ui/core'])('@object-uixcore')).toBe(false); + }); +}); + +describe('analyze', () => { + const config = { + fixed: [['@object-ui/core', 'object-ui']], + ignore: ['@object-ui/example-*'], + }; + const manifests = [pkg('@object-ui/core'), pkg('object-ui', true)]; + + it('passes a private fixed-group member when privatePackages.version is true', () => { + const result = analyze({ ...config, privatePackages: { version: true, tag: false } }, manifests); + expect(result.unclassified).toEqual([]); + expect(result.privateInFixed).toEqual([]); + expect(result.privatePackages).toEqual({ version: true, tag: false }); + }); + + it('flags a private fixed-group member when privatePackages.version is false', () => { + // The measured failure mode: `fixed` says "version in lockstep", the key + // says "ignored", and changesets reports neither until a changeset names + // this package beside a published one. + const result = analyze( + { ...config, privatePackages: { version: false, tag: false } }, + manifests + ); + expect(result.privateInFixed.map((p) => p.name)).toEqual(['object-ui']); + }); + + it('treats an undeclared privatePackages as undeclared, and still flags the contradiction', () => { + const result = analyze(config, manifests); + expect(result.privatePackages).toBeNull(); + expect(result.privateInFixed.map((p) => p.name)).toEqual(['object-ui']); + }); + + it('leaves a private package alone when it is ignored rather than fixed', () => { + const result = analyze( + { fixed: [['@object-ui/core']], ignore: ['@object-ui/example-*'], privatePackages: false }, + [pkg('@object-ui/core'), pkg('@object-ui/example-hello-world', true)] + ); + expect(result.unclassified).toEqual([]); + expect(result.privateInFixed).toEqual([]); + }); + + it('reports a package that is in neither `fixed` nor `ignore`', () => { + const result = analyze({ ...config, privatePackages: { version: true, tag: false } }, [ + ...manifests, + pkg('@object-ui/unlisted'), + ]); + expect(result.unclassified.map((p) => p.name)).toEqual(['@object-ui/unlisted']); + }); +}); + +describe('the repository itself', () => { + const config = JSON.parse( + fs.readFileSync(path.join(repoRoot, '.changeset/config.json'), 'utf8') + ) as { fixed?: string[][]; ignore?: string[]; privatePackages?: unknown }; + + const manifests = ['packages', 'apps'].flatMap((dir) => + fs + .readdirSync(path.join(repoRoot, dir), { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => path.join(dir, entry.name, 'package.json')) + .filter((rel) => fs.existsSync(path.join(repoRoot, rel))) + .map((rel) => { + const manifest = JSON.parse(fs.readFileSync(path.join(repoRoot, rel), 'utf8')); + return { name: manifest.name as string, path: rel, private: manifest.private === true }; + }) + .filter((entry) => Boolean(entry.name)) + ); + + it('declares `privatePackages` explicitly', () => { + expect( + normalizePrivatePackages(config.privatePackages), + 'An omitted key means `{ version: true, tag: false }` under @changesets/cli@2 and ' + + '`{ version: false, tag: false }` under v3 — opposite answers to "does object-ui ' + + 'release?". Write it down.' + ).not.toBeNull(); + }); + + it('classifies every workspace package, with no fixed/private contradiction', () => { + const { unclassified, privateInFixed } = analyze(config, manifests); + expect(unclassified.map((p) => `${p.name} (${p.path})`)).toEqual([]); + expect( + privateInFixed.map((p) => `${p.name} (${p.path})`), + 'A private package in the `fixed` group needs `privatePackages.version: true`, or the ' + + 'next changeset that names it beside a published package makes the release plan a ' + + 'mixed changeset and `changeset version` exits 1 on `main`.' + ).toEqual([]); + }); + + it('still keeps the private VS Code extension inside the fixed group', () => { + // The shape the two rules above exist for. If this ever stops being true the + // guard is not wrong, but it is no longer guarding anything real — and the + // rationale in both files should be re-read before it is trimmed. + const vscode = manifests.find((m) => m.path === 'packages/vscode-extension/package.json'); + expect(vscode?.name).toBe('object-ui'); + expect(vscode?.private).toBe(true); + expect((config.fixed ?? []).flat()).toContain('object-ui'); + }); +}); diff --git a/scripts/check-changeset-fixed.mjs b/scripts/check-changeset-fixed.mjs index 08e1ca854..6be4ee24e 100644 --- a/scripts/check-changeset-fixed.mjs +++ b/scripts/check-changeset-fixed.mjs @@ -1,10 +1,56 @@ #!/usr/bin/env node /** - * Validates that every workspace package is listed in the changeset - * `fixed` group (or explicitly ignored). + * Validates how `.changeset/config.json` classifies every workspace package for + * release. Three rules, all decided from the config file plus the manifests: + * + * 1. every workspace package under `packages/` and `apps/` is either in the + * `fixed` group or matched by `ignore`; + * 2. `privatePackages` is declared explicitly; + * 3. no PRIVATE package sits in the `fixed` group while + * `privatePackages.version` is false. + * + * Rule 1 is the original one and is version-agnostic. Rules 2 and 3 exist + * because `@changesets/cli@3` changed what an ABSENT `privatePackages` means, + * and this repo has a private package inside the `fixed` group — `object-ui` + * (`packages/vscode-extension`), private because it ships to the VS Code + * marketplace rather than npm, but versioned in lockstep with the 39 + * publishable packages so its version keeps matching the runtime it embeds. + * + * What changed, measured against `@changesets/config@4.0.0` rather than + * recalled: an omitted `privatePackages` used to default to + * `{ version: true, tag: false }` and now defaults to + * `{ version: false, tag: false }`, and `version: false` does not merely skip + * the version bump — it feeds `allowPrivatePackages: false` into the release + * assembler, i.e. the package is treated as IGNORED. A changeset that names one + * ignored and one non-ignored package is then a "mixed changeset", which + * `assembleReleasePlan` refuses outright: + * + * Error: Found mixed changeset no-console-lint-rule + * Found ignored packages: object-ui + * Found not ignored packages: @object-ui/app-shell @object-ui/fields … + * Mixed changesets that contain both ignored and not ignored packages are + * not allowed + * + * That is not a hypothetical: `.changeset/no-console-lint-rule.md` in the stock + * pending at the time of the v3 migration named exactly that combination, so + * bumping the CLI without declaring the key exited 1 on `changeset status` AND + * on `changeset version` — the release lane stops, and nothing in PR CI would + * have said so, because no PR workflow runs either command (the only invocation + * is inside `.github/workflows/changeset-release.yml`, on push to `main`). + * + * Hence rule 2: silence about `privatePackages` is no longer a safe default, + * because its meaning inverted. And hence rule 3: `fixed` membership and + * `version: false` are a contradiction — one says "version this in lockstep", + * the other says "this is ignored" — and changesets does not diagnose the + * contradiction at config-read time, only later as the mixed-changeset error, + * from whichever changeset happens to trip it. + * + * Runs on a bare checkout with no `pnpm install` (`.github/workflows/ci.yml`, + * job `changeset-check`, is a checkout plus one `node` call), so this file may + * not import `@changesets/*` or any other dependency. Keep it that way. * * Run: node scripts/check-changeset-fixed.mjs - * Exit: 0 = OK, 1 = packages are missing from the fixed group + * Exit: 0 = OK, 1 = a package is misclassified or the config is under-declared */ import { readFileSync, readdirSync, statSync } from "fs"; @@ -13,58 +59,170 @@ import { fileURLToPath } from "url"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); -// ── Load changeset config ───────────────────────────────────────────────────── -const config = JSON.parse( - readFileSync(resolve(root, ".changeset/config.json"), "utf8") -); +/** The workspace roots this gate classifies, shared with `check-changeset-presence.mjs`. */ +const PACKAGE_ROOTS = ["packages", "apps"]; + +/** + * Turns a changesets `ignore` entry (`@object-ui/example-*`) into a matcher. + * Kept identical to `ignoreMatcher` in `scripts/check-changeset-presence.mjs`: + * changesets glob-expands `ignore` and `fixed` when it reads the config, so a + * gate that compared literal strings would call a glob-ignored package + * unclassified and fail on a config changesets is perfectly happy with. + * + * @param {string[]} patterns + * @returns {(name: string) => boolean} + */ +export function globMatcher(patterns) { + const expressions = patterns.map( + (pattern) => + new RegExp( + `^${pattern.replace(/[.*+?^${}()|[\]\\]/g, (c) => (c === "*" ? ".*" : `\\${c}`))}$` + ) + ); + return (name) => expressions.some((expression) => expression.test(name)); +} + +/** + * Normalizes the written `privatePackages` value the way `@changesets/config@4` + * does: a boolean is shorthand for both fields, an object defaults each missing + * field to `false`, and an absent key is reported as absent rather than + * defaulted — rule 2 is about the declaration, not about the value. + * + * @param {unknown} written + * @returns {{ version: boolean, tag: boolean } | null} null when undeclared + */ +export function normalizePrivatePackages(written) { + if (written === undefined || written === null) return null; + if (typeof written !== "object") return { version: Boolean(written), tag: Boolean(written) }; + const value = /** @type {{ version?: unknown, tag?: unknown }} */ (written); + return { version: Boolean(value.version), tag: Boolean(value.tag) }; +} + +/** + * @typedef {{ name: string, path: string, private: boolean }} Manifest + * @typedef {{ unclassified: Manifest[], privateInFixed: Manifest[], + * privatePackages: { version: boolean, tag: boolean } | null }} Analysis + */ + +/** + * The whole judgement, as a pure function of the config and the manifests — + * `scripts/__tests__/check-changeset-fixed.test.ts` drives it directly. + * + * @param {{ fixed?: string[][], ignore?: string[], privatePackages?: unknown }} config + * @param {Manifest[]} manifests + * @returns {Analysis} + */ +export function analyze(config, manifests) { + const isFixed = globMatcher((config.fixed ?? []).flat()); + const isIgnored = globMatcher(config.ignore ?? []); + const privatePackages = normalizePrivatePackages(config.privatePackages); + + const unclassified = manifests.filter((pkg) => !isFixed(pkg.name) && !isIgnored(pkg.name)); + const privateInFixed = + privatePackages?.version === true + ? [] + : manifests.filter((pkg) => pkg.private && isFixed(pkg.name)); -const fixedSet = new Set(config.fixed?.flat() ?? []); -const ignoredSet = new Set(config.ignore ?? []); + return { unclassified, privateInFixed, privatePackages }; +} // ── Collect all workspace package names ────────────────────────────────────── -function findPackageJsons(dirs) { +/** + * @param {string[]} dirs + * @returns {Manifest[]} + */ +function readManifests(dirs) { + /** @type {Manifest[]} */ const results = []; for (const dir of dirs) { const abs = resolve(root, dir); + let entries; try { - for (const entry of readdirSync(abs)) { - const pkgFile = join(abs, entry, "package.json"); - try { - statSync(pkgFile); - results.push(join(dir, entry, "package.json")); - } catch { /* skip */ } + entries = readdirSync(abs); + } catch { + continue; + } + for (const entry of entries) { + const rel = join(dir, entry, "package.json"); + try { + statSync(join(abs, entry, "package.json")); + } catch { + continue; // not a package directory } - } catch { /* skip */ } + const pkg = JSON.parse(readFileSync(resolve(root, rel), "utf8")); + if (!pkg.name) continue; + results.push({ name: pkg.name, path: rel, private: pkg.private === true }); + } } return results; } -const manifests = findPackageJsons(["packages", "apps"]); +function main() { + const config = JSON.parse(readFileSync(resolve(root, ".changeset/config.json"), "utf8")); + const { unclassified, privateInFixed, privatePackages } = analyze( + config, + readManifests(PACKAGE_ROOTS) + ); -const missing = []; + let failed = false; -for (const rel of manifests) { - const pkg = JSON.parse(readFileSync(resolve(root, rel), "utf8")); - const name = pkg.name; - if (!name) continue; - if (!fixedSet.has(name) && !ignoredSet.has(name)) { - missing.push({ name, path: rel }); + if (unclassified.length > 0) { + failed = true; + console.error( + "❌ The following packages are missing from the changeset fixed group in .changeset/config.json:\n" + ); + for (const { name, path } of unclassified) { + console.error(` • ${name} (${path})`); + } + console.error( + "\nAdd them to the `fixed` array in .changeset/config.json to keep versions in sync." + ); } -} -// ── Report ──────────────────────────────────────────────────────────────────── -if (missing.length === 0) { - console.log("✅ All workspace packages are in the changeset fixed group."); - process.exit(0); -} else { - console.error( - "❌ The following packages are missing from the changeset fixed group in .changeset/config.json:\n" - ); - for (const { name, path } of missing) { - console.error(` • ${name} (${path})`); + if (privatePackages === null) { + failed = true; + console.error( + "\n❌ .changeset/config.json does not declare `privatePackages`.\n" + + "\nOmitting it is not neutral: @changesets/cli@2 defaulted to\n" + + '`{ "version": true, "tag": false }` and @changesets/cli@3 defaults to\n' + + '`{ "version": false, "tag": false }`, and `version: false` makes every private\n' + + "package IGNORED — after which any changeset naming a private package next to a\n" + + 'published one is a "mixed changeset" and `changeset status` / `changeset version`\n' + + "exit 1. No PR workflow runs either command, so the first symptom would be the\n" + + "release lane failing on `main`.\n" + + '\nDeclare it: `"privatePackages": { "version": true, "tag": false }` keeps this\n' + + "repo's behaviour (private packages versioned in lockstep, never git-tagged)." + ); + } else if (privateInFixed.length > 0) { + failed = true; + console.error( + "\n❌ These private packages are in the `fixed` group while " + + "`privatePackages.version` is false:\n" + ); + for (const { name, path } of privateInFixed) { + console.error(` • ${name} (${path})`); + } + console.error( + "\nThat is a contradiction changesets does not diagnose when it reads the config:\n" + + "`fixed` says version this in lockstep, `version: false` says treat it as ignored.\n" + + "It surfaces later, as `Mixed changesets that contain both ignored and not ignored\n" + + "packages are not allowed`, from whichever changeset happens to name one of these\n" + + "alongside a published package — and that error stops the release lane.\n" + + '\nFix: set `"privatePackages": { "version": true, "tag": false }`, or move the\n' + + "package out of `fixed` and into `ignore`." + ); } - console.error( - "\nAdd them to the `fixed` array in .changeset/config.json to keep versions in sync." + + if (failed) return 1; + + console.log("✅ All workspace packages are in the changeset fixed group."); + console.log( + `✅ privatePackages declared: version=${privatePackages.version}, tag=${privatePackages.tag}.` ); - process.exit(1); + return 0; +} + +// Only run when invoked as a script — the tests import the helpers above. +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + process.exit(main()); }