@spaced-out/ui-design-system
Version:
Sense UI components library
108 lines (93 loc) • 4.21 kB
JavaScript
/**
* 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`);