#!/usr/bin/env node // Force CommonJS mode // @ts-nocheck // Comprehensive build validation for Angular SDK const fs = require('fs'); const path = require('path'); console.log('šŸ” Validating Angular SDK Build...\n'); const distPath = path.join(__dirname, '../../dist/qrcode-angular'); const packageJson = JSON.parse(fs.readFileSync(path.join(distPath, 'package.json'), 'utf8')); // Test 1: Build artifacts exist const requiredFiles = [ 'index.d.ts', 'public-api.d.ts', 'package.json', 'README.md', 'fesm2022/selfxyz-qrcode-angular.mjs', 'fesm2022/selfxyz-qrcode-angular.mjs.map', 'esm2022/selfxyz-qrcode-angular.mjs', 'lib/components/self-qrcode/self-qrcode.component.d.ts', 'lib/components/led/led.component.d.ts', 'lib/services/websocket.service.d.ts' ]; console.log('šŸ“ Checking build artifacts...'); let missingFiles = []; for (const file of requiredFiles) { const filePath = path.join(distPath, file); if (fs.existsSync(filePath)) { console.log(` āœ… ${file}`); } else { console.log(` āŒ ${file} (MISSING)`); missingFiles.push(file); } } if (missingFiles.length > 0) { console.log(`\nāŒ Missing ${missingFiles.length} required files!`); process.exit(1); } // Test 2: Package.json validation console.log('\nšŸ“¦ Validating package.json...'); const requiredFields = ['name', 'version', 'main', 'module', 'types', 'exports', 'peerDependencies']; for (const field of requiredFields) { if (packageJson[field]) { console.log(` āœ… ${field}: ${typeof packageJson[field] === 'object' ? 'configured' : packageJson[field]}`); } else { console.log(` āŒ ${field}: missing`); process.exit(1); } } // Test 3: Exports validation console.log('\nšŸš€ Validating exports...'); const pkgExports = packageJson.exports; if (pkgExports && pkgExports['.']) { const mainExport = pkgExports['.']; console.log(` āœ… Main export types: ${mainExport.types}`); console.log(` āœ… Main export default: ${mainExport.default}`); console.log(` āœ… ESM2022 export: ${mainExport.esm2022}`); } else { console.log(' āŒ Main export missing'); process.exit(1); } // Test 4: Bundle size validation console.log('\nšŸ“Š Checking bundle sizes...'); const mainBundle = path.join(distPath, 'fesm2022/selfxyz-qrcode-angular.mjs'); const bundleStats = fs.statSync(mainBundle); const bundleSizeKB = bundleStats.size / 1024; console.log(` šŸ“¦ Main bundle: ${bundleSizeKB.toFixed(2)}KB`); if (bundleSizeKB > 100) { console.log(' āš ļø Bundle size is quite large (>100KB)'); } else { console.log(' āœ… Bundle size is reasonable'); } // Test 5: TypeScript definitions validation console.log('\nšŸ”§ Validating TypeScript definitions...'); const indexDts = fs.readFileSync(path.join(distPath, 'index.d.ts'), 'utf8'); const publicApiDts = fs.readFileSync(path.join(distPath, 'public-api.d.ts'), 'utf8'); if (indexDts.includes('export * from \'./public-api\'')) { console.log(' āœ… Index.d.ts exports public API'); } else { console.log(' āŒ Index.d.ts missing public API export'); process.exit(1); } const requiredExports = [ 'SelfQRcodeComponent', 'SelfQRcodeWrapperComponent', 'LedComponent', 'WebSocketService', 'SelfQRcodeAngularModule' ]; let missingExports = []; for (const exportName of requiredExports) { if (publicApiDts.includes(exportName)) { console.log(` āœ… ${exportName} exported`); } else { console.log(` āŒ ${exportName} missing from exports`); missingExports.push(exportName); } } if (missingExports.length > 0) { console.log(`\nāŒ Missing ${missingExports.length} required exports!`); process.exit(1); } // Test 6: Bundle content validation console.log('\nšŸ” Validating bundle content...'); const bundleContent = fs.readFileSync(mainBundle, 'utf8'); const requiredImports = [ '@angular/core', '@angular/common', 'angularx-qrcode', 'rxjs', 'socket.io-client', '@selfxyz/common' ]; for (const importName of requiredImports) { if (bundleContent.includes(importName)) { console.log(` āœ… ${importName} imported`); } else { console.log(` āŒ ${importName} missing from bundle`); process.exit(1); } } // Test 7: Peer dependencies validation console.log('\nšŸ”— Validating peer dependencies...'); const peerDeps = packageJson.peerDependencies; const expectedPeerDeps = { '@angular/core': '^18.0.0', '@angular/common': '^18.0.0', '@selfxyz/common': 'workspace:^', 'rxjs': '^7.8.0' }; for (const [dep, version] of Object.entries(expectedPeerDeps)) { if (peerDeps[dep] === version) { console.log(` āœ… ${dep}: ${version}`); } else { console.log(` āŒ ${dep}: expected ${version}, got ${peerDeps[dep] || 'missing'}`); process.exit(1); } } console.log('\nšŸŽ‰ All validations passed!'); console.log('\nšŸ“‹ Build Summary:'); console.log(` šŸ“¦ Package: ${packageJson.name}@${packageJson.version}`); console.log(` šŸ“ Output: ${distPath}`); console.log(` šŸ“Š Bundle size: ${bundleSizeKB.toFixed(2)}KB`); console.log(` šŸ”§ TypeScript: Full definitions included`); console.log(` šŸš€ Exports: Properly configured`); console.log(` šŸ”— Dependencies: ${Object.keys(packageJson.dependencies || {}).length} runtime, ${Object.keys(peerDeps).length} peer`); console.log('\nāœ… Angular SDK is ready for distribution!');