123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #!/usr/bin/env node
- import { EMPTY_OBJECT, arrayFromAsync, parallelForEach, pojo } from '@sequelize/utils';
- import { listDirectories, listFilesRecursive, readFileIfExists } from '@sequelize/utils/node';
- import isEqual from 'lodash/isEqual.js';
- import fs from 'node:fs/promises';
- import path from 'node:path';
- /**
- * does not modify the contents of the file but exits with code 1 if outdated, 0 if not
- */
- const checkOutdated = process.argv.includes('--check-outdated');
- /**
- * The package contains multiple individual exports that each need their own index file
- */
- const multipleEntryPoints = process.argv.includes('--multi-entry-points');
- const requestedSrcDir = process.argv[2];
- if (!requestedSrcDir) {
- console.error('Please provide the path to the src folder to synchronize');
- }
- const srcDir = path.normalize(path.join(process.cwd(), requestedSrcDir));
- console.info(
- `${checkOutdated ? 'Testing synchronization of' : 'Synchronizing'} exports of folder ${srcDir}`,
- );
- const folders = multipleEntryPoints
- ? (await listDirectories(srcDir)).map(folder => path.join(srcDir, folder))
- : [srcDir];
- const outdatedPaths = [];
- await parallelForEach(folders, async folder => {
- const files = await arrayFromAsync(listFilesRecursive(folder));
- const commonExports = [];
- /**
- * You can provide a browser-specific or node-specific implementation by adding ".browser" or ".node" to their filename
- */
- const browserExportOverrides = pojo();
- const nodeExportOverrides = pojo();
- files
- .map(file => {
- return path.relative(folder, file).replace(/\.ts$/, '.js');
- })
- .filter(pathname => {
- return (
- !/(^|\\)index\./.test(pathname) &&
- !pathname.startsWith('.DS_Store') &&
- !pathname.endsWith('.spec.js') &&
- !pathname.endsWith('.test.js') &&
- !pathname.includes('__tests__/') &&
- !pathname.includes('_internal/') &&
- !pathname.includes('.internal') &&
- !pathname.endsWith('.d.js')
- );
- })
- // eslint-disable-next-line unicorn/no-array-for-each -- clearer like this, perf doesn't matter
- .forEach(pathname => {
- if (pathname.includes('.node.')) {
- nodeExportOverrides[pathname.replace('.node.', '.')] = pathname;
- } else if (pathname.includes('.browser.')) {
- browserExportOverrides[pathname.replace('.browser.', '.')] = pathname;
- } else {
- commonExports.push(pathname);
- }
- });
- const baseExports = getExportsWithOverrides(commonExports, EMPTY_OBJECT);
- const browserExports = getExportsWithOverrides(commonExports, browserExportOverrides);
- const nodeExports = getExportsWithOverrides(commonExports, nodeExportOverrides);
- const promises = [];
- promises.push(outputExports(baseExports, path.join(folder, 'index.ts')));
- if (!isEqual(browserExports, baseExports)) {
- promises.push(outputExports(browserExports, path.join(folder, 'index.browser.ts')));
- }
- if (!isEqual(nodeExports, baseExports)) {
- promises.push(outputExports(nodeExports, path.join(folder, 'index.node.ts')));
- }
- await Promise.all(promises);
- });
- async function outputExports(exports, indexPath) {
- const imports = exports
- .map(pathname => {
- return `export * from './${pathname}';\n`;
- })
- .sort()
- .join('');
- const fileContents = `/** Generated File, do not modify directly. Run "yarn sync-exports" in the folder of the package instead */\n\n${imports}`;
- const file = await readFileIfExists(indexPath, 'utf-8');
- if (file === null || file !== fileContents) {
- outdatedPaths.push(indexPath);
- }
- if (!checkOutdated) {
- await fs.writeFile(indexPath, fileContents, 'utf-8');
- }
- }
- function getExportsWithOverrides(commonExports, platformExportOverrides) {
- const platformExportKeys = Object.keys(platformExportOverrides);
- if (platformExportKeys.length === 0) {
- return commonExports;
- }
- const platformExports = [];
- /** Add exports that were not replaced by another */
- for (const commonExport of commonExports) {
- if (platformExportOverrides[commonExport]) {
- continue;
- }
- platformExports.push(commonExport);
- }
- platformExports.push(...Object.values(platformExportOverrides));
- return platformExports;
- }
- if (outdatedPaths.length === 0) {
- console.info('All index files up-to-date');
- } else {
- const fileListStr = outdatedPaths.map(pathname => `- ${pathname}\n`).join('');
- if (checkOutdated) {
- console.info(`Outdated files:\n${fileListStr}`);
- process.exit(1);
- } else {
- console.info(`Updated files:\n${fileListStr}`);
- }
- }
|