diff --git a/package.json b/package.json index 892951a0dddd8..ec8081db6a891 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "main": "index.js", "scripts": { "copy-models": "node ./scripts/copy-models", + "downlevel-dts": "node ./scripts/downlevel-dts", "generate-clients": "node ./scripts/generate-clients", "bootstrap": "yarn", "clean": "yarn clear-build-cache && yarn clear-build-info && lerna clean", @@ -85,6 +86,7 @@ "mocha": "^8.0.1", "prettier": "2.3.0", "puppeteer": "^5.1.0", + "strip-comments": "2.0.1", "ts-jest": "^26.4.1", "ts-loader": "^7.0.5", "typedoc-plugin-lerna-packages": "^0.3.1", @@ -122,4 +124,4 @@ ], "**/*.{ts,js,md,json}": "prettier --write" } -} \ No newline at end of file +} diff --git a/scripts/downlevel-dts/README.md b/scripts/downlevel-dts/README.md new file mode 100644 index 0000000000000..e0d09166791e8 --- /dev/null +++ b/scripts/downlevel-dts/README.md @@ -0,0 +1,24 @@ +# How to downlevel-dts + +## Prerequisite + +- Node.js version >= 12. + +## Options + +``` +Runs downlevel-dts npm script (if present) in each workspace of monorepo, and +strips comments from *.d.ts files. + +Usage: index.js + +Options: + --version Show version number [boolean] + -h, --help Show help [boolean] +``` + +## Examples + +- Run downlevel-dts for workspaces in monorepo: + + `yarn downlevel-dts` diff --git a/scripts/downlevel-dts/index.js b/scripts/downlevel-dts/index.js new file mode 100644 index 0000000000000..546419d33408a --- /dev/null +++ b/scripts/downlevel-dts/index.js @@ -0,0 +1,91 @@ +// @ts-check +const yargs = require("yargs"); + +const { existsSync, readdirSync, readFileSync, statSync, writeFileSync } = require("fs"); +const { join } = require("path"); +const { execSync } = require("child_process"); +const stripComments = require("strip-comments"); + +// ToDo: Write downlevel-dts as a yargs command, and import yargs in scripts instead. +yargs + .usage( + "Runs downlevel-dts npm script (if present) in each workspace of monorepo," + + " and strips comments from *.d.ts files.\n\n" + + "Usage: index.js" + ) + .help() + .alias("h", "help").argv; + +const { packages } = JSON.parse(readFileSync(join(process.cwd(), "package.json")).toString()).workspaces; + +const getAllFiles = (dirPath, arrayOfFiles = []) => { + const files = readdirSync(dirPath); + + files.forEach((file) => { + if (statSync(dirPath + "/" + file).isDirectory()) { + arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles); + } else { + arrayOfFiles.push(join(dirPath, "/", file)); + } + }); + + return arrayOfFiles; +}; + +packages + .map((dir) => dir.replace("/*", "")) + .forEach((workspacesDir) => { + // Process each workspace in workspace directory + readdirSync(join(process.cwd(), workspacesDir), { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name) + .forEach((workspaceName) => { + const workspaceDir = join(workspacesDir, workspaceName); + + const packageJsonPath = join(workspaceDir, "package.json"); + const packageJson = JSON.parse(readFileSync(packageJsonPath).toString()); + if (!packageJson.scripts["downlevel-dts"]) { + console.error(`The "downlevel-dts" script is not defined for "${workspaceDir}"`); + return; + } + const downlevelArgs = packageJson.scripts["downlevel-dts"].split(" "); + const downlevelDirname = downlevelArgs[2].replace(`${downlevelArgs[1]}/`, ""); + + const tsTypesConfigPath = join(workspaceDir, "tsconfig.types.json"); + const declarationDirname = JSON.parse(readFileSync(tsTypesConfigPath).toString()).compilerOptions + .declarationDir; + + if (!declarationDirname) { + throw new Error(`The declarationDir is not defined in "${tsTypesConfigPath}".`); + } + + const declarationDir = join(workspaceDir, declarationDirname); + if (!existsSync(declarationDir)) { + throw new Error( + `The types for "${workspaceName}" do not exist.\n` + + `Please build types for workspace "${workspaceDir}" before running downlevel-dts script.` + ); + } + + const downlevelDir = join(declarationDir, downlevelDirname); + // Create downlevel-dts folder if it doesn't exist + if (!existsSync(downlevelDir)) { + execSync(["yarn", "downlevel-dts"].join(" "), { cwd: workspaceDir }); + } + + // Strip comments from downlevel-dts files + if (existsSync(downlevelDir)) { + getAllFiles(downlevelDir).forEach((downlevelTypesFilepath) => { + try { + const content = readFileSync(downlevelTypesFilepath, "utf8"); + writeFileSync(downlevelTypesFilepath, stripComments(content)); + } catch (error) { + console.error( + `Error while stripping comments from "${downlevelTypesFilepath.replace(process.cwd(), "")}"` + ); + console.error(error); + } + }); + } + }); + }); diff --git a/yarn.lock b/yarn.lock index 40f48fc369da4..baa489593b346 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11294,6 +11294,11 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-comments@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"