UNPKG

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