UNPKG

@spaced-out/ui-design-system

Version:
108 lines (93 loc) 4.21 kB
/** * Note(Nishant): This script is part of our long-term migration and type safety strategy. * * Context: * Our codebase has historically used Flow for type checking. Flow offers strong static typing, * but has limited ecosystem support compared to TypeScript. Since the TypeScript ecosystem * (including editors like VSCode, IDE integrations, and npm consumers) natively expects `.d.ts` * files for type definitions, we need to bridge that gap. * * Purpose of this script: * 1. It converts `.js.flow` files (Flow declaration files) in our `lib/` directory to * corresponding `.d.ts` files using `flow-to-ts`. * 2. The output `.d.ts` files provide equivalent type declarations in TypeScript syntax. * 3. We format these generated files using `prettier` to ensure consistent and readable output. * * Why `.d.ts` files matter: * - TypeScript consumers of our NPM package (like internal projects or external partners) * rely on `.d.ts` files to get autocompletion, compile-time checking, and rich IDE support. * - They serve as the public API contract of our component library. * - Without `.d.ts` files, consumers would have to fall back to `any` or custom typings, * defeating the purpose of having a typed library. * * Why not just migrate to TS directly? * - A full migration to TS is non-trivial and requires coordination across all teams. * - In the interim, this approach gives us compatibility with the TypeScript ecosystem * without dropping Flow support. * * How it works: * - We locate all `.js.flow` files under `lib/` * - Each file is passed through `flow-to-ts` with `-o d.ts` to get a `.d.ts` representation. * - We write the output next to the original file. * - The result is then formatted using Prettier. * * This script is invoked as part of the build pipeline, and must run **after** the Gulp build step. * Do not remove or bypass this logic — breaking `.d.ts` generation will break downstream consumers. * * Future: * - Once we fully migrate to TypeScript, this step can be replaced by native `.d.ts` generation * via `tsc` or Babel. */ const fs = require('fs'); const path = require('path'); const glob = require('glob'); const {spawnSync} = require('child_process'); const files = glob.sync(path.resolve(__dirname, '../lib/**/*.js.flow')); // eslint-disable-next-line no-console console.log('🔄 Converting .js.flow files to TypeScript declaration files...'); files.forEach((file) => { const outPath = file.replace(/\.js\.flow$/, '.d.ts'); const flowToTs = path.resolve(__dirname, './node_modules/.bin/flow-to-ts'); // Note(Nishant) For some reason if i try to install prettier locally it fails for few components. Not // spending too much time on it because the idea here is to move to ts eventually const prettier = path.resolve(__dirname, '../node_modules/.bin/prettier'); const result = spawnSync(flowToTs, ['-o', 'd.ts', file], { encoding: 'utf-8', // Note(Nishant): Tells Node.js to run the command inside a shell, like bash or sh. // essential for calling binaries via relative paths (e.g., from node_modules/.bin/) shell: true, }); const stdout = result.stdout?.trim(); const stderr = result.stderr?.trim(); if (result.error) { console.error(`Spawn error converting ${file}:`, result.error.message); return; } if (stderr) { console.error(`stderr converting ${file}:\n${stderr}`); return; } if (result.status !== 0) { console.error(`Non-zero exit code for ${file}`); return; } if (stdout && !stdout.includes('Processing') && !stdout.includes('Results')) { fs.writeFileSync(outPath, stdout); // eslint-disable-next-line no-console console.log(`✅ Converted: ${file}${outPath}`); // Format with Prettier const fmt = spawnSync(prettier, ['--write', outPath], { encoding: 'utf-8', shell: true, }); if (fmt.status !== 0) { console.error(`Prettier formatting failed for ${outPath}`); } } else { console.warn( `⚠️ No meaningful output for ${file}. It may be empty or skipped.`, ); } }); // eslint-disable-next-line no-console console.log(`✅ Flow to d.ts Job Finished`);