UNPKG

@storm-software/projen

Version:

Tools for managing Projen configuration automation within a Nx workspace.

495 lines (493 loc) 16.9 kB
import { joinPaths } from "../../chunk-LDQSXIL7.mjs"; import { init_esm_shims } from "../../chunk-PEAVGRTD.mjs"; // src/components/nx-workspace.ts init_esm_shims(); import { NX_DEFAULT_BUILD_OUTPUTS as BASE_NX_DEFAULT_BUILD_OUTPUTS, NxWorkspace } from "@aws/pdk/monorepo/components/nx-workspace"; import { ProjectUtils } from "@aws/pdk/monorepo/utils"; import { asUndefinedIfEmpty } from "@aws/pdk/monorepo/utils/common"; import { readFileSync } from "node:fs"; import { JsonFile } from "projen"; var NX_DEFAULT_BUILD_OUTPUTS = [ ...BASE_NX_DEFAULT_BUILD_OUTPUTS, "{workspaceRoot}/dist/{projectRoot}" ]; var StormNxWorkspace = class extends NxWorkspace { /** * Retrieves the singleton instance associated with project root. * * @param scope project instance. */ static of(scope) { return scope.root.components.find( (c) => ProjectUtils.isNamedInstanceOf(c, NxWorkspace) ); } /** * Raw nx.json file to support overrides that aren't handled * directly. * * **Attention:** any overrides applied here will not be visible * in the properties and only included in final synthesized output, * and likely to override native handling. * @advanced */ nxJson; /** * Automatically infer NxProject targets based on project type. * @experimental */ autoInferProjectTargets = true; /** * List of cacheable operations. */ cacheableOperations = [ "lint-sherif", "lint-knip", "lint-ls", "lint", "format-readme", "format-toml", "format-prettier", "format", "clean", "build-base", "build", "test", "e2e", "docs", "nx-release-publish" ]; /** * Some presets use the extends property to hide some default options in a separate json file. * The json file specified in the extends property is located in your node_modules folder. * The Nx preset files are specified in the nx package. * * @default "@storm-software/workspace-tools/config/base.json" */ extends = "@storm-software/workspace-tools/config/base.json"; /** * Plugins for extending the project graph */ nxPlugins = [ { plugin: "@nx/eslint/plugin", exclude: ["packages/**/__fixtures__/**/*"], options: { targetName: "lint", useFlatConfig: true } }, "@storm-software/workspace-tools/plugins/typescript", "@storm-software/workspace-tools/plugins/typescript/untyped", "@storm-software/workspace-tools/plugins/typescript/tsup" ]; /** * Default options for `nx affected` */ affected = { defaultBase: "main" }; /** * Named inputs * @see https://nx.dev/reference/nx-json#inputs-&-namedinputs */ namedInputs = { // https://nx.dev/more-concepts/customizing-inputs#defaults sharedGlobals: [ "{workspaceRoot}/.github/**/*", "{workspaceRoot}/assets/**/*", "{workspaceRoot}/tsconfig.*.json", "{workspaceRoot}/.npm@(rc|ignore)", "{workspaceRoot}/package.json", "{workspaceRoot}/{pnpm-workspace,pnpm-lock,package-lock,yarn-lock}.@(yaml|yml)", "{workspaceRoot}/bun.lockb", "{workspaceRoot}/LICENSE", "{workspaceRoot}/.git@(attributes|ignore)", "{workspaceRoot}/{nx.json,.nxignore}", "{workspaceRoot}/storm-workspace{,.*}.@(json|yaml|toml)", "{workspaceRoot}/.storm-workspace/config{,.*}.@(json|yaml|toml)", "{workspaceRoot}/storm-workspace.config.[jt]s", "{workspaceRoot}/.storm-workspace/config{,.*}.[jt]s", "{workspaceRoot}/.env{,.local}" ], default: ["sharedGlobals", "{projectRoot}/**/*"], production: [ "{projectRoot}/**/*", "!{projectRoot}/{tools,scripts}/**/*", "!{projectRoot}/node_modules/**/*", "!{projectRoot}/{api-extractor,tsdoc,typedoc}.json", "!{projectRoot}/.eslint-doc-generatorrc.@(js|json)", "!{projectRoot}/.storybook/**/*", "!{projectRoot}/tsconfig.storybook.json", "!{projectRoot}/jest.config.ts", "!{projectRoot}/tsconfig.spec.json", "!{projectRoot}/{src/,}test-setup.[jt]s", "!{projectRoot}/.eslintignore", "!{projectRoot}/.eslintrc.@(json|cjs)", "!{projectRoot}/eslint.config.@(js|cjs|mjs|ts|cts|mts|json)", "!{projectRoot}/biome.@(toml|json)", "!{projectRoot}/lefthook.@(yaml|yml)", "!{projectRoot}/.markdownlint.json", "!{projectRoot}/.markdownlint-cli2.cjs", "!{projectRoot}/.prettier@(rc|ignore)", "!{projectRoot}/docs/**/*", "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", "!{projectRoot}/{benches,e2e,tests,testing}/**/*", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)" ], testing: [ "sharedGlobals", "{workspaceRoot}/{jest.config,jest.preset,vitest.config,vitest.preset,vitest.workspace}.@(js|cjs|mjs|ts|cts|mts)", "{workspaceRoot}/{benches,e2e,tests,testing}/**/*", "{workspaceRoot}/coverage/**/*", "{projectRoot}/{project.json,README.md,CHANGELOG.md}", "{projectRoot}/.env{,.*}", "{projectRoot}/{jest.config,vitest.config}.@(js|cjs|mjs|ts|cts|mts)", "{projectRoot}/tsconfig.spec.json", "{projectRoot}/{src/,}test-setup.[jt]s", "{projectRoot}/{benches,e2e,tests,testing}/**/*", "{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)" ], linting: [ "sharedGlobals", "{workspaceRoot}/.eslintignore", "{workspaceRoot}/.eslintrc.@(js|cjs|mjs|ts|cts|mts|json)", "{workspaceRoot}/eslint.config.@(js|cjs|mjs|ts|cts|mts)", "{workspaceRoot}/biome.@(toml|json)", "{workspaceRoot}/lefthook.@(yaml|yml|json)", "{workspaceRoot}/.markdownlint.json", "{workspaceRoot}/.markdownlint-cli2.@(js|cjs|mjs|ts|cts|mts)", "{workspaceRoot}/.prettier@(rc|ignore)", "{workspaceRoot}/prettier.config.@(js|cjs|mjs|ts|cts|mts)", "{projectRoot}/{project.json,README.md,CHANGELOG.md}", "{projectRoot}/.env{,.*}", "{projectRoot}/.eslintignore", "{projectRoot}/.eslintrc.@(js|cjs|mjs|ts|cts|mts|json)", "{projectRoot}/eslint.config.@(js|cjs|mjs|ts|cts|mts)", "{projectRoot}/biome.@(toml|json)", "{projectRoot}/lefthook.@(yaml|yml|json)", "{projectRoot}/.markdownlint.json", "{projectRoot}/.markdownlint-cli2.@(js|cjs|mjs|ts|cts|mts)", "{projectRoot}/.prettier@(rc|ignore)" ], documentation: [ "sharedGlobals", "{workspaceRoot}/{api-extractor,tsdoc,typedoc}.json", "{workspaceRoot}/.eslint-doc-generatorrc.@(js|json)", "{workspaceRoot}/contentlayer.config.ts", "{workspaceRoot}/*.@(md|mdx)", "{workspaceRoot}/docs/**/*", "{workspaceRoot}/.storybook/**/*", "{projectRoot}/{project.json,README.md,CHANGELOG.md}", "{projectRoot}/.env{,.local}", "{projectRoot}/{api-extractor,tsdoc,typedoc}.json", "{projectRoot}/.eslint-doc-generatorrc.@(js|json)", "{projectRoot}/contentlayer.config.ts", "{projectRoot}/.storybook/**/*", "{projectRoot}/tsconfig.storybook.json", "{projectRoot}/docs/**/*", "{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", "!{projectRoot}/{benches,e2e,tests,testing}/**/*", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", "!{projectRoot}/tsconfig.spec.json" ], rust: [ "sharedGlobals", "{workspaceRoot}/Cargo.toml", "{workspaceRoot}/Cargo.lock", "{workspaceRoot}/.cargo/config.toml", "{workspaceRoot}/rust-toolchain", "{workspaceRoot}/rustfmt.toml", "{workspaceRoot}/deny.toml", "{projectRoot}/Cargo.toml", "{projectRoot}/.cargo/config.toml", "{projectRoot}/{project.json,CHANGELOG.md}", "{projectRoot}/.env{,.local}", "{projectRoot}/**/*.rs", "{projectRoot}/**/*.@(proto|acid|acidic|prisma)", "{projectRoot}/src/**/*.@(json|jsonc|yaml|yml|toml)", "!{projectRoot}/README.md", "!{projectRoot}/docs/**/*", "!{projectRoot}/{benches,e2e,tests,testing}/**/*" ], typescript: [ "sharedGlobals", "!{projectRoot}/tsconfig.@(spec|storybook).json", "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", "!{projectRoot}/node_modules/**/*", "!{projectRoot}/{benches,e2e,tests,testing}/**/*", "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.*.json", "{projectRoot}/{project.json,README.md,CHANGELOG.md}", "{projectRoot}/.env{,.*}", "{projectRoot}/docs/**/*", "{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", "{projectRoot}/**/*.@(proto|acid|acidic|prisma)", "{projectRoot}/src/**/*.@(cts|mts|ts|tsx|graphql|gql|js|cjs|mjs|jsx|json|jsonc|yaml|yml|toml|md|mdx)", "{projectRoot}/{build,tsup,contentlayer}.*.[jt]s?(x)", "{projectRoot}/{bin,tools,helpers,scripts}/**/*" ] }; /** * Dependencies between different target names across all projects * * @see https://nx.dev/reference/nx-json#target-defaults */ targetDefaults = { "lint-ls": { outputs: ["{projectRoot}/**/*"], inputs: ["linting", "default", "^production"], dependsOn: ["^lint-ls"], executor: "nx:run-commands", options: { command: 'pnpm exec ls-lint --config="./node_modules/@storm-software/linting-tools/ls-lint/.ls-lint.yml" ', color: true } }, "lint-sherif": { outputs: ["{projectRoot}/package.json"], inputs: ["{workspaceRoot}/package.json", "{projectRoot}/package.json"], executor: "nx:run-commands", options: { command: "pnpm exec sherif -i react -i react-dom -i typescript" } }, "lint-knip": { inputs: ["linting", "default", "^production"], executor: "nx:run-commands", options: { command: "pnpm exec knip" } }, lint: { outputs: ["{projectRoot}"], inputs: ["linting", "default", "^production"], dependsOn: ["lint-ls", "lint-sherif", "lint-knip", "lint-docs", "^lint"], executor: "nx:run-commands", options: { command: 'echo Linted the project files in "{projectRoot}" ' } }, "format-toml": { inputs: ["linting", "{projectRoot}/**/*.toml"], outputs: ["{projectRoot}/**/*.toml"], dependsOn: ["^format-toml"], executor: "nx:run-commands", options: { command: 'pnpm exec taplo format --colors="always" --config="./node_modules/@storm-software/linting-tools/taplo/config.toml" --cache-path="./tmp/taplo/{projectRoot}"', color: true } }, "format-readme": { inputs: [ "linting", "documentation", "{projectRoot}/{README.md,package.json,Cargo.toml,executors.json,generators.json}", "default", "^production" ], outputs: ["{projectRoot}/README.md"], dependsOn: ["^format-readme"], executor: "nx:run-commands", options: { command: 'pnpm exec storm-git readme-gen --templates="./tools/readme-templates" --project="{projectName}"', color: true } }, "format-prettier": { inputs: ["linting", "default", "^production"], dependsOn: ["^format-prettier"], executor: "nx:run-commands", options: { command: 'pnpm exec prettier "{projectRoot}/**/*" --write --ignore-unknown --no-error-on-unmatched-pattern --config="./node_modules/@storm-software/prettier/config.json" --ignore-path="./node_modules/@storm-software/prettier/.prettierignore" --cache --cache-location="./tmp/prettier/{projectRoot}" ', color: true } }, format: { inputs: ["linting", "default", "^production"], outputs: ["{projectRoot}"], dependsOn: ["format-toml", "format-readme", "format-prettier", "^format"], executor: "nx:run-commands", options: { command: 'echo Formatted the project files in "{projectRoot}" ' } }, clean: { inputs: ["default", "^production"], outputs: NX_DEFAULT_BUILD_OUTPUTS, dependsOn: ["^clean"], executor: "nx:run-commands", options: { commands: [ "pnpm exec rimraf --glob {projectRoot}/dist", "pnpm exec rimraf dist/{projectRoot}" ] } }, "build-untyped": { dependsOn: ["^build"] }, "build-base": { dependsOn: ["build-untyped", "^build"] }, "build-local": { inputs: ["default", "^production"], dependsOn: ["build-base", "build-untyped", "^build"] }, build: { inputs: ["default", "^production"], outputs: NX_DEFAULT_BUILD_OUTPUTS, dependsOn: ["build-base", "build-untyped", "^build"] }, rebuild: { inputs: ["default", "^production"], executor: "nx:run-commands", dependsOn: ["clean", "^build"], options: { command: "pnpm exec nx run {projectName}:build", color: true, cwd: "{workspaceRoot}" } }, docs: { outputs: ["{options.outputPath}"], inputs: ["linting", "documentation", "default", "^production"], dependsOn: ["build", "format-readme", "lint-docs", "^docs"] }, test: { inputs: ["testing", "default", "^production"], dependsOn: ["build", "^test"] }, e2e: { inputs: ["testing", "default", "^production"], dependsOn: ["test", "^e2e"] }, "nx-release-publish": { inputs: ["default", "^production"], dependsOn: ["build", "^nx-release-publish"] } }; /** * Configuration for Nx releases */ release = {}; /** * The number of parallel tasks to run. * * @defaultValue 5 */ parallel = 5; /** * Should the daemon be used to run tasks? * * @defaultValue true */ useDaemonProcess = true; /** * Set this to false to disable adding inference plugins when generating new projects * * @defaultValue true */ useInferencePlugins = true; /** * The default base branch for new projects. * * @defaultValue "main" */ defaultBase = "main"; /** * The CLI configuration for the workspace. */ cli; constructor(project) { super(project); let StormWorkspaceConfig; if (project.root.outdir) { const StormWorkspaceConfigJson = readFileSync( joinPaths(project.root.outdir, "storm-workspace.json"), "utf8" ); StormWorkspaceConfig = JSON.parse(StormWorkspaceConfigJson); } if (StormWorkspaceConfig?.namespace) { this.npmScope = StormWorkspaceConfig?.namespace; } if (StormWorkspaceConfig?.branch) { this.defaultBase = StormWorkspaceConfig?.branch; this.affected = { defaultBase: StormWorkspaceConfig?.branch }; } if (StormWorkspaceConfig?.packageManager) { this.cli = { packageManager: StormWorkspaceConfig?.packageManager }; } this.nxJson = new JsonFile(project, "nx.json", { obj: { extends: () => this.extends, npmScope: () => this.npmScope, affected: () => asUndefinedIfEmpty(this.affected), workspaceLayout: () => asUndefinedIfEmpty(this.workspaceLayout), plugins: () => asUndefinedIfEmpty(this.nxPlugins), namedInputs: () => asUndefinedIfEmpty(this.namedInputs), targetDefaults: () => asUndefinedIfEmpty(this.targetDefaults), tasksRunnerOptions: () => asUndefinedIfEmpty(this.tasksRunnerOptions), parallel: () => this.parallel, useDaemonProcess: () => this.useDaemonProcess, useInferencePlugins: () => this.useInferencePlugins, release: () => asUndefinedIfEmpty(this.release) } }); } /** * Adds a release group to the workspace. * * @param name The name of the release group * @param projects The projects in the release group * @param projectsRelationship The relationship between the projects * @param releaseTagPattern The release tag pattern * @param groupPreVersionCommand The command to run before versioning */ addReleaseGroup(name, projects, projectsRelationship = "independent", releaseTagPattern = "{projectName}@{version}", groupPreVersionCommand = "pnpm build") { this.release ??= { groups: {}, changelog: { entryWhenNoChanges: false, renderOptions: { authors: false, commitReferences: true, versionTitleDate: true } } }; this.release.groups[name] = { projects, projectsRelationship, releaseTagPattern, version: { groupPreVersionCommand, currentVersionResolver: "git-tag", specifierSource: "conventional-commits", generator: "@storm-software/workspace-tools:release-version", generatorOptions: { currentVersionResolver: "git-tag", specifierSource: "conventional-commits" } } }; } }; export { NX_DEFAULT_BUILD_OUTPUTS, StormNxWorkspace };