Skip to content

Commit 0f8c0a2

Browse files
authored
fix(scripts): run downlevel-dts script in parallel (#2837)
1 parent 7e634cf commit 0f8c0a2

10 files changed

+146
-93
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"main": "index.js",
77
"scripts": {
88
"copy-models": "node ./scripts/copy-models",
9-
"downlevel-dts": "node ./scripts/downlevel-dts",
9+
"downlevel-dts": "node --es-module-specifier-resolution=node ./scripts/downlevel-dts",
1010
"generate-clients": "node ./scripts/generate-clients",
1111
"bootstrap": "yarn",
1212
"clean": "yarn clear-build-cache && yarn clear-build-info && lerna clean",
@@ -53,6 +53,7 @@
5353
"@types/jest": "^26.0.4",
5454
"@typescript-eslint/eslint-plugin": "4.30.0",
5555
"@typescript-eslint/parser": "4.30.0",
56+
"async": "3.2.1",
5657
"chai": "^4.2.0",
5758
"chai-as-promised": "^7.1.1",
5859
"codecov": "^3.4.0",

scripts/downlevel-dts/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Runs downlevel-dts npm script (if present) in each workspace of monorepo, and
1111
strips comments from *.d.ts files.
1212
13-
Usage: index.js
13+
Usage: index.mjs
1414
1515
Options:
1616
--version Show version number [boolean]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// @ts-check
2+
import { exec } from "child_process";
3+
import { access, readFile, writeFile } from "fs/promises";
4+
import { join } from "path";
5+
import stripComments from "strip-comments";
6+
import { promisify } from "util";
7+
8+
import { getAllFiles } from "./getAllFiles.mjs";
9+
import { getDeclarationDirname } from "./getDeclarationDirname.mjs";
10+
import { getDownlevelDirname } from "./getDownlevelDirname.mjs";
11+
12+
const execPromise = promisify(exec);
13+
14+
export const downlevelWorkspace = async (workspacesDir, workspaceName) => {
15+
const workspaceDir = join(workspacesDir, workspaceName);
16+
const downlevelDirname = await getDownlevelDirname(workspaceDir);
17+
const declarationDirname = await getDeclarationDirname(workspaceDir);
18+
19+
const declarationDir = join(workspaceDir, declarationDirname);
20+
try {
21+
await access(declarationDir);
22+
} catch (error) {
23+
throw new Error(
24+
`The types for "${workspaceName}" do not exist.\n` +
25+
`Please build types for workspace "${workspaceDir}" before running downlevel-dts script.`
26+
);
27+
}
28+
29+
const downlevelDir = join(declarationDir, downlevelDirname);
30+
// Create downlevel-dts folder if it doesn't exist
31+
try {
32+
await access(downlevelDir);
33+
} catch (error) {
34+
await execPromise(["yarn", "downlevel-dts"].join(" "), { cwd: workspaceDir });
35+
}
36+
37+
// Strip comments from downlevel-dts files
38+
try {
39+
await access(downlevelDir);
40+
const files = await getAllFiles(downlevelDir);
41+
for (const downlevelTypesFilepath of files) {
42+
try {
43+
const content = await readFile(downlevelTypesFilepath, "utf8");
44+
await writeFile(downlevelTypesFilepath, stripComments(content));
45+
} catch (error) {
46+
console.error(`Error while stripping comments from "${downlevelTypesFilepath.replace(process.cwd(), "")}"`);
47+
console.error(error);
48+
}
49+
}
50+
} catch (error) {
51+
// downlevelDir is not present, do nothing.
52+
}
53+
};

scripts/downlevel-dts/getAllFiles.mjs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { readdir, stat } from "fs/promises";
2+
3+
export const getAllFiles = async (dirPath, arrayOfFiles = []) => {
4+
const files = await readdir(dirPath);
5+
6+
for (const file of files) {
7+
const { isDirectory } = await stat(dirPath + "/" + file);
8+
if (isDirectory()) {
9+
const filesInDirectory = await getAllFiles(dirPath + "/" + file, arrayOfFiles);
10+
arrayOfFiles.push(filesInDirectory);
11+
} else {
12+
arrayOfFiles.push(join(dirPath, "/", file));
13+
}
14+
}
15+
16+
return arrayOfFiles;
17+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { readFile } from "fs/promises";
2+
import { join } from "path";
3+
4+
export const getDeclarationDirname = async (workspaceDir) => {
5+
const tsTypesConfigPath = join(workspaceDir, "tsconfig.types.json");
6+
const tsTypesConfigJson = JSON.parse((await readFile(tsTypesConfigPath)).toString());
7+
8+
const declarationDirname = tsTypesConfigJson.compilerOptions.declarationDir;
9+
if (!declarationDirname) {
10+
throw new Error(`The declarationDir is not defined in "${tsTypesConfigPath}".`);
11+
}
12+
13+
return declarationDirname;
14+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { readFile } from "fs/promises";
2+
import { join } from "path";
3+
4+
export const getDownlevelDirname = async (workspaceDir) => {
5+
const packageJsonPath = join(workspaceDir, "package.json");
6+
const packageJson = JSON.parse((await readFile(packageJsonPath)).toString());
7+
if (!packageJson.scripts["downlevel-dts"]) {
8+
console.error(`The "downlevel-dts" script is not defined for "${workspaceDir}"`);
9+
return;
10+
}
11+
const downlevelArgs = packageJson.scripts["downlevel-dts"].split(" ");
12+
return downlevelArgs[2].replace(`${downlevelArgs[1]}/`, "");
13+
};
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { readdirSync, readFileSync } from "fs";
2+
import { join } from "path";
3+
4+
export const getWorkspaces = (rootDir) => {
5+
const { packages } = JSON.parse(readFileSync(join(rootDir, "package.json")).toString()).workspaces;
6+
return packages
7+
.map((dir) => dir.replace("/*", ""))
8+
.flatMap((workspacesDir) =>
9+
readdirSync(join(rootDir, workspacesDir), { withFileTypes: true })
10+
.filter((dirent) => dirent.isDirectory())
11+
.map((dirent) => ({ workspacesDir, workspaceName: dirent.name }))
12+
);
13+
};

scripts/downlevel-dts/index.js

-91
This file was deleted.

scripts/downlevel-dts/index.mjs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @ts-check
2+
import parallelLimit from "async/parallelLimit";
3+
import { cpus } from "os";
4+
import yargs from "yargs";
5+
6+
import { downlevelWorkspace } from "./downlevelWorkspace.mjs";
7+
import { getWorkspaces } from "./getWorkspaces.mjs";
8+
9+
// ToDo: Write downlevel-dts as a yargs command, and import yargs in scripts instead.
10+
yargs
11+
.usage(
12+
"Runs downlevel-dts npm script (if present) in each workspace of monorepo," +
13+
" and strips comments from *.d.ts files.\n\n" +
14+
"Usage: index.mjs"
15+
)
16+
.help()
17+
.alias("h", "help").argv;
18+
19+
const workspaces = getWorkspaces(process.cwd());
20+
const tasks = workspaces.map(({ workspacesDir, workspaceName }) => async () => {
21+
await downlevelWorkspace(workspacesDir, workspaceName);
22+
});
23+
24+
parallelLimit(tasks, cpus().length, function (err) {
25+
if (err) {
26+
throw err;
27+
}
28+
});

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,11 @@ [email protected], async@^3.0.1:
26012601
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
26022602
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
26032603

2604+
2605+
version "3.2.1"
2606+
resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8"
2607+
integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==
2608+
26042609
asynckit@^0.4.0:
26052610
version "0.4.0"
26062611
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"

0 commit comments

Comments
 (0)