@storm-software/workspace-tools
Version:
Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.
313 lines (310 loc) • 9.75 kB
JavaScript
import {
nxVersion
} from "./chunk-EK75QNMS.mjs";
import {
ProjectTagConstants,
addProjectTag
} from "./chunk-HUVBVDJ7.mjs";
import {
joinPaths
} from "./chunk-ATIBREWM.mjs";
import {
__name
} from "./chunk-2BPV2XV2.mjs";
// src/base/typescript-library-generator.ts
import { addDependenciesToPackageJson, addProjectConfiguration, ensurePackage, formatFiles, names, offsetFromRoot, readJson, updateJson, writeJson } from "@nx/devkit";
import { determineProjectNameAndRootOptions } from "@nx/devkit/src/generators/project-name-and-root-utils";
import { addTsConfigPath, getRelativePathToRootTsConfig, tsConfigBaseOptions } from "@nx/js";
import jsInitGenerator from "@nx/js/src/generators/init/init";
import setupVerdaccio from "@nx/js/src/generators/setup-verdaccio/generator";
async function typeScriptLibraryGeneratorFn(tree, options, config) {
const normalized = await normalizeOptions(tree, {
...options
});
const tasks = [];
tasks.push(await jsInitGenerator(tree, {
...normalized,
tsConfigName: normalized.rootProject ? "tsconfig.json" : "tsconfig.base.json"
}));
tasks.push(addDependenciesToPackageJson(tree, {}, {
"@storm-software/workspace-tools": "latest",
"@storm-software/testing-tools": "latest",
...options.devDependencies ?? {}
}));
if (normalized.publishable) {
tasks.push(await setupVerdaccio(tree, {
...normalized,
skipFormat: true
}));
}
const projectConfig = {
root: normalized.directory,
projectType: "library",
sourceRoot: joinPaths(normalized.directory ?? "", "src"),
targets: {
build: {
executor: options.buildExecutor,
outputs: [
"{options.outputPath}"
],
options: {
entry: [
joinPaths(normalized.projectRoot, "src", "index.ts")
],
outputPath: getOutputPath(normalized),
tsconfig: joinPaths(normalized.projectRoot, "tsconfig.json"),
project: joinPaths(normalized.projectRoot, "package.json"),
defaultConfiguration: "production",
platform: "neutral",
assets: [
{
input: normalized.projectRoot,
glob: "*.md",
output: "/"
},
{
input: "",
glob: "LICENSE",
output: "/"
}
]
},
configurations: {
production: {
debug: false,
verbose: false
},
development: {
debug: true,
verbose: true
}
}
}
}
};
if (options.platform) {
projectConfig.targets.build.options.platform = options.platform === "worker" ? "node" : options.platform;
}
addProjectTag(projectConfig, ProjectTagConstants.Platform.TAG_ID, options.platform === "node" ? ProjectTagConstants.Platform.NODE : options.platform === "worker" ? ProjectTagConstants.Platform.WORKER : options.platform === "browser" ? ProjectTagConstants.Platform.BROWSER : ProjectTagConstants.Platform.NEUTRAL, {
overwrite: false
});
createProjectTsConfigJson(tree, normalized);
addProjectConfiguration(tree, normalized.name, projectConfig);
let repository = {
type: "github",
url: config?.repository || `https://github.com/${config?.organization || "storm-software"}/${config?.namespace || config?.name || "repository"}.git`
};
let description = options.description || "A package developed by Storm Software used to create modern, scalable web applications.";
if (tree.exists("package.json")) {
const packageJson = readJson(tree, "package.json");
if (packageJson?.repository) {
repository = packageJson.repository;
}
if (packageJson?.description) {
description = packageJson.description;
}
}
if (!normalized.importPath) {
normalized.importPath = normalized.name;
}
const packageJsonPath = joinPaths(normalized.projectRoot, "package.json");
if (tree.exists(packageJsonPath)) {
updateJson(tree, packageJsonPath, (json) => {
if (!normalized.importPath) {
normalized.importPath = normalized.name;
}
json.name = normalized.importPath;
json.version = "0.0.1";
if (json.private && (normalized.publishable || normalized.rootProject)) {
json.private = void 0;
}
return {
...json,
version: "0.0.1",
description,
repository: {
...repository,
directory: normalized.projectRoot
},
type: "module",
dependencies: {
...json.dependencies
},
publishConfig: {
access: "public"
}
};
});
} else {
writeJson(tree, packageJsonPath, {
name: normalized.importPath,
version: "0.0.1",
description,
repository: {
...repository,
directory: normalized.projectRoot
},
private: !normalized.publishable || normalized.rootProject,
type: "module",
publishConfig: {
access: "public"
}
});
}
if (tree.exists("package.json") && normalized.importPath) {
updateJson(tree, "package.json", (json) => ({
...json,
pnpm: {
...json?.pnpm,
overrides: {
...json?.pnpm?.overrides,
[normalized.importPath ?? ""]: "workspace:*"
}
}
}));
}
addTsConfigPath(tree, normalized.importPath, [
joinPaths(normalized.projectRoot, "./src", `index.${normalized.js ? "js" : "ts"}`)
]);
addTsConfigPath(tree, joinPaths(normalized.importPath, "/*"), [
joinPaths(normalized.projectRoot, "./src", "/*")
]);
if (tree.exists("package.json")) {
const packageJson = readJson(tree, "package.json");
if (packageJson?.repository) {
repository = packageJson.repository;
}
if (packageJson?.description) {
description = packageJson.description;
}
}
const tsconfigPath = joinPaths(normalized.projectRoot, "tsconfig.json");
if (tree.exists(tsconfigPath)) {
updateJson(tree, tsconfigPath, (json) => {
json.composite ??= true;
return json;
});
} else {
writeJson(tree, tsconfigPath, {
extends: `${offsetFromRoot(normalized.projectRoot)}tsconfig.base.json`,
composite: true,
compilerOptions: {
outDir: `${offsetFromRoot(normalized.projectRoot)}dist/out-tsc`
},
files: [],
include: [
"src/**/*.ts",
"src/**/*.js"
],
exclude: [
"jest.config.ts",
"src/**/*.spec.ts",
"src/**/*.test.ts"
]
});
}
await formatFiles(tree);
return null;
}
__name(typeScriptLibraryGeneratorFn, "typeScriptLibraryGeneratorFn");
function getOutputPath(options) {
const parts = [
"dist"
];
if (options.projectRoot === ".") {
parts.push(options.name);
} else {
parts.push(options.projectRoot);
}
return joinPaths(...parts);
}
__name(getOutputPath, "getOutputPath");
function createProjectTsConfigJson(tree, options) {
const tsconfig = {
extends: options.rootProject ? void 0 : getRelativePathToRootTsConfig(tree, options.projectRoot),
...options?.tsconfigOptions ?? {},
compilerOptions: {
...options.rootProject ? tsConfigBaseOptions : {},
outDir: joinPaths(offsetFromRoot(options.projectRoot), "dist/out-tsc"),
noEmit: true,
...options?.tsconfigOptions?.compilerOptions ?? {}
},
files: [
...options?.tsconfigOptions?.files ?? []
],
include: [
...options?.tsconfigOptions?.include ?? [],
"src/**/*.ts",
"src/**/*.js",
"bin/**/*"
],
exclude: [
...options?.tsconfigOptions?.exclude ?? [],
"jest.config.ts",
"src/**/*.spec.ts",
"src/**/*.test.ts"
]
};
writeJson(tree, joinPaths(options.projectRoot, "tsconfig.json"), tsconfig);
}
__name(createProjectTsConfigJson, "createProjectTsConfigJson");
async function normalizeOptions(tree, options, config) {
let importPath = options.importPath;
if (!importPath && config?.namespace) {
importPath = `@${config?.namespace}/${options.name}`;
}
if (options.publishable) {
if (!importPath) {
throw new Error(`For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)`);
}
}
let bundler = "tsc";
if (options.publishable === false && options.buildable === false) {
bundler = "none";
}
const { Linter } = ensurePackage("@nx/eslint", nxVersion);
const rootProject = false;
const { projectName, names: projectNames, projectRoot, importPath: normalizedImportPath } = await determineProjectNameAndRootOptions(tree, {
name: options.name,
projectType: "library",
directory: options.directory,
importPath,
rootProject
});
const normalized = names(projectNames.projectFileName);
const fileName = normalized.fileName;
return {
js: false,
pascalCaseFiles: false,
skipFormat: false,
skipTsConfig: false,
includeBabelRc: false,
unitTestRunner: "jest",
linter: Linter.EsLint,
testEnvironment: "node",
config: "project",
compiler: "tsc",
bundler,
skipTypeCheck: false,
minimal: false,
hasPlugin: false,
isUsingTsSolutionConfig: false,
projectPackageManagerWorkspaceState: "included",
...options,
fileName,
name: projectName,
projectNames,
projectRoot,
parsedTags: options.tags ? options.tags.split(",").map((s) => s.trim()) : [],
importPath: normalizedImportPath,
rootProject,
shouldUseSwcJest: false
};
}
__name(normalizeOptions, "normalizeOptions");
export {
typeScriptLibraryGeneratorFn,
getOutputPath,
createProjectTsConfigJson,
normalizeOptions
};