@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
JavaScript
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
};