From 5d77a33c38272989e494ffdcb733530b01133a7d Mon Sep 17 00:00:00 2001 From: plebeius Date: Sun, 8 Mar 2026 19:28:03 +0800 Subject: [PATCH] fix: patch bitsocial-react-hooks esm imports on install Add a `postinstall` repair step for the git-based `@bitsocialhq/bitsocial-react-hooks` package so test and build environments stop tripping over extensionless relative imports in dist. This keeps GitHub Actions aligned with local installs without changing app logic. --- package.json | 2 +- scripts/patch-bitsocial-react-hooks-esm.cjs | 97 +++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 scripts/patch-bitsocial-react-hooks-esm.cjs diff --git a/package.json b/package.json index 4df7fea7..533c588c 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "scripts": { "generate:assets": "node scripts/generate-asset-manifest.js", "sync:directories": "node scripts/sync-directories.js", - "postinstall": "node scripts/patch-capacitor-cli-tar.cjs", + "postinstall": "node scripts/patch-capacitor-cli-tar.cjs && node scripts/patch-bitsocial-react-hooks-esm.cjs", "prebuild": "yarn sync:directories && yarn generate:assets", "prestart": "yarn sync:directories && yarn generate:assets", "start": "node scripts/start-dev.js", diff --git a/scripts/patch-bitsocial-react-hooks-esm.cjs b/scripts/patch-bitsocial-react-hooks-esm.cjs new file mode 100644 index 00000000..f7079e61 --- /dev/null +++ b/scripts/patch-bitsocial-react-hooks-esm.cjs @@ -0,0 +1,97 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const packageDistPath = path.join(__dirname, '..', 'node_modules', '@bitsocialhq', 'bitsocial-react-hooks', 'dist'); +const logPrefix = '[patch-bitsocial-react-hooks-esm]'; + +if (!fs.existsSync(packageDistPath)) { + console.log(`${logPrefix} Skip: @bitsocialhq/bitsocial-react-hooks dist not found.`); + process.exit(0); +} + +const relativeImportPattern = /(from\s+|import\s+)(['"])(\.\.?\/[^'"]+)\2/g; +let touchedFiles = 0; +let rewrittenImports = 0; + +const splitSpecifier = (specifier) => { + const suffixStart = specifier.search(/[?#]/); + + if (suffixStart === -1) { + return { bareSpecifier: specifier, suffix: '' }; + } + + return { + bareSpecifier: specifier.slice(0, suffixStart), + suffix: specifier.slice(suffixStart), + }; +}; + +const resolveSpecifier = (filePath, specifier) => { + const { bareSpecifier, suffix } = splitSpecifier(specifier); + + if (path.extname(bareSpecifier)) { + return null; + } + + const absoluteSpecifierPath = path.resolve(path.dirname(filePath), bareSpecifier); + + if (fs.existsSync(`${absoluteSpecifierPath}.js`)) { + return `${bareSpecifier}.js${suffix}`; + } + + if (fs.existsSync(path.join(absoluteSpecifierPath, 'index.js'))) { + return `${bareSpecifier}/index.js${suffix}`; + } + + return null; +}; + +const patchFile = (filePath) => { + const source = fs.readFileSync(filePath, 'utf8'); + let fileImportCount = 0; + + const updated = source.replace(relativeImportPattern, (match, prefix, quote, specifier) => { + const resolvedSpecifier = resolveSpecifier(filePath, specifier); + + if (!resolvedSpecifier || resolvedSpecifier === specifier) { + return match; + } + + fileImportCount += 1; + return `${prefix}${quote}${resolvedSpecifier}${quote}`; + }); + + if (!fileImportCount) { + return; + } + + fs.writeFileSync(filePath, updated, 'utf8'); + touchedFiles += 1; + rewrittenImports += fileImportCount; +}; + +const walk = (currentPath) => { + for (const entry of fs.readdirSync(currentPath, { withFileTypes: true })) { + const entryPath = path.join(currentPath, entry.name); + + if (entry.isDirectory()) { + walk(entryPath); + continue; + } + + if (entry.isFile() && entry.name.endsWith('.js')) { + patchFile(entryPath); + } + } +}; + +walk(packageDistPath); + +if (!touchedFiles) { + console.log(`${logPrefix} No relative ESM imports needed patching.`); + process.exit(0); +} + +console.log(`${logPrefix} Patched ${rewrittenImports} imports across ${touchedFiles} files.`);