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",
|
||||
"version": "0.1.14",
|
||||
"version": "0.1.15",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "whisper-money",
|
||||
"version": "0.1.14",
|
||||
"version": "0.1.15",
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^2.2.0",
|
||||
"@inertiajs/react": "^2.1.4",
|
||||
|
|
|
|||
103
package.json
103
package.json
|
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "whisper-money",
|
||||
"version": "0.1.14",
|
||||
"version": "0.1.15",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"postinstall": "node scripts/patch-inquirer-string-width.js",
|
||||
"build": "vite build",
|
||||
"build:ssr": "vite build && vite build --ssr",
|
||||
"dev": "vite",
|
||||
|
|
@ -18,89 +19,89 @@
|
|||
"types": "tsc --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.19.0",
|
||||
"@laravel/vite-plugin-wayfinder": "^0.1.3",
|
||||
"@release-it/conventional-changelog": "^10.0.4",
|
||||
"@sentry/vite-plugin": "^4.6.1",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.1.0",
|
||||
"@eslint/js": "^9.39.3",
|
||||
"@laravel/vite-plugin-wayfinder": "^0.1.7",
|
||||
"@release-it/conventional-changelog": "^10.0.5",
|
||||
"@sentry/vite-plugin": "^4.9.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/json-logic-js": "^2.0.8",
|
||||
"@types/node": "^22.13.5",
|
||||
"@types/node": "^22.19.13",
|
||||
"babel-plugin-react-compiler": "^1.0.0",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-react": "^7.37.3",
|
||||
"eslint-plugin-react-hooks": "^7.0.0",
|
||||
"eslint": "^9.39.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"jsdom": "^25.0.1",
|
||||
"playwright": "^1.57.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"playwright": "^1.58.2",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-organize-imports": "^4.3.0",
|
||||
"prettier-plugin-tailwindcss": "^0.6.14",
|
||||
"release-it": "^19.2.4",
|
||||
"typescript-eslint": "^8.23.0",
|
||||
"vitest": "^2.1.8"
|
||||
"typescript-eslint": "^8.56.1",
|
||||
"vitest": "^2.1.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^2.2.0",
|
||||
"@inertiajs/react": "^2.1.4",
|
||||
"@headlessui/react": "^2.2.9",
|
||||
"@inertiajs/react": "^2.3.17",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-avatar": "^1.1.3",
|
||||
"@radix-ui/react-checkbox": "^1.1.4",
|
||||
"@radix-ui/react-collapsible": "^1.1.3",
|
||||
"@radix-ui/react-avatar": "^1.1.11",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-context-menu": "^2.2.16",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.14",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-progress": "^1.1.8",
|
||||
"@radix-ui/react-radio-group": "^1.3.8",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-toggle": "^1.1.2",
|
||||
"@radix-ui/react-toggle-group": "^1.1.2",
|
||||
"@radix-ui/react-tooltip": "^1.1.8",
|
||||
"@sentry/react": "^10.32.1",
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@radix-ui/react-toggle": "^1.1.10",
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@sentry/react": "^10.40.0",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@types/react": "^19.2.0",
|
||||
"@types/react-dom": "^19.2.0",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"concurrently": "^9.0.1",
|
||||
"concurrently": "^9.2.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"dexie": "^4.2.1",
|
||||
"dexie": "^4.3.0",
|
||||
"dexie-react-hooks": "^4.2.0",
|
||||
"facehash": "^0.1.0",
|
||||
"globals": "^15.14.0",
|
||||
"globals": "^15.15.0",
|
||||
"input-otp": "^1.4.2",
|
||||
"json-logic-js": "^2.0.5",
|
||||
"laravel-vite-plugin": "^2.0",
|
||||
"laravel-vite-plugin": "^2.1.0",
|
||||
"lucide-react": "^0.553.0",
|
||||
"motion": "^12.34.3",
|
||||
"posthog-js": "^1.331.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"recharts": "^3.5.1",
|
||||
"posthog-js": "^1.356.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"recharts": "^3.7.0",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.0.1",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.7.2",
|
||||
"uuidv7": "^1.0.2",
|
||||
"typescript": "^5.9.3",
|
||||
"uuidv7": "^1.1.0",
|
||||
"vaul": "^1.1.2",
|
||||
"vite": "^7.0.4",
|
||||
"vite": "^7.3.1",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-linux-x64-gnu": "4.9.5",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.9.5",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "^4.0.1",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "^4.0.1",
|
||||
"lightningcss-linux-x64-gnu": "^1.29.1",
|
||||
"lightningcss-win32-x64-msvc": "^1.29.1"
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "^4.2.1",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "^4.2.1",
|
||||
"lightningcss-linux-x64-gnu": "^1.31.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