diff --git a/package.json b/package.json index 10af96bd..627af23f 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,11 @@ "build:cjs": "npx tsc -p tsconfig.cjs.json", "build:esm": "npx tsc -p tsconfig.esm.json", "build:fix-esm": "node scripts/fix-esm-imports.cjs", + "build:fix-dts": "node scripts/fix-dts-imports.cjs", "build:post": "echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json", - "build": "npm-run-all clean build:cjs build:esm build:fix-esm build:post", - "integrity-checks": "npm-run-all clean format-check lint-check test build", + "build": "npm-run-all clean build:cjs build:esm build:fix-esm build:fix-dts build:post", + "attw": "npx @arethetypeswrong/cli --pack --ignore-rules fallback-condition false-esm", + "integrity-checks": "npm-run-all clean format-check lint-check test build attw", "prepublishOnly": "npm run integrity-checks", "prepare": "npm run build" }, diff --git a/scripts/fix-dts-imports.cjs b/scripts/fix-dts-imports.cjs new file mode 100644 index 00000000..2de161d6 --- /dev/null +++ b/scripts/fix-dts-imports.cjs @@ -0,0 +1,125 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +/** + * Post-build script to fix TypeScript declaration file imports by adding .js extensions. + * This is required because when package.json has "type": "module", TypeScript treats + * .d.ts files as ESM modules, which require explicit file extensions for relative imports. + */ + +const TYPES_DIR = path.join(__dirname, '../dist/types'); + +function fixImportsInFile(filePath) { + let content = fs.readFileSync(filePath, 'utf8'); + let modified = false; + + // Fix relative imports - add .js extension if missing + content = content.replace( + /from\s+['"](\.[^'"]*?)['"];?/g, + (match, importPath) => { + // Skip if already has extension or is directory import + if (path.extname(importPath) || importPath.endsWith('/')) { + return match; + } + + // Check if this is a directory import (look for index file) + const fullPath = path.resolve(path.dirname(filePath), importPath); + const indexPath = path.join(fullPath, 'index.d.ts'); + + if (fs.existsSync(indexPath)) { + // Directory import - add /index.js + modified = true; + return match.replace(importPath, importPath + '/index.js'); + } else { + // File import - add .js + modified = true; + return match.replace(importPath, importPath + '.js'); + } + } + ); + + // Fix export statements as well + content = content.replace( + /export\s+(?:\*|\{[^}]*\})\s+from\s+['"](\.[^'"]*?)['"];?/g, + (match, importPath) => { + // Skip if already has extension or is directory import + if (path.extname(importPath) || importPath.endsWith('/')) { + return match; + } + + // Check if this is a directory import (look for index file) + const fullPath = path.resolve(path.dirname(filePath), importPath); + const indexPath = path.join(fullPath, 'index.d.ts'); + + if (fs.existsSync(indexPath)) { + // Directory import - add /index.js + modified = true; + return match.replace(importPath, importPath + '/index.js'); + } else { + // File import - add .js + modified = true; + return match.replace(importPath, importPath + '.js'); + } + } + ); + + // Fix dynamic import() type expressions + content = content.replace( + /import\(['"](\.[^'"]*?)['"]\)/g, + (match, importPath) => { + // Skip if already has extension or is directory import + if (path.extname(importPath) || importPath.endsWith('/')) { + return match; + } + + // Check if this is a directory import (look for index file) + const fullPath = path.resolve(path.dirname(filePath), importPath); + const indexPath = path.join(fullPath, 'index.d.ts'); + + if (fs.existsSync(indexPath)) { + // Directory import - add /index.js + modified = true; + return match.replace(importPath, importPath + '/index.js'); + } else { + // File import - add .js + modified = true; + return match.replace(importPath, importPath + '.js'); + } + } + ); + + if (modified) { + fs.writeFileSync(filePath, content, 'utf8'); + console.log(`Fixed imports in: ${path.relative(process.cwd(), filePath)}`); + } +} + +function walkDirectory(dir) { + const files = fs.readdirSync(dir); + + for (const file of files) { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + + if (stat.isDirectory()) { + walkDirectory(filePath); + } else if (file.endsWith('.d.ts')) { + fixImportsInFile(filePath); + } + } +} + +function main() { + if (!fs.existsSync(TYPES_DIR)) { + console.log('Types directory does not exist, skipping declaration file fixing'); + return; + } + + console.log('Fixing TypeScript declaration file imports by adding .js extensions...'); + walkDirectory(TYPES_DIR); + console.log('Declaration file import fixing completed'); +} + +main();