UNPKG

@storm-software/workspace-tools

Version:

Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.

327 lines (322 loc) • 8.57 kB
import { withRunExecutor } from "../../../chunk-EYZGKQNH.mjs"; import "../../../chunk-2QMGYIOO.mjs"; import "../../../chunk-4PKTZSV2.mjs"; import { writeInfo } from "../../../chunk-MMA4S6LZ.mjs"; import "../../../chunk-3J2CP54B.mjs"; import { joinPaths } from "../../../chunk-TBW5MCN6.mjs"; import "../../../chunk-3YDFOWNH.mjs"; // src/executors/clean-package/executor.ts import { joinPathFragments } from "@nx/devkit"; import { copy, mkdir, pathExists, readFile, readJson, remove, writeFile, writeJson } from "fs-extra"; import { Glob as Glob2 } from "glob"; // src/executors/clean-package/constants.ts var IGNORE_FILES = [ ".circleci", ".DS_Store", ".editorconfig", ".eslintignore", ".flowconfig", ".git", ".github", ".travis.yml", ".vscode", ".watchmanconfig", ".yarnrc", "appveyor.yml", "karma.conf.js", "node_modules", "package-lock.json", "pnpm-debug.log", "pnpm-lock.yaml", ".devcontainer.json", "test", "yarn-error.log", "yarn.lock", /^(babel|commitlint|jest|vitest)\.config\.[cm]?(j|t)s$/, /^\.?nano-staged\.(c|m)?js(on)?$/, /^\.?simple-git-hooks.js(on)?$/, /^\.?simple-pre-commit.js(on)?$/, /^\.babelrc/, /^\.clean-publish/, /^\.commitlintrc/, /^\.eslintrc/, /^\.jsconfig/, /^\.jsdocrc/, /^\.lintstagedrc/, /^\.nanostagedrc/, /^\.prettierrc/, /^\.remarkrc/, /^\.renovaterc/, /^\.size-limit/, /^\.yaspellerrc/, /^changelog/i, /eslint.config.(c|m)?js/, /README\.[\w-]+\.md/ ]; var IGNORE_FIELDS = [ "babel", "browserslist", "c8", "clean-publish", "commitlint", "devDependencies", "eslintConfig", "eslintIgnore", "husky", "jest", "lint-staged", "nano-staged", "pre-commit", "prettier", "pwmetrics", "remarkConfig", "renovate", "resolutions", "sharec", "simple-git-hooks", "simple-pre-commit", "size-limit", "storm", "typeCoverage", "yaspeller" ]; var NPM_SCRIPTS = [ "postinstall", "postpack", "postpublish", "postversion", "prepublish", "publish", "uninstall", "version" ]; var PUBLISH_CONFIG_FIELDS = [ "bin", "main", "exports", "types", "typings", "module", "browser", "esnext", "es2015", "unpkg", "umd:main", "typesVersions", "cpu", "os" ]; // src/executors/clean-package/utils.ts import { Glob, hasMagic } from "glob"; import micromatch from "micromatch"; import { basename } from "node:path"; function isObject(object) { return Boolean(object) && typeof object === "object"; } function filterObjectByKey(object, filterByKey = (key) => true, deep = false) { const result = {}; let changed = false; for (const key in object) { if (filterByKey(key)) { if (deep && isObject(object[key])) { result[key] = filterObjectByKey(object[key], filterByKey, deep); if (result[key] !== object[key]) { changed = true; } } else { result[key] = object[key]; } } else { changed = true; } } return changed ? result : object; } function createIgnoreMatcher(ignorePattern = "**/*") { if (ignorePattern instanceof RegExp) { return (filename) => !ignorePattern.test(filename); } if (hasMagic(ignorePattern, { magicalBraces: true })) { const isMatch = micromatch.matcher(ignorePattern); return (_filename, path) => !isMatch(path); } return (filename) => filename !== ignorePattern; } async function createFilesFilter(ignoreFiles = "", cwd) { let ignoreFilesList = []; if (ignoreFiles) { const glob = new Glob(ignoreFiles, { cwd }); ignoreFilesList = await glob.walk(); } const ignorePatterns = ignoreFilesList.length > 0 ? IGNORE_FILES.concat(...ignoreFilesList).filter(Boolean) : IGNORE_FILES; const filter = ignorePatterns.reduce( (next, ignorePattern) => { const ignoreMatcher = createIgnoreMatcher(ignorePattern); if (!next) { return ignoreMatcher; } return (filename, path) => ignoreMatcher(filename, path) && next && next(filename, path); }, null ); return (path) => { const filename = basename(path); return filter?.(filename, path); }; } // src/executors/clean-package/executor.ts async function cleanPackageExecutorFn(options, context, config) { const tempDirectoryName = joinPathFragments( config.workspaceRoot, "tmp", context.root ); const exists = await pathExists(tempDirectoryName); if (exists) { writeInfo( `\u{1F9F9} Cleaning temporary directory path: ${tempDirectoryName}`, config ); await remove(tempDirectoryName); } await mkdir(tempDirectoryName); writeInfo(`Created temporary directory: ${tempDirectoryName}`, config); const packageJson = await readJson(options.packageJsonPath); await copy(options.outputPath, tempDirectoryName, { filter: createFilesFilter(options.ignoredFiles, options.outputPath) }); if (options.cleanReadMe) { await cleanReadMe( tempDirectoryName, packageJson.repository, packageJson.homepage ); } if (options.cleanComments) { await cleanComments(tempDirectoryName); } const tempPackageJson = clearPackageJSON(packageJson, options.fields); writeJson( joinPathFragments(tempDirectoryName, "package.json"), tempPackageJson ); await copy(tempDirectoryName, options.outputPath, { override: true, preserveTimestamps: true }); await remove(tempDirectoryName); return { success: true }; } function getReadmeUrlFromRepository(repository) { const repoUrl = typeof repository === "object" ? repository.url : repository; if (repoUrl) { const name = repoUrl.match(/[^/:]+\/[^/:]+$/)?.[0]?.replace(/\.git$/, ""); return `https://github.com/${name}#README.md`; } return null; } async function cleanReadMe(directoryName, repository, homepage) { const readmePath = joinPathFragments(directoryName, "README.md"); const readme = await readFile(readmePath); const readmeUrl = getReadmeUrlFromRepository(repository); if (homepage || readmeUrl) { const cleaned = readme.toString().split(/\n##\s*\w/m)[0] + ` ## Documentation Read full docs **[here](${homepage || readmeUrl})**. `; await writeFile(readmePath, cleaned); } } async function cleanComments(directoryName) { const glob = new Glob2(["**/*.js"], { cwd: directoryName }); const files = await glob.walk(); await Promise.all( files.map(async (i) => { const file = joinPathFragments(directoryName, i); const content = await readFile(file); const cleaned = content.toString().replace(/\s*\/\/.*\n/gm, "\n").replace(/\s*\/\*[^/]+\*\/\n?/gm, "\n").replace(/\n+/gm, "\n").replace(/^\n+/gm, ""); await writeFile(file, cleaned); }) ); } function clearPackageJSON(packageJson, inputIgnoreFields) { const ignoreFields = inputIgnoreFields ? IGNORE_FIELDS.concat(inputIgnoreFields) : IGNORE_FIELDS; if (!packageJson.publishConfig) { return packageJson; } const publishConfig = { ...packageJson.publishConfig }; PUBLISH_CONFIG_FIELDS.forEach((field) => { if (publishConfig[field]) { packageJson[field] = publishConfig[field]; delete publishConfig[field]; } }); if (!Object.keys(publishConfig).length) { const { publishConfig: _, ...pkg } = packageJson; return pkg; } const cleanPackageJSON = filterObjectByKey( { ...packageJson, publishConfig }, (key) => !!(key && !ignoreFields.includes(key) && key !== "scripts") ); if (packageJson.scripts && !ignoreFields.includes("scripts")) { cleanPackageJSON.scripts = filterObjectByKey( packageJson.scripts, (script) => !!(script && NPM_SCRIPTS.includes(script)) ); if (cleanPackageJSON.scripts.publish && /^clean-publish( |$)/.test(cleanPackageJSON.scripts.publish)) { delete cleanPackageJSON.scripts.publish; } } for (const i in cleanPackageJSON) { if (isObject(cleanPackageJSON[i]) && Object.keys(cleanPackageJSON[i]).length === 0) { delete cleanPackageJSON[i]; } } return cleanPackageJSON; } var executor_default = withRunExecutor( "Storm Clean-Package executor", cleanPackageExecutorFn, { skipReadingConfig: false, hooks: { applyDefaultOptions: (options) => { options.outputPath ??= "dist/{projectRoot}"; options.packageJsonPath ??= joinPaths( options.outputPath, "package.json" ); options.cleanReadMe ??= true; options.cleanComments ??= true; return options; } } } ); export { cleanPackageExecutorFn, executor_default as default };