nextui/packages/react/scripts/cherry-pick.js
2022-01-01 18:56:14 -03:00

135 lines
3.7 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const glob = require('tiny-glob');
const readPkgUp = require('read-pkg-up');
const mkDir = promisify(fs.mkdir);
const rimraf = promisify(require('rimraf'));
const stat = promisify(fs.stat);
const writeFile = promisify(fs.writeFile);
const isFile = (path) =>
stat(path)
.then((stats) => stats.isFile())
.catch(() => false);
const withDefaults = (
{ cwd = '.', ...options } = {},
additionalDefaults = {}
) => ({
inputDir: 'src',
cwd: path.resolve(process.cwd(), cwd),
...additionalDefaults,
...options
});
const noop = () => {};
// get all folder name from a directory
const getFoldersFromDir = async (cwd, dir) => {
const files = await glob(`${dir}/*`, { cwd });
const folders = files
.filter((file) => file.indexOf('.') === -1)
.map((file) => file.replace(`${dir}/`, ''));
return folders;
};
const findFiles = async ({ cwd, inputDir, esmDir }) => {
const filePaths = await glob(
path.join(inputDir, '!(index).{js,jsx,ts,tsx}'),
{ cwd }
);
const componentsFolders = await getFoldersFromDir(cwd, esmDir);
const files = filePaths
.filter((f) => !f.endsWith('.d.ts'))
.filter((f) => !f.endsWith('.test.ts'))
.filter((f) => !f.endsWith('.test.tsx'))
.filter((f) => !f.endsWith('.stories.ts'))
.filter((f) => !f.endsWith('.stories.tsx'))
.map((filePath) => path.basename(filePath).replace(/\.(js|ts)x?$/, ''));
return files.filter((file) => componentsFolders.includes(file));
};
const pkgCache = new WeakMap();
const getPkgName = async (options) => {
if (options.name != null) {
return options.name;
}
if (pkgCache.has(options)) {
return pkgCache.get(options);
}
const result = await readPkgUp({ cwd: options.cwd });
if (!result) {
throw new Error(
'Could not determine package name. No `name` option was passed and no package.json was found relative to: ' +
options.cwd
);
}
const pkgName = result.packageJson.name;
pkgCache.set(options, pkgName);
return pkgName;
};
const fileProxy = async (options, file) => {
const { cwd, cjsDir, esmDir, typesDir } = options;
// const pkgName = await getPkgName(options);
const proxyPkg = {
// name: `${pkgName}/${file}`,
// private: true,
sideEffects: false,
main: path.join('..', cjsDir, `${file}/index.js`),
module: path.join('..', esmDir, `${file}/index.js`),
types: path.join('..', esmDir, `${file}/index.d.ts`)
};
if (typeof typesDir === 'string') {
proxyPkg.types = path.join('..', typesDir, `${file}.d.ts`);
} else if (await isFile(path.join(cwd, `${file}.d.ts`))) {
proxyPkg.types = path.join('..', `${file}.d.ts`);
// try the esm path in case types are located with each
} else if (await isFile(path.join(cwd, esmDir, `${file}.d.ts`))) {
proxyPkg.types = path.join('..', esmDir, `${file}.d.ts`);
}
return JSON.stringify(proxyPkg, null, 2) + '\n';
};
const cherryPick = async (inputOptions) => {
const options = withDefaults(inputOptions, {
cjsDir: 'lib',
esmDir: 'es'
});
const files = await findFiles(options);
await Promise.all(
files.map(async (file) => {
const proxyDir = path.join(options.cwd, file);
await mkDir(proxyDir).catch(noop);
await writeFile(
`${proxyDir}/package.json`,
await fileProxy(options, file)
);
})
);
return files;
};
const clean = async (inputOptions) => {
const options = withDefaults(inputOptions);
const files = await findFiles(options);
await Promise.all(
files.map(async (file) => rimraf(path.join(options.cwd, file)))
);
return files;
};
module.exports.default = cherryPick;
module.exports.clean = clean;