const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); const rimraf = require('rimraf'); // Get all items in src directory const srcDir = path.join(__dirname, '..', 'src'); const srcItems = fs.readdirSync(srcDir); // Create dist directory if it doesn't exist const distDir = path.join(__dirname, '..', 'dist'); if (!fs.existsSync(distDir)) { fs.mkdirSync(distDir, { recursive: true }); } // Clean up any previous temporary directories const tempDir = path.join(__dirname, '..', 'temp_modules'); if (fs.existsSync(tempDir)) { rimraf.sync(tempDir); } // Create temporary directory fs.mkdirSync(tempDir, { recursive: true }); console.log('Building main package...'); execSync('npm run build', { stdio: 'inherit' }); // Process each item in src directory srcItems.forEach(item => { const itemPath = path.join(srcDir, item); // If it's a directory (like utils), pack the whole directory as a module if (fs.statSync(itemPath).isDirectory() ) { // && item !== 'utils' // Special case: if the directory is 'utils', we'll handle individual files inside it later packDirectory(item, itemPath); } }); // Process individual files in utils directory const utilsDir = path.join(__dirname, '..', 'src', 'utils'); if (fs.existsSync(utilsDir)) { const utilsFiles = fs.readdirSync(utilsDir); utilsFiles.forEach(file => { if (file.endsWith('.js') && file !== 'index.js') { packIndividualFile(file, 'utils', utilsDir); } }); } // // Process each individual file in src directory (not in subdirectories) // const srcDir = path.join(__dirname, '..', 'src'); // const srcFiles = fs.readdirSync(srcDir).filter(file => { // const filePath = path.join(srcDir, file); // return fs.statSync(filePath).isFile() && file.endsWith('.js') && file !== 'index.js'; // }); // srcFiles.forEach(file => { // if (file.endsWith('.js')) { // packIndividualFile(file, 'src', srcDir); // } // }); // Function to pack an entire directory as a module function packDirectory(dirName, dirPath) { const moduleDir = path.join(tempDir, dirName); // Create module-specific directory fs.mkdirSync(moduleDir, { recursive: true }); // Create a module-specific package.json const packageJson = { name: `@haina/${dirName}`, version: require('../package.json').version, description: `Haina ${dirName} module - part of @haina/npm utility library`, main: `build/cjs/${dirName}/index.js`, // Assuming there's an index.js in the directory module: `build/esm/${dirName}/index.js`, type: 'module', files: [ "build" ], scripts: { postinstall: "node -e \"console.log('This is a sub-module of @haina/npm. For full documentation, see https://github.com/hainatravel-it/hai-npm.git')\"" } }; fs.writeFileSync( path.join(moduleDir, 'package.json'), JSON.stringify(packageJson, null, 2) ); // Copy README if exists const readmePath = path.join(__dirname, '..', 'README.MD'); if (fs.existsSync(readmePath)) { const readmeContent = fs.readFileSync(readmePath, 'utf8'); // Add module-specific information to README const moduleReadmeContent = `# @haina/${dirName}\n\n${readmeContent}\n\n## Note\n\nThis is a standalone module from the \`@haina/npm\` package. \n\nFor more information about the full package, visit the [original repository](https://github.com/hainatravel-it/hai-npm.git).\n`; fs.writeFileSync(path.join(moduleDir, 'README.MD'), moduleReadmeContent); } // Create build directories and copy built files const moduleBuildDir = path.join(moduleDir, 'build'); fs.mkdirSync(moduleBuildDir, { recursive: true }); // Copy the built ESM and CJS versions of the directory const esmSrcDir = path.join(__dirname, '..', 'build', 'esm', dirName); const cjsSrcDir = path.join(__dirname, '..', 'build', 'cjs', dirName); const esmDestDir = path.join(moduleBuildDir, 'esm', dirName); const cjsDestDir = path.join(moduleBuildDir, 'cjs', dirName); // Only copy if source directories exist if (fs.existsSync(esmSrcDir)) { copyDir(esmSrcDir, esmDestDir); } if (fs.existsSync(cjsSrcDir)) { copyDir(cjsSrcDir, cjsDestDir); } // Run npm pack in the module directory console.log(`Packing directory module: ${dirName}`); const result = execSync(`cd "${moduleDir}" && npm pack`, { encoding: 'utf8' }); console.log(result); // Move the resulting .tgz file to the main dist directory const tgzFiles = fs.readdirSync(moduleDir).filter(f => f.endsWith('.tgz')); tgzFiles.forEach(tgzFile => { const srcPath = path.join(moduleDir, tgzFile); const destPath = path.join(distDir, `${dirName}-${require('../package.json').version.replace(/v/, '')}.tgz`); fs.renameSync(srcPath, destPath); console.log(`Created: ${path.basename(destPath)}`); }); } // Function to pack an individual file as a module function packIndividualFile(fileName, parentDir, parentPath) { const moduleName = path.basename(fileName, '.js'); const moduleDir = path.join(tempDir, moduleName); // Create module-specific directory fs.mkdirSync(moduleDir, { recursive: true }); // Create a module-specific package.json const packageJson = { name: `@haina/${parentDir}-${moduleName}`, version: require('../package.json').version, description: `Haina ${parentDir}-${moduleName} module - part of @haina/npm utility library`, main: parentDir === 'src' ? `build/cjs/${fileName}` : `build/cjs/${parentDir}/${fileName}`, module: parentDir === 'src' ? `build/esm/${fileName}` : `build/esm/${parentDir}/${fileName}`, type: 'module', files: [ "build" ], scripts: { postinstall: "node -e \"console.log('This is a sub-module of @haina/npm. For full documentation, see https://github.com/hainatravel-it/hai-npm.git')\"" } }; fs.writeFileSync( path.join(moduleDir, 'package.json'), JSON.stringify(packageJson, null, 2) ); // Copy README if exists const readmePath = path.join(__dirname, '..', 'README.MD'); if (fs.existsSync(readmePath)) { const readmeContent = fs.readFileSync(readmePath, 'utf8'); // Add module-specific information to README const moduleReadmeContent = `# @haina/${parentDir}-${moduleName}\n\n${readmeContent}\n\n## Note\n\nThis is a standalone module from the \`@haina/npm\` package. \n\nFor more information about the full package, visit the [original repository](https://github.com/hainatravel-it/hai-npm.git).\n`; fs.writeFileSync(path.join(moduleDir, 'README.MD'), moduleReadmeContent); } // Create build directories and copy built files const moduleBuildDir = path.join(moduleDir, 'build'); fs.mkdirSync(moduleBuildDir, { recursive: true }); // Copy the built ESM and CJS versions of the module const esmSrcDir = parentDir === 'src' ? path.join(__dirname, '..', 'build', 'esm') : path.join(__dirname, '..', 'build', 'esm', parentDir); const cjsSrcDir = parentDir === 'src' ? path.join(__dirname, '..', 'build', 'cjs') : path.join(__dirname, '..', 'build', 'cjs', parentDir); const esmDestDir = parentDir === 'src' ? path.join(moduleBuildDir, 'esm') : path.join(moduleBuildDir, 'esm', parentDir); const cjsDestDir = parentDir === 'src' ? path.join(moduleBuildDir, 'cjs') : path.join(moduleBuildDir, 'cjs', parentDir); fs.mkdirSync(esmDestDir, { recursive: true }); fs.mkdirSync(cjsDestDir, { recursive: true }); // Copy the specific module file const srcFile = fileName; if (fs.existsSync(path.join(esmSrcDir, srcFile))) { fs.copyFileSync( path.join(esmSrcDir, srcFile), path.join(esmDestDir, srcFile) ); } if (fs.existsSync(path.join(cjsSrcDir, srcFile))) { fs.copyFileSync( path.join(cjsSrcDir, srcFile), path.join(cjsDestDir, srcFile) ); } // Run npm pack in the module directory console.log(`Packing individual file module: ${parentDir}.${moduleName}`); const result = execSync(`cd "${moduleDir}" && npm pack`, { encoding: 'utf8' }); console.log(result); // Move the resulting .tgz file to the main dist directory const tgzFiles = fs.readdirSync(moduleDir).filter(f => f.endsWith('.tgz')); tgzFiles.forEach(tgzFile => { const srcPath = path.join(moduleDir, tgzFile); const destPath = path.join(distDir, `${parentDir}-${moduleName}-${require('../package.json').version.replace(/v/, '')}.tgz`); fs.renameSync(srcPath, destPath); console.log(`Created: ${path.basename(destPath)}`); }); } // Helper function to copy directory recursively function copyDir(src, dest) { fs.mkdirSync(dest, { recursive: true }); const items = fs.readdirSync(src); items.forEach(item => { const srcPath = path.join(src, item); const destPath = path.join(dest, item); if (fs.statSync(srcPath).isDirectory()) { copyDir(srcPath, destPath); } else { fs.copyFileSync(srcPath, destPath); } }); } // Clean up temporary directory rimraf.sync(tempDir); console.log('Module packing completed!');