fix(tooling): fix stringWidth error in release-it interactive prompt (#179)
## Why
### Problem
Running `bun release -i patch` (or any interactive `release-it`
invocation) always failed with:
```
ERROR stringWidth is not a function
```
### Root Cause
`@inquirer/core` (used by `inquirer@12`, which `release-it@19` depends
on) bundles its own `wrap-ansi@6.2.0` (CJS). That package calls
`require('string-width')`, but the top-level `string-width` in this
project is v8 — pure ESM. When required via CJS, Node returns a module
namespace object instead of a function, causing the crash when
`release-it` tried to render its interactive confirmation prompt.
## What
- Added `scripts/patch-inquirer-string-width.js`: installs
CJS-compatible versions of `string-width@4`, `strip-ansi@6`,
`ansi-regex@5`, and `is-fullwidth-code-point@3` into
`node_modules/@inquirer/core/node_modules/` so `wrap-ansi@6` resolves
them correctly.
- Added a `postinstall` script to `package.json` so the patch is
re-applied automatically after every `bun install`.
## Verification
### Tests
No automated tests — this is a dev tooling fix. Verified manually by
running `node node_modules/release-it/bin/release-it.js --dry-run` and
confirming the interactive prompt renders without the `stringWidth`
error.
### Manual
1. `bun install` — postinstall script runs and outputs `Patch applied.`
2. `bun release -i patch` — interactive prompt now renders correctly.
This commit is contained in:
parent
6c5961da05
commit
866f90838e
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "whisper-money",
|
"name": "whisper-money",
|
||||||
"version": "0.1.14",
|
"version": "0.1.15",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "whisper-money",
|
"name": "whisper-money",
|
||||||
"version": "0.1.14",
|
"version": "0.1.15",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^2.2.0",
|
"@headlessui/react": "^2.2.0",
|
||||||
"@inertiajs/react": "^2.1.4",
|
"@inertiajs/react": "^2.1.4",
|
||||||
|
|
|
||||||
103
package.json
103
package.json
|
|
@ -1,10 +1,11 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package.json",
|
"$schema": "https://json.schemastore.org/package.json",
|
||||||
"name": "whisper-money",
|
"name": "whisper-money",
|
||||||
"version": "0.1.14",
|
"version": "0.1.15",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"postinstall": "node scripts/patch-inquirer-string-width.js",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"build:ssr": "vite build && vite build --ssr",
|
"build:ssr": "vite build && vite build --ssr",
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
@ -18,89 +19,89 @@
|
||||||
"types": "tsc --noEmit"
|
"types": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.39.3",
|
||||||
"@laravel/vite-plugin-wayfinder": "^0.1.3",
|
"@laravel/vite-plugin-wayfinder": "^0.1.7",
|
||||||
"@release-it/conventional-changelog": "^10.0.4",
|
"@release-it/conventional-changelog": "^10.0.5",
|
||||||
"@sentry/vite-plugin": "^4.6.1",
|
"@sentry/vite-plugin": "^4.9.1",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.9.1",
|
||||||
"@testing-library/react": "^16.1.0",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@types/json-logic-js": "^2.0.8",
|
"@types/json-logic-js": "^2.0.8",
|
||||||
"@types/node": "^22.13.5",
|
"@types/node": "^22.19.13",
|
||||||
"babel-plugin-react-compiler": "^1.0.0",
|
"babel-plugin-react-compiler": "^1.0.0",
|
||||||
"eslint": "^9.17.0",
|
"eslint": "^9.39.3",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-react": "^7.37.3",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.0",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"jsdom": "^25.0.1",
|
"jsdom": "^25.0.1",
|
||||||
"playwright": "^1.57.0",
|
"playwright": "^1.58.2",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.8.1",
|
||||||
"prettier-plugin-organize-imports": "^4.1.0",
|
"prettier-plugin-organize-imports": "^4.3.0",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||||
"release-it": "^19.2.4",
|
"release-it": "^19.2.4",
|
||||||
"typescript-eslint": "^8.23.0",
|
"typescript-eslint": "^8.56.1",
|
||||||
"vitest": "^2.1.8"
|
"vitest": "^2.1.9"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^2.2.0",
|
"@headlessui/react": "^2.2.9",
|
||||||
"@inertiajs/react": "^2.1.4",
|
"@inertiajs/react": "^2.3.17",
|
||||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-avatar": "^1.1.3",
|
"@radix-ui/react-avatar": "^1.1.11",
|
||||||
"@radix-ui/react-checkbox": "^1.1.4",
|
"@radix-ui/react-checkbox": "^1.3.3",
|
||||||
"@radix-ui/react-collapsible": "^1.1.3",
|
"@radix-ui/react-collapsible": "^1.1.12",
|
||||||
"@radix-ui/react-context-menu": "^2.2.16",
|
"@radix-ui/react-context-menu": "^2.2.16",
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-label": "^2.1.2",
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
"@radix-ui/react-navigation-menu": "^1.2.5",
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
||||||
"@radix-ui/react-popover": "^1.1.15",
|
"@radix-ui/react-popover": "^1.1.15",
|
||||||
"@radix-ui/react-progress": "^1.1.8",
|
"@radix-ui/react-progress": "^1.1.8",
|
||||||
"@radix-ui/react-radio-group": "^1.3.8",
|
"@radix-ui/react-radio-group": "^1.3.8",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-separator": "^1.1.8",
|
"@radix-ui/react-separator": "^1.1.8",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@radix-ui/react-toggle": "^1.1.2",
|
"@radix-ui/react-toggle": "^1.1.10",
|
||||||
"@radix-ui/react-toggle-group": "^1.1.2",
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@sentry/react": "^10.32.1",
|
"@sentry/react": "^10.40.0",
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
"@tailwindcss/vite": "^4.2.1",
|
||||||
"@tanstack/react-table": "^8.21.3",
|
"@tanstack/react-table": "^8.21.3",
|
||||||
"@types/react": "^19.2.0",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.0",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.0.0",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.2.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dexie": "^4.2.1",
|
"dexie": "^4.3.0",
|
||||||
"dexie-react-hooks": "^4.2.0",
|
"dexie-react-hooks": "^4.2.0",
|
||||||
"facehash": "^0.1.0",
|
"facehash": "^0.1.0",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.15.0",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"json-logic-js": "^2.0.5",
|
"json-logic-js": "^2.0.5",
|
||||||
"laravel-vite-plugin": "^2.0",
|
"laravel-vite-plugin": "^2.1.0",
|
||||||
"lucide-react": "^0.553.0",
|
"lucide-react": "^0.553.0",
|
||||||
"motion": "^12.34.3",
|
"motion": "^12.34.3",
|
||||||
"posthog-js": "^1.331.0",
|
"posthog-js": "^1.356.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.4",
|
||||||
"recharts": "^3.5.1",
|
"recharts": "^3.7.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
"tailwind-merge": "^3.0.1",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tailwindcss": "^4.0.0",
|
"tailwindcss": "^4.2.1",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.9.3",
|
||||||
"uuidv7": "^1.0.2",
|
"uuidv7": "^1.1.0",
|
||||||
"vaul": "^1.1.2",
|
"vaul": "^1.1.2",
|
||||||
"vite": "^7.0.4",
|
"vite": "^7.3.1",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.9.5",
|
"@rollup/rollup-linux-x64-gnu": "4.9.5",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.9.5",
|
"@rollup/rollup-win32-x64-msvc": "4.9.5",
|
||||||
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
|
"@tailwindcss/oxide-linux-x64-gnu": "^4.2.1",
|
||||||
"@tailwindcss/oxide-win32-x64-msvc": "^4.0.1",
|
"@tailwindcss/oxide-win32-x64-msvc": "^4.2.1",
|
||||||
"lightningcss-linux-x64-gnu": "^1.29.1",
|
"lightningcss-linux-x64-gnu": "^1.31.1",
|
||||||
"lightningcss-win32-x64-msvc": "^1.29.1"
|
"lightningcss-win32-x64-msvc": "^1.31.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* Patch script to fix ESM/CJS interop issue with string-width in @inquirer/core.
|
||||||
|
*
|
||||||
|
* @inquirer/core bundles wrap-ansi@6 (CJS) which requires string-width@4 (CJS).
|
||||||
|
* However, the top-level string-width is v8 (ESM-only), causing:
|
||||||
|
* ERROR stringWidth is not a function
|
||||||
|
*
|
||||||
|
* This script installs CJS-compatible versions of string-width and its
|
||||||
|
* dependencies into @inquirer/core's nested node_modules after each install.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
import { existsSync, mkdirSync } from 'fs';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
|
||||||
|
const targetDir = resolve(
|
||||||
|
import.meta.dirname,
|
||||||
|
'../node_modules/@inquirer/core/node_modules',
|
||||||
|
);
|
||||||
|
|
||||||
|
const packages = [
|
||||||
|
{ name: 'string-width', version: '4.2.3' },
|
||||||
|
{ name: 'strip-ansi', version: '6.0.1' },
|
||||||
|
{ name: 'ansi-regex', version: '5.0.1' },
|
||||||
|
{ name: 'is-fullwidth-code-point', version: '3.0.0' },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const pkg of packages) {
|
||||||
|
const dest = resolve(targetDir, pkg.name);
|
||||||
|
if (existsSync(dest)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Patching ${pkg.name}@${pkg.version} into @inquirer/core...`);
|
||||||
|
mkdirSync(dest, { recursive: true });
|
||||||
|
|
||||||
|
const tarball = `${pkg.name}-${pkg.version}.tgz`;
|
||||||
|
execSync(`npm pack ${pkg.name}@${pkg.version} --quiet`, {
|
||||||
|
cwd: dest,
|
||||||
|
stdio: 'pipe',
|
||||||
|
});
|
||||||
|
execSync(`tar -xzf ${tarball} --strip-components=1`, {
|
||||||
|
cwd: dest,
|
||||||
|
stdio: 'pipe',
|
||||||
|
});
|
||||||
|
execSync(`rm ${tarball}`, { cwd: dest, stdio: 'pipe' });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Patch applied.');
|
||||||
Loading…
Reference in New Issue