import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { packages } from '../workspace-packages.mjs'; import merge from 'deepmerge'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const TSCONFIG_COMMENT = `// Don't edit this file directly. It is generated by /scripts/update-package-configs.ts\n\n`; const packagesRoot = path.join(__dirname, '..', 'packages'); const packageJSONMap = new Map(); const packageDirnameMap = new Map(); const internalDependencyMap = new Map(); // collect package json for all packages packages.forEach(pkg => { const packageJSONPath = path.join(packagesRoot, pkg.name, 'package.json'); if (!fs.existsSync(packageJSONPath)) { console.error(); console.error(`Could not find package.json: ${packageJSONPath}`); console.error(); process.exit(1); } const packageJSONData = JSON.parse(fs.readFileSync(packageJSONPath).toString()); const packageName = packageJSONData.name; packageDirnameMap.set(packageName, pkg.name); packageJSONMap.set(packageName, packageJSONData); }); // collect initial cross package dependencies info packageDirnameMap.forEach((_packageDirname, packageName) => { const { dependencies, devDependencies } = packageJSONMap.get(packageName); const internalDependencies = [ ...(dependencies ? Object.keys(dependencies) : []), ...(devDependencies ? Object.keys(devDependencies) : []), ].filter(dep => packageDirnameMap.has(dep)); internalDependencyMap.set(packageName, internalDependencies); }); function resolveInternalDependencies(dependencies) { const childDeps = []; for (const idep of dependencies) { const deps = internalDependencyMap.get(idep); const res = resolveInternalDependencies(deps); for (const jdep of res) { childDeps.push(jdep); } } const resolved = childDeps.concat(dependencies); // remove all duplicated after the first appearance return resolved.filter((item, idx) => resolved.indexOf(item) === idx); } packageDirnameMap.forEach((packageDirname, packageName) => { const pkg = packages.find(pkg => pkg.name === packageDirname); const pkgDir = path.join(packagesRoot, packageDirname); const tsconfigPath = path.join(pkgDir, 'tsconfig.json'); let tsConfigOverride = {}; const tsConfigOverridePath = path.join(pkgDir, 'tsconfig.override.json'); if (fs.existsSync(tsConfigOverridePath)) { tsConfigOverride = JSON.parse(fs.readFileSync(tsConfigOverridePath)); } const overwriteMerge = (destinationArray, sourceArray) => sourceArray; const internalDependencies = resolveInternalDependencies(internalDependencyMap.get(packageName)); const tsconfigData = merge( { extends: `../../tsconfig.${pkg.environment === 'browser' ? 'browser' : 'node'}-base.json`, compilerOptions: { module: pkg.environment === 'browser' ? 'ESNext' : 'commonjs', outDir: './types', rootDir: '.', composite: true, allowJs: true, strict: pkg.strict, checkJs: pkg.type === 'js' ? true : undefined, emitDeclarationOnly: pkg.type === 'js' ? true : undefined, }, references: internalDependencies.map(dep => { return { path: `../${packageDirnameMap.get(dep)}/tsconfig.json` }; }), include: ['src', '*.js'], exclude: ['dist', 'types'], }, tsConfigOverride, { arrayMerge: overwriteMerge }, ); fs.writeFileSync(tsconfigPath, TSCONFIG_COMMENT + JSON.stringify(tsconfigData, null, ' ')); }); const projectLevelTsconfigPath = path.join(__dirname, '..', 'tsconfig.json'); const projectLevelTsconfigData = { extends: './tsconfig.node-base.json', files: [], references: resolveInternalDependencies(Array.from(packageDirnameMap.keys())).map( packageName => ({ path: `./packages/${packageDirnameMap.get(packageName)}/tsconfig.json`, }), ), }; fs.writeFileSync( projectLevelTsconfigPath, TSCONFIG_COMMENT + JSON.stringify(projectLevelTsconfigData, null, ' '), );