@codedrifters/configulator 0.0.105 → 0.0.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.mts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +2 -2
- package/lib/index.mjs.map +1 -1
- package/package.json +4 -4
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../utils/src/aws/aws-types.ts","../../utils/src/git/git-utils.ts","../../utils/src/string/string-utils.ts","../../utils/src/index.ts","../src/index.ts","../src/aws/aws-deployment-config.ts","../src/turbo/turbo-repo-task.ts","../src/turbo/turbo-repo.ts","../src/aws/aws-deployment-target.ts","../src/latest-eligible-version.ts","../src/version-package-map.ts","../src/versions.ts","../src/jsii/jsii-faker.ts","../src/pnpm/pnpm-workspace.ts","../src/projects/monorepo-project.ts","../src/tasks/reset-task.ts","../src/projects/typescript-project.ts","../src/vscode/vscode.ts","../src/typescript/typescript-config.ts","../src/workflows/aws-deploy-workflow.ts"],"sourcesContent":["/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const AWS_STAGE_TYPE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type AwsStageType = (typeof AWS_STAGE_TYPE)[keyof typeof AWS_STAGE_TYPE];\n\n/**\n * Deployment target role: whether an (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n */\nexport const DEPLOYMENT_TARGET_ROLE = {\n /**\n * Account and region that represents the primary region for this service.\n * For example, the base DynamoDB Region for global tables.\n */\n PRIMARY: \"primary\",\n /**\n * Account and region that represents a secondary region for this service.\n * For example, a replica region for a global DynamoDB table.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Type for deployment target role values.\n */\nexport type DeploymentTargetRoleType =\n (typeof DEPLOYMENT_TARGET_ROLE)[keyof typeof DEPLOYMENT_TARGET_ROLE];\n\n/**\n * Environment types (primary/secondary).\n *\n * @deprecated Use {@link DEPLOYMENT_TARGET_ROLE} instead. This constant is maintained for backward compatibility.\n */\nexport const AWS_ENVIRONMENT_TYPE = DEPLOYMENT_TARGET_ROLE;\n\n/**\n * Type for environment type values.\n *\n * @deprecated Use {@link DeploymentTargetRoleType} instead. This type is maintained for backward compatibility.\n */\nexport type AwsEnvironmentType = DeploymentTargetRoleType;\n","import { execSync } from \"node:child_process\";\n\n/**\n * Returns the current full git branch name\n *\n * ie: feature/1234 returns feature/1234\n *\n */\nexport const findGitBranch = (): string => {\n return execSync(\"git rev-parse --abbrev-ref HEAD\")\n .toString(\"utf8\")\n .replace(/[\\n\\r\\s]+$/, \"\");\n};\n\nexport const findGitRepoName = (): string => {\n /**\n * When running in github actions this will be populated.\n */\n if (process.env.GITHUB_REPOSITORY) {\n return process.env.GITHUB_REPOSITORY;\n }\n\n /**\n * locally, we need to extract the repo name from the git config.\n */\n const remote = execSync(\"git config --get remote.origin.url\")\n .toString(\"utf8\")\n .replace(/[\\n\\r\\s]+$/, \"\")\n .trim();\n\n const match = remote.match(/[:\\/]([^/]+\\/[^/]+?)(?:\\.git)?$/);\n const repoName = match ? match[1] : \"error-repo-name\";\n\n return repoName;\n};\n","import * as crypto from \"node:crypto\";\n\n/**\n *\n * @param inString string to hash\n * @param trimLength trim to this length (defaults to 999 chars)\n * @returns\n */\nexport const hashString = (inString: string, trimLength: number = 999) => {\n return crypto\n .createHash(\"sha256\")\n .update(inString)\n .digest(\"hex\")\n .substring(0, trimLength);\n};\n\n/**\n *\n * @param inputString string to truncate\n * @param maxLength max length of this string\n * @returns trimmed string\n */\nexport const trimStringLength = (inputString: string, maxLength: number) => {\n return inputString.length < maxLength\n ? inputString\n : inputString.substring(0, maxLength);\n};\n","export * from \"./aws/aws-types\";\nexport * from \"./git/git-utils\";\nexport * from \"./string/string-utils\";\n","export * from \"./aws/\";\nexport * from \"./git/\";\nexport * from \"./latest-eligible-version\";\nexport * from \"./version-package-map\";\nexport * from \"./versions\";\nexport * from \"./jsii/\";\nexport * from \"./pnpm/\";\nexport * from \"./projects/\";\nexport * from \"./tasks/\";\nexport * from \"./turbo/\";\nexport * from \"./typescript/\";\nexport * from \"./vscode/\";\nexport * from \"./workflows/\";\n","import { join, relative } from \"node:path\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { AWS_STAGE_TYPE } from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { AwsDeploymentTarget } from \"./aws-deployment-target\";\nimport { TurboRepo } from \"../turbo\";\n\n/*******************************************************************************\n *\n * AWS Deployment Configuration\n *\n * This component allows configuration of multiple AWS deployment\n * targets, each with its own account, region, and deployment type\n * (dev, stage, prod). It supports both local and CI deployments,\n * with customizable settings for each target.\n *\n ******************************************************************************/\n\n/*\nexport interface AwsDeploymentConfigOptions {}\n*/\n\nexport class AwsDeploymentConfig extends Component {\n public static of(\n project: AwsCdkTypeScriptApp,\n ): AwsDeploymentConfig | undefined {\n const isDefined = (c: Component): c is AwsDeploymentConfig =>\n c instanceof AwsDeploymentConfig;\n return project.components.find(isDefined);\n }\n\n /**\n * Environment variables to be injected into all tasks.\n */\n public readonly env: Record<string, string>;\n\n /**\n * The relative path to the project directory from the root of the project.\n */\n public readonly projectPath: string;\n\n /**\n * The relative path to the root of the project from the output directory.\n */\n public readonly rootPath: string;\n\n /**\n * The output directory for the CDK synthesis, from the root directory.\n */\n public readonly rootCdkOut: string;\n\n /**\n * The output directory for the CDK synthesis.\n */\n public readonly cdkOut: string;\n\n /**\n * Array of targets for deployment.\n */\n public readonly awsDeploymentTargets: Array<AwsDeploymentTarget> = [];\n\n constructor(project: AwsCdkTypeScriptApp) {\n super(project);\n\n /**\n * Common variables used across tasks.\n */\n this.env = { GIT_BRANCH: \"$(git branch --show-current)\" };\n this.projectPath = relative(project.root.outdir, project.outdir);\n this.rootPath = relative(project.outdir, project.root.outdir);\n this.rootCdkOut = join(\"dist\", this.projectPath, \"cdk.out\");\n this.cdkOut = join(this.rootPath, \"dist\", this.projectPath, \"cdk.out\");\n\n /**\n * Reset some tasks we will rebuild below.\n */\n [\"deploy\", \"watch\"].forEach((taskName) => {\n const task = project.tasks.tryFind(taskName);\n if (task) {\n task.reset();\n task.say(\n \"Generic task is disabled. Please use the specific task for your deployment target.\",\n );\n }\n });\n\n /**\n * Redefine Synth here\n *\n * Deploy and watch get reconfigured per deployment target.\n * @see addDeploymentTarget()\n */\n this.configureSynthTask();\n }\n\n /*****************************************************************************\n *\n * Target filter helpers\n *\n * Return various targets for deployment scripts to use.\n *\n ****************************************************************************/\n\n /**\n * @returns All production deployment targets.\n */\n public get prodTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.PROD,\n );\n }\n public get prodTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.PROD && target.ciDeployment,\n );\n }\n public get prodTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.PROD && target.localDeployment,\n );\n }\n\n /**\n *\n * @returns All stage deployment targets.\n */\n public get stageTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.STAGE,\n );\n }\n public get stageTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.STAGE && target.ciDeployment,\n );\n }\n public get stageTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.STAGE && target.localDeployment,\n );\n }\n\n /**\n *\n * @returns All dev deployment targets.\n */\n public get devTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.DEV,\n );\n }\n public get devTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.DEV && target.ciDeployment,\n );\n }\n public get devTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.DEV && target.localDeployment,\n );\n }\n\n /*****************************************************************************\n *\n * Synth Tasks\n *\n * - Configure synth task to use the branch name\n * - Change the output location for easier workflows.\n *\n ****************************************************************************/\n\n private configureSynthTask = (): void => {\n this.project.tasks.tryFind(\"synth\")?.reset(`rm -rf ${this.cdkOut}`);\n this.project.tasks\n .tryFind(\"synth\")\n ?.exec(`cdk synth --output ${this.cdkOut}`, { env: this.env });\n\n this.project.tasks.tryFind(\"synth:silent\")?.reset(`rm -rf ${this.cdkOut}`);\n this.project.tasks\n .tryFind(\"synth:silent\")\n ?.exec(`cdk synth -q --output ${this.cdkOut}`, { env: this.env });\n };\n\n preSynthesize(): void {\n super.preSynthesize();\n\n /**\n * If turbo's active we should ensure the post compile task\n * is configured to consider the cdk output directory in it's root location.\n */\n if (TurboRepo.of(this.project)) {\n const turbo = TurboRepo.of(this.project)!;\n turbo.postCompileTask?.outputs.push(join(this.cdkOut, \"**\"));\n }\n }\n}\n","import { Component, Project } from \"projen/lib\";\n\n/**\n * Each of the below options corresponds to a task property found here:\n * * https://turborepo.com/docs/reference/configuration#defining-tasks\n */\nexport interface TurboRepoTaskOptions {\n readonly name: string;\n readonly dependsOn?: Array<string>;\n readonly env?: Array<string>;\n readonly passThroughEnv?: Array<string>;\n readonly outputs?: Array<string>;\n readonly cache?: boolean;\n readonly inputs?: Array<string>;\n readonly outputLogs?:\n | \"full\"\n | \"hash-only\"\n | \"new-only\"\n | \"errors-only\"\n | \"none\";\n readonly persistent?: boolean;\n readonly interactive?: boolean;\n}\n\nexport class TurboRepoTask extends Component {\n public readonly name: string;\n public dependsOn: Array<string>;\n public readonly env: Array<string>;\n public readonly passThroughEnv: Array<string>;\n public outputs: Array<string>;\n public cache: boolean;\n public inputs: Array<string>;\n public readonly outputLogs:\n | \"full\"\n | \"hash-only\"\n | \"new-only\"\n | \"errors-only\"\n | \"none\";\n public readonly persistent: boolean;\n public readonly interactive: boolean;\n\n /**\n * Include this task in turbo.json output?\n */\n public isActive: boolean;\n\n constructor(\n public readonly project: Project,\n options: TurboRepoTaskOptions,\n ) {\n super(project);\n\n this.name = options.name;\n this.dependsOn = options.dependsOn ?? [];\n this.env = options.env ?? [];\n this.passThroughEnv = options.passThroughEnv ?? [];\n this.outputs = options.outputs ?? [];\n this.cache = options.cache ?? true;\n this.inputs = [\n ...(options.inputs ?? []),\n // rerun if projen config changes\n \".projen/**\",\n // ignore mac files\n \"!.DS_Store\",\n \"!**/.DS_Store\",\n ];\n this.outputLogs = options.outputLogs ?? \"new-only\";\n this.persistent = options.persistent ?? false;\n this.interactive = options.interactive ?? false;\n this.isActive = true;\n }\n\n public taskConfig(): Record<string, any> {\n return {\n dependsOn: this.dependsOn,\n env: this.env,\n passThroughEnv: this.passThroughEnv,\n outputs: this.outputs,\n cache: this.cache,\n inputs: this.inputs,\n outputLogs: this.outputLogs,\n persistent: this.persistent,\n interactive: this.interactive,\n };\n }\n}\n","import { Component, FileBase, JsonFile, Project, Task } from \"projen/lib\";\nimport { BuildWorkflowOptions } from \"projen/lib/build\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { NodeProject } from \"projen/lib/javascript\";\nimport { TurboRepoTask } from \"./turbo-repo-task\";\n\n/*******************************************************************************\n *\n * Turbo Repo Config\n *\n ******************************************************************************/\n\nexport const ROOT_TURBO_TASK_NAME = \"turbo:build\";\nexport const ROOT_CI_TASK_NAME = \"build:all\";\n\nexport interface RemoteCacheOptions {\n /**\n * Local profile name to use when fetching the cache endpoint and token.\n */\n readonly profileName: string;\n\n /**\n * OIDC role to assume when fetching the cache endpoint and token.\n */\n readonly oidcRole: string;\n\n /**\n * Name for the params used to store the cache endpoint.\n */\n readonly endpointParamName: string;\n\n /**\n * Name for the params used to store the cache's API token.\n */\n readonly tokenParamName: string;\n\n /**\n * team name used in remote cache commands\n */\n readonly teamName: string;\n}\n\nexport interface TurboRepoOptions {\n /**\n * Version of turborepo to use.\n *\n * @default: specified in versions file\n */\n readonly turboVersion?: string;\n\n /**\n * Extend from the root turbo.json to create specific configuration for a package using Package Configurations.\n *\n * The only valid value for extends is [\"//\"] to inherit configuration from the root turbo.json.\n * If extends is used in the root turbo.json, it will be ignored.\n *\n * https://turbo.build/repo/docs/reference/configuration#extends\n */\n readonly extends?: Array<string>;\n\n /**\n * A list of globs that you want to include in all task hashes. If any file matching these globs changes, all tasks will miss cache. Globs are relative to the location of turbo.json.\n *\n * By default, all files in source control in the Workspace root are included in the global hash.\n *\n * Globs must be in the repository's source control root. Globs outside of the repository aren't supported.\n *\n * https://turbo.build/repo/docs/reference/configuration#globaldependencies\n */\n readonly globalDependencies?: Array<string>;\n\n /**\n * A list of environment variables that you want to impact the hash of all tasks. Any change to these environment variables will cause all tasks to miss cache.\n *\n * For more on wildcard and negation syntax, see the env section.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalenv\n */\n readonly globalEnv?: Array<string>;\n\n /**\n * A list of environment variables that you want to make available to tasks.\n * Using this key opts all tasks into Strict\n * Environment Variable Mode.\n *\n * Additionally, Turborepo has a built-in set of global passthrough variables\n * for common cases, like operating system environment variables. This\n * includes variables like HOME, PATH, APPDATA, SHELL, PWD, and more. The full\n * list can be found in the source code.\n *\n * Passthrough values do not contribute to hashes for caching\n *\n * If you want changes in these variables to cause cache misses, you will need\n * to include them in env or globalEnv.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalpassthroughenv\n */\n readonly globalPassThroughEnv?: Array<string>;\n\n /**\n * @default: \"stream\"\n *\n * Select a terminal UI for the repository.\n *\n * \"tui\" allows for viewing each log at once and interacting with the task.\n * \"stream\" outputs logs as they come in and is not interactive.\n *\n * https://turbo.build/repo/docs/reference/configuration#ui\n */\n readonly ui?: \"tui\" | \"stream\";\n\n /**\n * @default: false\n *\n * Turborepo uses your repository's lockfile to determine caching behavior,\n * Package Graphs, and more. Because of this, we use the packageManager field\n * to help you stabilize your Turborepo.\n *\n * To help with incremental migration or in situations where you can't use\n * the packageManager field, you may use\n * --dangerously-disable-package-manager-check to opt out of this check and\n * assume the risks of unstable lockfiles producing unpredictable behavior.\n * When disabled, Turborepo will attempt a best-effort discovery of the\n * intended package manager meant for the repository.\n *\n * https://turbo.build/repo/docs/reference/configuration#dangerouslydisablepackagemanagercheck\n */\n readonly dangerouslyDisablePackageManagerCheck?: boolean;\n\n /**\n * @default: \".turbo/cache\"\n *\n * Specify the filesystem cache directory.\n *\n * https://turbo.build/repo/docs/reference/configuration#cachedir\n */\n readonly cacheDir?: string;\n\n /**\n * @default: true\n *\n * Turborepo runs a background process to pre-calculate some expensive\n * operations. This standalone process (daemon) is a performance optimization,\n * and not required for proper functioning of turbo.\n *\n * https://turbo.build/repo/docs/reference/configuration#daemon\n */\n readonly daemon?: boolean;\n\n /**\n * @default: \"strict\"\n *\n * Turborepo's Environment Modes allow you to control which environment\n * variables are available to a task at runtime:\n *\n *\"strict\": Filter environment variables to only those that are specified\n * in the env and globalEnv keys in turbo.json.\n *\n * \"loose\": Allow all environment variables for the process to be available.\n *\n * https://turbo.build/repo/docs/reference/configuration#envmode\n */\n readonly envMode?: string;\n\n /*****************************************************************************\n *\n * Cache Settings\n *\n ****************************************************************************/\n\n /**\n * Cache settings, if using remote cache.\n */\n readonly remoteCacheOptions?: RemoteCacheOptions;\n\n /**\n * Env Args that will bre added to turbo's build:all task\n *\n * @default: {}\n */\n readonly buildAllTaskEnvVars?: Record<string, string>;\n\n /*****************************************************************************\n *\n * Tasks - Optionally define a different projen task for one of the lifecycle\n * steps.\n *\n ****************************************************************************/\n\n /**\n * Pre compile task\n *\n * @default: \"pre-compile\"\n */\n readonly preCompileTask?: Task;\n\n /**\n * Compile task\n *\n * @default: \"compile\"\n */\n readonly compileTask?: Task;\n\n /**\n * Post compile task\n *\n * @default: \"post-compile\"\n */\n readonly postCompileTask?: Task;\n\n /**\n * Test task\n *\n * @default: \"test\"\n */\n readonly testTask?: Task;\n\n /**\n * Package task\n *\n * @default: \"package\"\n */\n readonly packageTask?: Task;\n}\n\nexport class TurboRepo extends Component {\n /**\n * Static method to discovert turbo in a project.\n */\n public static of(project: Project): TurboRepo | undefined {\n const isDefined = (c: Component): c is TurboRepo => c instanceof TurboRepo;\n return project.components.find(isDefined);\n }\n\n public static buildWorkflowOptions = (\n remoteCacheOptions: RemoteCacheOptions,\n ): Partial<BuildWorkflowOptions> => {\n return {\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n },\n permissions: {\n contents: JobPermission.WRITE,\n idToken: JobPermission.WRITE,\n },\n preBuildSteps: [\n {\n name: \"AWS Creds for SSM\",\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n [\"role-to-assume\"]: remoteCacheOptions.oidcRole,\n [\"aws-region\"]: \"us-east-1\",\n [\"role-duration-seconds\"]: \"900\",\n },\n },\n ],\n };\n };\n\n /**\n * Version of turborepo to use.\n */\n public readonly turboVersion: string;\n\n /**\n * Extend from the root turbo.json to create specific configuration for a package using Package Configurations.\n *\n * The only valid value for extends is [\"//\"] to inherit configuration from the root turbo.json.\n * If extends is used in the root turbo.json, it will be ignored.\n *\n * https://turbo.build/repo/docs/reference/configuration#extends\n */\n public readonly extends: Array<string>;\n\n /**\n * A list of globs that you want to include in all task hashes. If any file matching these globs changes, all tasks will miss cache. Globs are relative to the location of turbo.json.\n *\n * By default, all files in source control in the Workspace root are included in the global hash.\n *\n * Globs must be in the repository's source control root. Globs outside of the repository aren't supported.\n *\n * https://turbo.build/repo/docs/reference/configuration#globaldependencies\n */\n public readonly globalDependencies: Array<string>;\n\n /**\n * A list of environment variables that you want to impact the hash of all tasks. Any change to these environment variables will cause all tasks to miss cache.\n *\n * For more on wildcard and negation syntax, see the env section.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalenv\n */\n public readonly globalEnv: Array<string>;\n\n /**\n * A list of environment variables that you want to make available to tasks.\n * Using this key opts all tasks into Strict\n * Environment Variable Mode.\n *\n * Additionally, Turborepo has a built-in set of global passthrough variables\n * for common cases, like operating system environment variables. This\n * includes variables like HOME, PATH, APPDATA, SHELL, PWD, and more. The full\n * list can be found in the source code.\n *\n * Passthrough values do not contribute to hashes for caching\n *\n * If you want changes in these variables to cause cache misses, you will need\n * to include them in env or globalEnv.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalpassthroughenv\n */\n public readonly globalPassThroughEnv: Array<string>;\n\n /**\n * @default: \"stream\"\n *\n * Select a terminal UI for the repository.\n *\n * \"tui\" allows for viewing each log at once and interacting with the task.\n * \"stream\" outputs logs as they come in and is not interactive.\n *\n * https://turbo.build/repo/docs/reference/configuration#ui\n */\n public readonly ui: \"tui\" | \"stream\";\n\n /**\n * @default: false\n *\n * Turborepo uses your repository's lockfile to determine caching behavior,\n * Package Graphs, and more. Because of this, we use the packageManager field\n * to help you stabilize your Turborepo.\n *\n * To help with incremental migration or in situations where you can't use\n * the packageManager field, you may use\n * --dangerously-disable-package-manager-check to opt out of this check and\n * assume the risks of unstable lockfiles producing unpredictable behavior.\n * When disabled, Turborepo will attempt a best-effort discovery of the\n * intended package manager meant for the repository.\n *\n * https://turbo.build/repo/docs/reference/configuration#dangerouslydisablepackagemanagercheck\n */\n public readonly dangerouslyDisablePackageManagerCheck: boolean;\n\n /**\n * @default: \".turbo/cache\"\n *\n * Specify the filesystem cache directory.\n *\n * https://turbo.build/repo/docs/reference/configuration#cachedir\n */\n public readonly cacheDir: string;\n\n /**\n * @default: true\n *\n * Turborepo runs a background process to pre-calculate some expensive\n * operations. This standalone process (daemon) is a performance optimization,\n * and not required for proper functioning of turbo.\n *\n * https://turbo.build/repo/docs/reference/configuration#daemon\n */\n public readonly daemon: boolean;\n\n /**\n * @default: \"strict\"\n *\n * Turborepo's Environment Modes allow you to control which environment\n * variables are available to a task at runtime:\n *\n *\"strict\": Filter environment variables to only those that are specified\n * in the env and globalEnv keys in turbo.json.\n *\n * \"loose\": Allow all environment variables for the process to be available.\n *\n * https://turbo.build/repo/docs/reference/configuration#envmode\n */\n public readonly envMode: string;\n\n /*****************************************************************************\n *\n * Cache Settings\n *\n ****************************************************************************/\n\n /**\n * Cache settings, if using remote cache.\n */\n public readonly remoteCacheOptions?: RemoteCacheOptions;\n\n /**\n * is this the root project?\n */\n public readonly isRootProject: boolean;\n\n /**\n * Turbo's build:all task at the root of the monorepo.\n *\n * This is a normal projen task that runs the root turbo task.\n */\n public readonly buildAllTask?: Task;\n\n /**\n * Main turbo:build task\n *\n * This is a special Turbo task\n */\n public readonly buildTask: TurboRepoTask;\n\n /**\n * pre compile task\n */\n public readonly preCompileTask?: TurboRepoTask;\n\n /**\n * compile task\n */\n public readonly compileTask?: TurboRepoTask;\n\n /**\n * post compile task\n */\n public readonly postCompileTask?: TurboRepoTask;\n\n /**\n * Test task\n */\n public readonly testTask?: TurboRepoTask;\n\n /**\n * Package task\n */\n public readonly packageTask?: TurboRepoTask;\n\n /**\n * Sub-Tasks to run\n */\n public readonly tasks: Array<TurboRepoTask> = [];\n\n /**\n * Env Args that will bre added to turbo's build:all task\n */\n public readonly buildAllTaskEnvVars: Record<string, string>;\n\n constructor(\n public readonly project: NodeProject,\n options: TurboRepoOptions = {},\n ) {\n super(project);\n\n this.turboVersion = options.turboVersion ?? \"catalog:\";\n this.isRootProject = project === project.root;\n\n /**\n * Add turborepo package to root project.\n */\n if (this.isRootProject) {\n project.addDevDeps(`turbo@${this.turboVersion}`);\n }\n\n /**\n * Ignore the working cache for turbo.\n */\n project.gitignore.addPatterns(\"/.turbo\");\n project.npmignore?.addPatterns(\"/.turbo/\");\n\n /***************************************************************************\n *\n * Set some default options\n *\n **************************************************************************/\n\n this.extends = options.extends ?? (this.isRootProject ? [] : [\"//\"]);\n this.globalDependencies = options.globalDependencies ?? [];\n this.globalEnv = options.globalEnv ?? [];\n this.globalPassThroughEnv = options.globalPassThroughEnv ?? [];\n this.ui = options.ui ?? \"stream\";\n this.dangerouslyDisablePackageManagerCheck =\n options.dangerouslyDisablePackageManagerCheck ?? false;\n this.cacheDir = options.cacheDir ?? \".turbo/cache\";\n this.daemon = options.daemon ?? true;\n this.envMode = options.envMode ?? \"strict\";\n this.remoteCacheOptions = options.remoteCacheOptions;\n this.buildAllTaskEnvVars = options.buildAllTaskEnvVars ?? {};\n\n /***************************************************************************\n *\n * Turbo Build Task\n *\n * All turbo configs contain a turbo build task.\n *\n **************************************************************************/\n\n /**\n * The turbo entry point definition for the turbo:build task. This exists\n * in each project and is written tot he turbo.json file. This task is not\n * a projen task or a Node task.\n */\n this.buildTask = new TurboRepoTask(this.project, {\n name: ROOT_TURBO_TASK_NAME,\n dependsOn: this.isRootProject ? [`^${ROOT_TURBO_TASK_NAME}`] : [],\n });\n\n /***************************************************************************\n *\n * Turbo Build All Task\n *\n * The Projen entry point. This only exists in the root and is a projen\n * task that can be run using pnpm.\n *\n * - Turns off telemetry\n * - Runs root turbo task to build all sub-projects.\n *\n **************************************************************************/\n\n if (this.isRootProject) {\n /**\n * Create and configure the build all task.\n */\n this.buildAllTask = this.project.tasks.addTask(ROOT_CI_TASK_NAME, {\n description:\n \"Root build followed by sub-project builds. Mimics the CI build process in one step.\",\n });\n this.buildAllTask.exec(\"turbo telemetry disable\");\n\n /**\n * Any env vars that may need to be added to the build all task.\n */\n if (this.buildAllTaskEnvVars) {\n Object.entries(this.buildAllTaskEnvVars).forEach(([name, value]) => {\n this.addGlobalEnvVar(name, value);\n });\n }\n\n /**\n * No remote cache in use, so run the root turbo task to build all\n * sub-projects locally.\n */\n if (!this.remoteCacheOptions) {\n this.buildAllTask.exec(\n `turbo ${ROOT_TURBO_TASK_NAME} --summarize --concurrency=10`,\n );\n } else {\n /**\n * Remote cache in use, so run the root turbo task to build all\n * sub-projects using the remote cache.\n */\n this.buildAllTask.exec(\n `turbo turbo:build --summarize --concurrency=10 --cache=remote:rw --api=$TURBO_ENDPOINT --token=$TURBO_TOKEN --team=${this.remoteCacheOptions.teamName}`,\n {\n condition: '[ ! -n \"$CI\" ]',\n env: {\n TURBO_ENDPOINT: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.endpointParamName} --query Parameter.Value --output text --profile ${this.remoteCacheOptions.profileName})`,\n TURBO_TOKEN: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.tokenParamName} --query Parameter.Value --output text --profile ${this.remoteCacheOptions.profileName})`,\n },\n },\n );\n // running in CI, We'll depend on OIDC auth.\n this.buildAllTask.exec(\n `turbo turbo:build --summarize --concurrency=10 --cache=remote:rw --api=$TURBO_ENDPOINT --token=$TURBO_TOKEN --team=${this.remoteCacheOptions.teamName}`,\n {\n condition: '[ -n \"$CI\" ]',\n env: {\n TURBO_ENDPOINT: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.endpointParamName} --query Parameter.Value --output text)`,\n TURBO_TOKEN: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.tokenParamName} --query Parameter.Value --output text)`,\n },\n },\n );\n }\n }\n\n /**\n * SUB-PROJECT\n *\n * Creates tasks for the typical lifecycle for all project projects.\n */\n if (!this.isRootProject) {\n /**\n * All generated files in the project. Include these as inputs to the\n * compile related tasks.\n */\n const generatedFiles = this.project.components\n .filter((c): c is FileBase => c instanceof FileBase)\n .map((c) => c.path);\n\n this.preCompileTask = new TurboRepoTask(project, {\n name: options.preCompileTask?.name ?? \"pre-compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.compileTask = new TurboRepoTask(project, {\n name: options.compileTask?.name ?? \"compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.postCompileTask = new TurboRepoTask(project, {\n name: options.postCompileTask?.name ?? \"post-compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.testTask = new TurboRepoTask(project, {\n name: options.testTask?.name ?? \"test\",\n });\n this.packageTask = new TurboRepoTask(project, {\n name: options.packageTask?.name ?? \"package\",\n inputs: [\".npmignore\"],\n });\n this.tasks.push(\n this.preCompileTask,\n this.compileTask,\n this.postCompileTask,\n this.testTask,\n this.packageTask,\n );\n }\n }\n\n /**\n * Add an env var to the global env vars for all tasks.\n * This will also become an input for the build:all task cache at the root.\n */\n public addGlobalEnvVar(name: string, value: string) {\n /**\n * Add env var to global task env\n */\n this.buildAllTask?.env(name, value);\n\n /**\n * Add to global env vars for all tasks.\n */\n if (this.isRootProject) {\n this.globalEnv.push(name);\n }\n }\n\n public activateBranchNameEnvVar() {\n this.addGlobalEnvVar(\n \"BRANCH_NAME\",\n \"${BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}\",\n );\n }\n\n preSynthesize(): void {\n /**\n * Add any local workspace specific deps to dependsOn so that we know\n * compile has finished before attempting to use any distribution artifacts.\n *\n * Do this in presynth so that we can be sure all project dependencies have\n * been defined first.\n */\n let nextDependsOn = this.project.deps.all\n .filter((d) => d.version === \"workspace:*\")\n .map((d) => [d.name, ROOT_TURBO_TASK_NAME].join(\"#\"));\n\n /**\n * Loop over all projen tasks and their corresponding turbo task\n * definitions. Chain them together using dependsOn, along with any outside\n * package dependencies.\n */\n if (!this.isRootProject) {\n (\n [\n [this.project.preCompileTask, this.preCompileTask],\n [this.project.compileTask, this.compileTask],\n [this.project.postCompileTask, this.postCompileTask],\n [this.project.testTask, this.testTask],\n [this.project.packageTask, this.packageTask],\n ] as Array<[Task, TurboRepoTask]>\n ).forEach(([pjTask, turboTask]) => {\n /**\n * If steps exist chain using dependsOn\n */\n if (pjTask && turboTask && pjTask.steps.length > 0) {\n if (nextDependsOn.length > 0) {\n turboTask.dependsOn.push(...nextDependsOn);\n }\n nextDependsOn = [turboTask.name];\n\n /**\n * Otherwise, if a task doesn't do anything, deactivate it.\n */\n } else {\n turboTask.isActive = false;\n }\n });\n\n /**\n * Main build entry point depends on whatever was last.\n */\n this.buildTask.dependsOn.push(...nextDependsOn);\n }\n\n /**\n * The name for the turbo config file.\n */\n const fileName: string = \"turbo.json\";\n\n /**\n * Ensure that turbo config doesn't end up in any package distributions.\n */\n this.project.addPackageIgnore(fileName);\n\n /**\n * The content of this YAML file will be resolved at synth time. By then,\n * any sub-projects will be defined and this will be a complete list.\n */\n new JsonFile(this.project, fileName, {\n obj: {\n extends: this.extends.length ? this.extends : undefined,\n globalDependencies:\n this.isRootProject && this.globalDependencies.length\n ? this.globalDependencies\n : undefined,\n globalEnv:\n this.isRootProject && this.globalEnv.length\n ? this.globalEnv\n : undefined,\n globalPassThroughEnv:\n this.isRootProject && this.globalPassThroughEnv.length\n ? this.globalPassThroughEnv\n : undefined,\n ui: this.isRootProject ? this.ui : undefined,\n dangerouslyDisablePackageManagerCheck: this.isRootProject\n ? this.dangerouslyDisablePackageManagerCheck\n : undefined,\n cacheDir: this.isRootProject ? this.cacheDir : undefined,\n daemon: this.isRootProject ? this.daemon : undefined,\n envMode: this.isRootProject ? this.envMode : undefined,\n /**\n * All tasks\n */\n tasks: this.tasks\n .filter((task) => task.isActive)\n .reduce(\n (acc, task) => {\n acc[task.name] = {\n ...task.taskConfig(),\n };\n return acc;\n },\n {\n [this.buildTask.name]: { ...this.buildTask.taskConfig() },\n } as Record<string, any>,\n ),\n },\n });\n\n super.preSynthesize();\n }\n}\n","// eslint-disable-next-line import/no-extraneous-dependencies\nimport {\n AWS_STAGE_TYPE,\n AwsEnvironmentType,\n AwsStageType,\n DEPLOYMENT_TARGET_ROLE,\n DeploymentTargetRoleType,\n} from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { AwsDeploymentConfig } from \"./aws-deployment-config\";\nimport { GitBranch } from \"../git\";\n\n/*******************************************************************************\n *\n * AWS Deployment Configuration\n *\n * A single deployment target that CDK applications can be deployed into.\n *\n ******************************************************************************/\n\n/**\n * Represents the configuration for local deployment in AWS.\n */\nexport interface AwsLocalDeploymentConfig {\n /**\n * The AWS profile (in ~/.aws/config) to use for local deployment.\n *\n * @default generated dynamically based role name, account and region\n */\n readonly profile?: string;\n\n /**\n * Named Role used to conduct local deployments.\n *\n * @default \"poweruseraccess\"\n */\n readonly roleName?: string;\n\n /**\n * The pattern used to identify stacks to deploy in CI deployments.\n *\n * @default *-${account}-${region}\n */\n readonly stackPattern?: string;\n}\n\nexport interface CiDeploymentConfig {\n /**\n * The OIDC IAM Role to assume for CI deployments.\n */\n readonly roleArn: string;\n\n /**\n * The pattern used to identify stacks to deploy in CI deployments.\n *\n * @default *-${account}-${region}\n */\n readonly stackPattern?: string;\n}\n\n/**\n * Represents a deployment target in AWS, including account and region, and\n * branches allowed to deploy to this target.\n */\nexport interface AwsDeploymentTargetOptions {\n /**\n * The account name for the deployment target.\n */\n readonly account: string;\n\n /**\n * The AWS region for the deployment target.\n */\n readonly region: string;\n\n /**\n * AWS deployment type, such as dev, stage, or prod.\n *\n * @default 'dev'\n */\n readonly awsStageType?: AwsStageType;\n\n /**\n * Deployment target role: whether this (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n *\n * @default 'primary'\n */\n readonly deploymentTargetRole?: DeploymentTargetRoleType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use `deploymentTargetRole` instead. This property is maintained for backward compatibility.\n * @default 'primary'\n */\n readonly awsEnvironmentType?: AwsEnvironmentType;\n\n /**\n * The AWS profile to use for this deployment target.\n *\n * @default ['main'] when prod release type, ['feature/*'] when dev type\n */\n readonly branches?: Array<GitBranch>;\n\n /**\n * Can this deployment target be used for local development?\n *\n * @default true for dev environments, false for prod environments\n */\n readonly localDeployment?: boolean;\n\n /**\n * Configuration when deploying to this target locally.\n */\n readonly localDeploymentConfig?: AwsLocalDeploymentConfig;\n\n /**\n * Can this deployment target be used in CI deployments?\n *\n * @default false\n */\n readonly ciDeployment?: boolean;\n\n /*\n * Configuration when deploying to this target in CI.\n\n */\n readonly ciDeploymentConfig?: CiDeploymentConfig;\n}\n\nexport class AwsDeploymentTarget extends Component {\n /**\n * Static method to discovert targets in a project.\n */\n public static of(\n project: AwsCdkTypeScriptApp,\n ): Array<AwsDeploymentTarget> | undefined {\n const isDefined = (c: Component): c is AwsDeploymentTarget =>\n c instanceof AwsDeploymentTarget;\n return project.components.filter(isDefined);\n }\n\n /**\n * The account name for the deployment target.\n */\n public account: string;\n\n /**\n * The AWS region for the deployment target.\n */\n public region: string;\n\n /**'\n * AWS stage type, such as dev, stage, or prod.\n *\n * @default 'dev'\n */\n public awsStageType: AwsStageType;\n\n /**\n * Deployment target role: whether this (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n *\n * @default 'primary'\n */\n public deploymentTargetRole: DeploymentTargetRoleType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use `deploymentTargetRole` instead. This property is maintained for backward compatibility.\n * @default 'primary'\n */\n public awsEnvironmentType: AwsEnvironmentType;\n\n /**\n * The AWS profile to use for this deployment target.\n *\n * @default ['main'] when prod release type, ['feature/*'] when dev type\n */\n public branches: Array<GitBranch> = [];\n\n /**\n * Can this deployment target be used for local development?\n *\n * @default true for dev environments, false for prod environments\n */\n public localDeployment?: boolean;\n\n /**\n * Configuration when deploying to this target locally.\n */\n public localDeploymentConfig?: AwsLocalDeploymentConfig;\n\n /**\n * Can this deployment target be used in CI deployments?\n *\n * @default false\n */\n public ciDeployment?: boolean;\n\n /*\n * Configuration when deploying to this target in CI.\n */\n public ciDeploymentConfig?: Required<CiDeploymentConfig>;\n\n /**\n * Configuration for the CDK output directory for this deployment target.\n */\n public awsDeploymentConfig: AwsDeploymentConfig;\n\n constructor(\n project: AwsCdkTypeScriptApp,\n options: AwsDeploymentTargetOptions,\n ) {\n super(project);\n\n /**\n * Set target region and account.\n */\n this.account = options.account;\n this.region = options.region;\n\n /**\n * Set default type\n */\n this.awsStageType = options.awsStageType || AWS_STAGE_TYPE.DEV;\n\n /**\n * Set deployment target role (preferred) or fall back to deprecated awsEnvironmentType.\n */\n const role =\n options.deploymentTargetRole ??\n options.awsEnvironmentType ??\n DEPLOYMENT_TARGET_ROLE.PRIMARY;\n this.deploymentTargetRole = role;\n this.awsEnvironmentType = role;\n\n /**\n * Set default Branches\n */\n\n this.branches =\n options.branches ??\n (this.awsStageType === AWS_STAGE_TYPE.PROD\n ? [\n {\n branch: \"main\",\n },\n ]\n : [\n {\n branch: \"feature/*\",\n },\n ]);\n\n /**\n * Set default for local deployment\n */\n this.localDeployment =\n options.localDeployment ?? this.awsStageType === AWS_STAGE_TYPE.DEV;\n\n /**\n * Some default configurations for local deployments.\n */\n if (this.localDeployment) {\n const roleName =\n options.localDeploymentConfig?.roleName?.toLowerCase() ||\n \"poweruseraccess\";\n const profile =\n options.localDeploymentConfig?.profile ||\n `${roleName}-${this.awsStageType}-${this.account}-${this.region}`;\n\n const stackPattern =\n options.localDeploymentConfig?.stackPattern ||\n `${this.awsStageType}/${this.awsEnvironmentType}/*-${this.account}-${this.region}`;\n\n this.localDeploymentConfig = {\n profile,\n roleName,\n stackPattern,\n ...options.localDeploymentConfig,\n };\n }\n\n /**\n * Set CI deployment default\n */\n this.ciDeployment = options.ciDeployment ?? false;\n\n /**\n * Some defaults for CI deployments.\n */\n if (this.ciDeployment) {\n const roleArn =\n options.ciDeploymentConfig?.roleArn ||\n `arn:aws:iam::${this.account}:role/GitHubDeployer}`;\n\n const stackPattern =\n options.ciDeploymentConfig?.stackPattern ||\n `${this.awsStageType}/${this.awsEnvironmentType}/*-${this.account}-${this.region}`;\n\n this.ciDeploymentConfig = {\n roleArn,\n stackPattern,\n ...options.ciDeploymentConfig,\n };\n }\n\n /**\n * Find or create CDK folder config for this project.\n */\n this.awsDeploymentConfig =\n AwsDeploymentConfig.of(project) || new AwsDeploymentConfig(project);\n\n /**\n * Add the target to the deployment targets array.\n */\n this.awsDeploymentConfig.awsDeploymentTargets.push(this);\n\n // Deploy tasks are configured per target.\n this.configureDeployTask();\n\n // Watch tasks are configured per target.\n this.configureWatchTask();\n }\n\n /*****************************************************************************\n *\n * Deploy Tasks\n *\n * - If local deploy, add a deploy task.\n *\n ****************************************************************************/\n\n private configureDeployTask = (): void => {\n if (this.localDeployment) {\n const taskName = [\n \"deploy\",\n this.awsStageType,\n this.account,\n this.region,\n ].join(\":\");\n const deployTask = this.project.tasks.addTask(taskName, {\n env: this.awsDeploymentConfig.env,\n });\n deployTask.exec(\n `cdk deploy --lookups=false --require-approval=never --profile=${this.localDeploymentConfig?.profile} --app=${this.awsDeploymentConfig.cdkOut} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n }\n };\n\n /*****************************************************************************\n *\n * Watch tasks\n *\n * - Configure watch task to use the branch name\n * - configure watch task to use the correct synth output location.\n *\n ****************************************************************************/\n\n private configureWatchTask = (): void => {\n if (this.localDeployment) {\n const taskName = [\n \"watch\",\n this.awsStageType,\n this.account,\n this.region,\n ].join(\":\");\n const watchTask = this.project.tasks.addTask(taskName, {\n env: this.awsDeploymentConfig.env,\n });\n\n // update the synth first\n const synthSilent = this.project.tasks.tryFind(\"synth:silent\");\n if (synthSilent) {\n watchTask.spawn(synthSilent);\n }\n\n // do a normal deploy\n watchTask.exec(\n `cdk deploy --lookups=false --require-approval=never --profile=${this.localDeploymentConfig?.profile} --app=${this.awsDeploymentConfig.cdkOut} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n\n // watch for changes and log output\n watchTask.exec(\n `cdk watch --lookups=false --require-approval=never --hotswap --profile=${this.localDeploymentConfig?.profile} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n }\n };\n}\n","const NPM_REGISTRY = \"https://registry.npmjs.org\";\n\n/**\n * Metadata for a package from the npm registry. Only the fields we use are typed.\n *\n * @see https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md\n */\ninterface NpmPackageMetadata {\n name?: string;\n \"dist-tags\"?: { latest?: string };\n time?: Record<string, string>;\n versions?: Record<string, unknown>;\n}\n\n/**\n * Returns true if the version has a semver prerelease segment (e.g. -canary, -alpha, -beta).\n * Full releases like 1.2.3 or 1.2.3+build.1 return false.\n */\nfunction isPrerelease(version: string): boolean {\n const v = version.replace(/^v/, \"\");\n return /^\\d+\\.\\d+\\.\\d+-/.test(v);\n}\n\n/**\n * Compares two semver-like version strings (e.g. \"1.2.3\").\n * Returns negative if a < b, positive if a > b, 0 if equal.\n * Prerelease segments are treated as less than release.\n */\nfunction compareVersions(a: string, b: string): number {\n const parse = (v: string): number[] => {\n const parts = v.replace(/^v/, \"\").split(/[-+]/)[0].split(\".\");\n return parts.map((p) => {\n const n = parseInt(p, 10);\n return Number.isNaN(n) ? 0 : n;\n });\n };\n const pa = parse(a);\n const pb = parse(b);\n const len = Math.max(pa.length, pb.length);\n for (let i = 0; i < len; i++) {\n const na = pa[i] ?? 0;\n const nb = pb[i] ?? 0;\n if (na !== nb) return na - nb;\n }\n return 0;\n}\n\n/**\n * Returns the latest full-release version of an npm package that has been\n * published for at least `minimumReleaseAgeMinutes` minutes. Prefers the\n * version indicated by the registry's \"latest\" dist-tag when it is a full\n * release: if that version's publish time is in the registry and old enough,\n * it is used; if it is not in the registry's \"time\" object (e.g. truncated\n * for large packages), the dist-tag is still used so npm's \"latest\" is\n * followed. When the dist-tag version is too new (in time but not old enough),\n * we fall back to the highest full-release version that is old enough and\n * ≤ latest (e.g. latest 2.x that's old enough, not 3.0.0). Prerelease\n * versions are excluded. Returns null if `time` is missing or no version is\n * eligible.\n *\n * @param packageName - npm package name (e.g. \"projen\").\n * @param minimumReleaseAgeMinutes - minimum age in minutes (e.g. 1440 for 24h).\n * @returns The latest eligible version string, or null.\n */\nexport async function getLatestEligibleVersion(\n packageName: string,\n minimumReleaseAgeMinutes: number,\n): Promise<string | null> {\n const url = `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`;\n let res: Response;\n try {\n res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n if (!res.ok) return null;\n let data: NpmPackageMetadata;\n try {\n data = (await res.json()) as NpmPackageMetadata;\n } catch {\n return null;\n }\n const time = data.time;\n if (!time || typeof time !== \"object\") return null;\n\n const nowMs = Date.now();\n const minAgeMs = minimumReleaseAgeMinutes * 60 * 1000;\n\n const distTagLatest = data[\"dist-tags\"]?.latest;\n if (distTagLatest && !isPrerelease(distTagLatest)) {\n const publishedAtStr = time[distTagLatest];\n if (typeof publishedAtStr === \"string\") {\n const publishedAt = Date.parse(publishedAtStr);\n if (!Number.isNaN(publishedAt) && nowMs - publishedAt >= minAgeMs) {\n return distTagLatest;\n }\n } else {\n return distTagLatest;\n }\n }\n\n const versionTimestamps: { version: string; publishedAt: number }[] = [];\n for (const [key, value] of Object.entries(time)) {\n if (key === \"created\" || key === \"modified\" || typeof value !== \"string\") {\n continue;\n }\n if (isPrerelease(key)) continue;\n const publishedAt = Date.parse(value);\n if (Number.isNaN(publishedAt)) continue;\n const ageMs = nowMs - publishedAt;\n if (ageMs >= minAgeMs) {\n versionTimestamps.push({ version: key, publishedAt });\n }\n }\n\n if (versionTimestamps.length === 0) return null;\n\n let candidates = versionTimestamps;\n if (distTagLatest && !isPrerelease(distTagLatest)) {\n candidates = versionTimestamps.filter(\n (e) => compareVersions(e.version, distTagLatest) <= 0,\n );\n }\n if (candidates.length === 0) return null;\n\n candidates.sort((a, b) => compareVersions(b.version, a.version));\n return candidates[0].version;\n}\n","import { VERSION } from \"./versions\";\n\n/**\n * Keys of the VERSION object in versions.ts.\n */\nexport type VersionKey = keyof typeof VERSION;\n\n/**\n * Mapping of VERSION keys that are backed by an npm package and eligible\n * for auto-update. Only these keys should be updated by version-update\n * automation; others (e.g. NODE_WORKFLOWS) are skipped.\n *\n * @see {@link VERSION_KEYS_SKIP} for keys that must not be auto-updated.\n */\nexport const VERSION_NPM_PACKAGES: ReadonlyArray<{\n key: VersionKey;\n npmPackage: string;\n}> = [\n { key: \"AWS_CDK_CLI_VERSION\", npmPackage: \"aws-cdk\" },\n { key: \"AWS_CDK_LIB_VERSION\", npmPackage: \"aws-cdk-lib\" },\n { key: \"AWS_CONSTRUCTS_VERSION\", npmPackage: \"constructs\" },\n { key: \"PNPM_VERSION\", npmPackage: \"pnpm\" },\n { key: \"PROJEN_VERSION\", npmPackage: \"projen\" },\n { key: \"TURBO_VERSION\", npmPackage: \"turbo\" },\n] as const;\n\n/**\n * VERSION keys that are not backed by npm and must be skipped by\n * auto-update (e.g. runtime versions like Node.js).\n */\nexport const VERSION_KEYS_SKIP: ReadonlyArray<VersionKey> = [\"NODE_WORKFLOWS\"];\n","export const VERSION = {\n /**\n * CDK CLI for workflows and command line operations.\n *\n * CLI and lib are versioned separately, so this is the CLI version.\n */\n AWS_CDK_CLI_VERSION: \"2.1106.1\",\n\n /**\n * CDK Version to use for construct projects.\n *\n * CLI and lib are versioned separately, so this is the lib version.\n */\n AWS_CDK_LIB_VERSION: \"2.239.0\",\n\n /**\n * Version of the AWS Constructs library to use.\n */\n AWS_CONSTRUCTS_VERSION: \"10.5.1\",\n\n /**\n * Version of Node.js to use in CI workflows at github actions.\n */\n NODE_WORKFLOWS: \"24\",\n\n /**\n * Version of PNPM to use in workflows at github actions.\n */\n PNPM_VERSION: \"10.30.0\",\n\n /**\n * Version of Projen to use.\n */\n PROJEN_VERSION: \"0.99.13\",\n\n /**\n * What version of the turborepo library should we use?\n */\n TURBO_VERSION: \"2.8.10\",\n} as const;\n","import * as spec from \"@jsii/spec\";\nimport { Component, JsonFile } from \"projen\";\nimport { TypeScriptProject } from \"projen/lib/typescript\";\nimport { ValueOf } from \"type-fest\";\n\n/**\n * The FQNs for the base classes and options used by Jsii.\n *\n * These are the defaults used by Projen's TypeScriptProject.\n */\nconst ProjenBaseFqn = {\n TYPESCRIPT_PROJECT: \"projen.typescript.TypeScriptProject\",\n TYPESCRIPT_PROJECT_OPTIONS: \"projen.typescript.TypeScriptProjectOptions\",\n} as const;\n\nexport interface ClassTypeOptions {\n /**\n * The name of the class.\n *\n * @example \"MyProject\"\n */\n name: string;\n\n /**\n * The FQN for the base class this class is extending.\n *\n * @default ProjenBaseFqn.TYPESCRIPT_PROJECT\n */\n baseFqn?: ValueOf<typeof ProjenBaseFqn> | string;\n\n /**\n * The FQN for the options for this class.\n *\n * @default ProjenBaseFqn.TYPESCRIPT_PROJECT_OPTIONS\n */\n optionsFqn?: ValueOf<typeof ProjenBaseFqn> | string;\n}\n\nexport class JsiiFaker extends Component {\n // find project singleton\n public static of(project: TypeScriptProject): JsiiFaker | undefined {\n const isDefined = (c: Component): c is JsiiFaker => c instanceof JsiiFaker;\n return project.components.find(isDefined);\n }\n\n private _assemblyName: string;\n private _types: { [name: string]: spec.Type } = {};\n\n constructor(public readonly project: TypeScriptProject) {\n super(project);\n\n /**\n * In JSII, the assembly name is essentially the package name. It's used as a\n * scope when targeting types and metadata in other \"jsii assemblies\" that\n * might be in sub-packages used by the project.\n *\n * For this case, we'll just use the package name from Projen.\n */\n this._assemblyName = this.project.package.packageName;\n\n new JsonFile(project, \".jsii\", {\n obj: () => {\n return {\n name: this._assemblyName,\n types: this._types,\n };\n },\n });\n }\n\n public toJSON = () => {\n return {\n types: this._types,\n };\n };\n\n public addClassType(options: ClassTypeOptions) {\n const fqn = [this._assemblyName, options.name].join(\".\");\n const type: spec.ClassType = {\n assembly: this._assemblyName,\n base: options.baseFqn ?? ProjenBaseFqn.TYPESCRIPT_PROJECT,\n fqn,\n kind: spec.TypeKind.Class,\n name: options.name,\n initializer: {\n parameters: [\n {\n name: \"options\",\n type: {\n fqn:\n options.optionsFqn ?? ProjenBaseFqn.TYPESCRIPT_PROJECT_OPTIONS,\n },\n },\n ],\n },\n };\n\n this._types[fqn] = type;\n }\n}\n","import { relative } from \"path\";\nimport { Component, Project, YamlFile } from \"projen\";\nimport { ValueOf } from \"type-fest\";\n\n/**\n * Predefined minimum release age values in minutes.\n */\nexport const MIMIMUM_RELEASE_AGE = {\n ZERO_DAYS: 0,\n ONE_HOUR: 60,\n SIX_HOURS: 360,\n TWELVE_HOURS: 720,\n ONE_DAY: 1440,\n TWO_DAYS: 2880,\n THREE_DAYS: 4320,\n FOUR_DAYS: 5760,\n FIVE_DAYS: 7200,\n SIX_DAYS: 8640,\n ONE_WEEK: 10080,\n};\n\nexport interface PnpmWorkspaceOptions {\n /**\n * Filename for the pnpm workspace file. This should probably never change.\n *\n * @default \"pnpm-workspace.yaml\"\n */\n readonly fileName?: string;\n\n /**\n * To reduce the risk of installing compromised packages, you can delay the\n * installation of newly published versions. In most cases, malicious releases\n * are discovered and removed from the registry within an hour.\n *\n * minimumReleaseAge defines the minimum number of minutes that must pass\n * after a version is published before pnpm will install it. This applies to\n * all dependencies, including transitive ones.\n *\n * Note: this should match depsUpgradeOptions.cooldown in the project config.\n *\n * See: https://pnpm.io/settings#minimumreleaseage\n *\n * @default MIMIMUM_RELEASE_AGE.ONE_DAY\n */\n readonly minimumReleaseAge?: ValueOf<typeof MIMIMUM_RELEASE_AGE>;\n\n /**\n * If you set minimumReleaseAge but need certain dependencies to always\n * install the newest version immediately, you can list them under\n * minimumReleaseAgeExclude. The exclusion works by package name and applies\n * to all versions of that package.\n *\n * @default - no exclusions (empty array)\n *\n * See: https://pnpm.io/settings#minimumreleaseageexclude\n */\n readonly minimumReleaseAgeExclude?: Array<string>;\n\n /**\n * A list of package names that are allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation. Only the\n * packages listed in this array will be able to run those lifecycle scripts.\n * If onlyBuiltDependenciesFile and neverBuiltDependencies are omitted, this\n * configuration option will default to blocking all install scripts.\n *\n * You may restrict allowances to specific versions (and lists of versions\n * using a disjunction with ||). When versions are specified, only those\n * versions of the package may run lifecycle scripts:\n *\n * See: https://pnpm.io/settings#onlybuiltdependencies\n *\n * @default none (empty array)\n */\n readonly onlyBuiltDependencies?: Array<string>;\n\n /**\n * A list of package names that are NOT allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation and will not\n * warn or ask to be executed.\n *\n * This is useful when you want to hide the warning because you know the\n * lifecycle scripts are not needed.\n *\n * https://pnpm.io/settings#ignoredbuiltdependencies\n *\n * @default none (empty array)\n */\n readonly ignoredBuiltDependencies?: Array<string>;\n\n /**\n * Additional subproject paths to include in the workspace packages array.\n * These will be combined with any subprojects discovered via projen's\n * project.subprojects property. Paths should be relative to the project root.\n *\n * @default none (empty array)\n */\n readonly subprojects?: Array<string>;\n\n /**\n * Catalog of reusable dependency version ranges.\n *\n * The catalog allows you to define dependency versions as reusable constants\n * that can be referenced in package.json files using the catalog: protocol.\n *\n * Example:\n * ```yaml\n * catalog:\n * react: ^18.0.0\n * typescript: ^5.0.0\n * ```\n *\n * Then in package.json:\n * ```json\n * {\n * \"dependencies\": {\n * \"react\": \"catalog:react\"\n * }\n * }\n * ```\n *\n * @default undefined (not included in output)\n *\n * See: https://pnpm.io/pnpm-workspace_yaml#catalog\n */\n readonly defaultCatalog?: { [key: string]: string };\n\n /**\n * Named catalogs of reusable dependency version ranges.\n *\n * Multiple named catalogs with arbitrarily chosen names can be configured under the namedCatalogs key.\n *\n * Example:\n * ```yaml\n * namedCatalogs:\n * frontend:\n * react: ^18.0.0\n * typescript: ^5.0.0\n * backend:\n * express: ^4.18.0\n * ```\n *\n * Then in package.json:\n * ```json\n * {\n * \"dependencies\": {\n * \"react\": \"catalog:frontend/react\"\n * }\n * }\n * ```\n *\n * @default undefined (not included in output)\n *\n * See: https://pnpm.io/catalogs\n */\n readonly namedCatalogs?: {\n [catalogName: string]: { [dependencyName: string]: string };\n };\n}\n\nexport class PnpmWorkspace extends Component {\n /**\n * Get the pnpm workspace component of a project. If it does not exist,\n * return undefined.\n *\n * @param project\n * @returns\n */\n public static of(project: Project): PnpmWorkspace | undefined {\n const isDefined = (c: Component): c is PnpmWorkspace =>\n c instanceof PnpmWorkspace;\n return project.root.components.find(isDefined);\n }\n\n /**\n * Filename for the pnpm workspace file.\n */\n public readonly fileName: string;\n\n /**\n * To reduce the risk of installing compromised packages, you can delay the\n * installation of newly published versions. In most cases, malicious releases\n * are discovered and removed from the registry within an hour.\n *\n * minimumReleaseAge defines the minimum number of minutes that must pass\n * after a version is published before pnpm will install it. This applies to\n * all dependencies, including transitive ones.\n *\n * Note: this should match depsUpgradeOptions.cooldown in the project config.\n *\n * See: https://pnpm.io/settings#minimumreleaseage\n */\n public minimumReleaseAge: ValueOf<typeof MIMIMUM_RELEASE_AGE>;\n\n /**\n * If you set minimumReleaseAge but need certain dependencies to always\n * install the newest version immediately, you can list them under\n * minimumReleaseAgeExclude. The exclusion works by package name and applies\n * to all versions of that package.\n *\n * See: https://pnpm.io/settings#minimumreleaseageexclude\n */\n public minimumReleaseAgeExclude: Array<string>;\n\n /**\n * A list of package names that are allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation. Only the\n * packages listed in this array will be able to run those lifecycle scripts.\n * If onlyBuiltDependenciesFile and neverBuiltDependencies are omitted, this\n * configuration option will default to blocking all install scripts.\n *\n * You may restrict allowances to specific versions (and lists of versions\n * using a disjunction with ||). When versions are specified, only those\n * versions of the package may run lifecycle scripts:\n *\n * See: https://pnpm.io/settings#onlybuiltdependencies\n */\n public onlyBuiltDependencies: Array<string>;\n\n /**\n * A list of package names that are NOT allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation and will not\n * warn or ask to be executed.\n *\n * This is useful when you want to hide the warning because you know the\n * lifecycle scripts are not needed.\n *\n * https://pnpm.io/settings#ignoredbuiltdependencies\n */\n public ignoredBuiltDependencies: Array<string>;\n\n /**\n * Additional subproject paths to include in the workspace packages array.\n * These will be combined with any subprojects discovered via projen's\n * project.subprojects property.\n */\n public subprojects: Array<string>;\n\n /**\n * Default catalog of reusable dependency version ranges.\n *\n * The default catalog is used to define dependency versions as reusable constants\n * that can be referenced in package.json files using the catalog: protocol.\n *\n * See:https://pnpm.io/catalogs\n */\n public defaultCatalog?: { [key: string]: string };\n\n /**\n * Named catalogs of reusable dependency version ranges.\n *\n * Multiple named catalogs with arbitrarily chosen names can be configured under the namedCatalogs key.\n *\n * See: https://pnpm.io/catalogs\n */\n public namedCatalogs?: {\n [catalogName: string]: { [dependencyName: string]: string };\n };\n\n constructor(project: Project, options: PnpmWorkspaceOptions = {}) {\n super(project);\n\n /***************************************************************************\n *\n * CLEAR package,json\n *\n * It appears that if ANY pnpm settings exist in the package.json file, all\n * of the setting in the pnpm-workspace.yaml file are ignored. so we need to\n * clear out anything that was placed into the package.json file.\n *\n **************************************************************************/\n\n project.tryFindObjectFile(\"package.json\")?.addDeletionOverride(\"pnpm\");\n\n /***************************************************************************\n * \n * Setup pnpm-workspace.yaml file.\n * \n * Now that the package.json file is cleared of any pnpm settings, we can\n * safely write settings to the pnpm-workspace.yaml file.\n * \n **************************************************************************\n\n /**\n * Set filename to default if not provided.\n */\n this.fileName = options.fileName ?? \"pnpm-workspace.yaml\";\n\n /**\n * Set minimum release age; default ONE_DAY when not provided.\n */\n this.minimumReleaseAge =\n options.minimumReleaseAge ?? MIMIMUM_RELEASE_AGE.ONE_DAY;\n\n /**\n * Set minimum release age exclude to empty array if not provided\n */\n this.minimumReleaseAgeExclude = options.minimumReleaseAgeExclude\n ? [\"@codedrifters/*\", ...options.minimumReleaseAgeExclude]\n : [\"@codedrifters/*\"];\n\n /**\n * Set only built dependencies to empty array if not provided\n */\n this.onlyBuiltDependencies = options.onlyBuiltDependencies\n ? options.onlyBuiltDependencies\n : [];\n\n /**\n * Set ignored built dependencies to empty array if not provided\n */\n this.ignoredBuiltDependencies = options.ignoredBuiltDependencies\n ? options.ignoredBuiltDependencies\n : [];\n\n /**\n * Store additional subproject paths if provided\n */\n this.subprojects = options.subprojects ?? [];\n\n /**\n * Store catalog if provided\n */\n this.defaultCatalog = options.defaultCatalog;\n\n /**\n * Store named catalogs if provided\n */\n this.namedCatalogs = options.namedCatalogs;\n\n /**\n * In case that this file is in a package, don't package it.\n */\n project.addPackageIgnore(this.fileName);\n\n /**\n * Write pnpm workspace file\n */\n new YamlFile(this.project, this.fileName, {\n obj: () => {\n const pnpmConfig: any = {};\n const packages = new Array<string>();\n\n /**\n * Add projen subprojects to the packages array.\n */\n for (const subproject of project.subprojects) {\n // grab the relative out directory\n packages.push(relative(this.project.outdir, subproject.outdir));\n }\n\n /**\n * Add additional subproject paths provided via options.\n * Use a Set to deduplicate paths to avoid including the same\n * subproject multiple times.\n */\n const packageSet = new Set(packages);\n for (const subprojectPath of this.subprojects) {\n packageSet.add(subprojectPath);\n }\n\n /**\n * Convert back to array if we added any additional paths\n */\n if (this.subprojects.length > 0) {\n packages.length = 0;\n packages.push(...packageSet);\n }\n\n /**\n * Set minimum release age.\n */\n pnpmConfig.minimumReleaseAge = this.minimumReleaseAge;\n\n /**\n * Set minimum release age exclude if any are provided.\n */\n if (this.minimumReleaseAgeExclude.length > 0) {\n pnpmConfig.minimumReleaseAgeExclude = this.minimumReleaseAgeExclude;\n }\n\n /**\n * Set only built dependencies if any are provided.\n */\n if (this.onlyBuiltDependencies.length > 0) {\n pnpmConfig.onlyBuiltDependencies = this.onlyBuiltDependencies;\n }\n\n /**\n * Set ignored built dependencies if any are provided.\n */\n if (this.ignoredBuiltDependencies.length > 0) {\n pnpmConfig.ignoreBuiltDependencies = this.ignoredBuiltDependencies;\n }\n\n /**\n * Set default catalog if provided.\n */\n if (\n this.defaultCatalog &&\n Object.keys(this.defaultCatalog).length > 0\n ) {\n pnpmConfig.catalog = this.defaultCatalog;\n }\n\n /**\n * Set named catalogs if provided.\n */\n if (this.namedCatalogs && Object.keys(this.namedCatalogs).length > 0) {\n pnpmConfig.namedCatalogs = this.namedCatalogs;\n }\n\n /**\n * Return the final pnpm config object.\n */\n return {\n ...(packages.length > 0 ? { packages } : {}),\n ...(pnpmConfig ? { ...pnpmConfig } : {}),\n };\n },\n });\n }\n}\n","import { BuildWorkflowOptions } from \"projen/lib/build\";\nimport {\n NodePackageManager,\n UpgradeDependencies,\n UpgradeDependenciesOptions,\n UpgradeDependenciesSchedule,\n} from \"projen/lib/javascript\";\nimport {\n TypeScriptAppProject,\n TypeScriptProjectOptions,\n} from \"projen/lib/typescript\";\nimport { merge } from \"ts-deepmerge\";\nimport { PnpmWorkspace, PnpmWorkspaceOptions } from \"../pnpm/pnpm-workspace\";\nimport { ResetTask, ResetTaskOptions } from \"../tasks/reset-task\";\nimport {\n ROOT_CI_TASK_NAME,\n TurboRepo,\n TurboRepoOptions,\n} from \"../turbo/turbo-repo\";\nimport { VERSION } from \"../versions\";\nimport { VSCodeConfig } from \"../vscode/vscode\";\n\n/*******************************************************************************\n *\n * Monorepo Root Project\n *\n * This project should be used as the base project for other projects in a\n * monorepo. The Monorepo root project generally won't contain any code, but it\n * will contain configuration for the monorepo, such as package management,\n * linting, testing, and other project-wide settings.\n *\n ******************************************************************************/\n\nexport interface IDependencyResolver {\n resolveDepsAndWritePackageJson(): boolean;\n}\n\n/**\n * Configuration options for the monorepo.\n */\nexport interface MonorepoProjectOptions extends Omit<\n TypeScriptProjectOptions,\n \"defaultReleaseBranch\"\n> {\n /**\n * Turn on Turborepo support.\n *\n * @default true\n */\n turbo?: boolean;\n\n /**\n * Optionsal options for turborepo config\n */\n turboOptions?: TurboRepoOptions;\n\n /**\n * Enable the reset task that deletes all build artifacts.\n *\n * @default true\n */\n resetTask?: boolean;\n\n /**\n * Options for the reset task.\n */\n resetTaskOptions?: ResetTaskOptions;\n\n /**\n * PNPM options for the monorepo.\n */\n pnpmOptions?: {\n /**\n * The version of PNPM to use in the monorepo.\n * @default VERSION.PNPM_VERSION\n * @see {@link src/versions.ts}\n */\n version?: string;\n\n /**\n * Optional pnpm options for the monorepo workspace file.\n */\n pnpmWorkspaceOptions?: PnpmWorkspaceOptions;\n };\n\n /**\n * Turn on a dedicated workflow that upgrades only\n * @codedrifters/configulator on a schedule (e.g. nightly). When false or\n * unset, rely on projen's default upgrade workflow for all dependency\n * upgrades instead.\n *\n * @default false\n */\n readonly upgradeConfigulatorTask?: boolean;\n\n /**\n * Options for the upgrade configurator task.\n *\n * @default: daily schedule\n */\n readonly upgradeConfigulatorTaskOptions?: UpgradeDependenciesOptions;\n}\n\ninterface AppliedOptions\n extends TypeScriptProjectOptions, MonorepoProjectOptions {}\n\nexport class MonorepoProject extends TypeScriptAppProject {\n /**\n * Version of PNPM which the whole monorepo should use.\n */\n readonly pnpmVersion: string;\n\n /**\n * Optional task that will attempt to upgrade the @codedrifters/configulator\n * package version nightly. This keeps the project up-to-date with the latest\n * official CodeDrifters configs.\n */\n readonly upgradeConfigulatorTask?: UpgradeDependencies;\n\n /**\n * List of functions to call after dependencies have been installed.\n */\n private postInstallDependencies = new Array<() => boolean>();\n\n constructor(userOptions: MonorepoProjectOptions) {\n /***************************************************************************\n *\n * BUILD WORKFLOW OPTIONS\n *\n * discover some turbo options for build workflow, if needed.\n *\n **************************************************************************/\n\n const buildWorkflowOptions: Partial<BuildWorkflowOptions> = userOptions\n .turboOptions?.remoteCacheOptions\n ? TurboRepo.buildWorkflowOptions(\n userOptions.turboOptions.remoteCacheOptions,\n )\n : {};\n\n /***************************************************************************\n *\n * DEFAULT OPTIONS\n *\n * These are the default options unless you override with option inputs.\n *\n **************************************************************************/\n\n const defaultOptions: Omit<\n MonorepoProjectOptions,\n \"name\" | \"defaultReleaseBranch\"\n > = {\n /**\n * Use typescript based config file.\n */\n projenrcTs: true,\n\n /**\n * Projen version should be pinned to the local specified version.\n */\n projenVersion: \"catalog:\",\n\n /**\n * Use Prettier for code formatting.\n */\n prettier: true,\n\n /**\n * Not licensed by default.\n */\n licensed: false,\n\n /**\n * GitHub options for the monorepo.\n * Don't enable mergify by default.\n */\n githubOptions: {\n mergify: false,\n\n /**\n * Configure pull request linting to validate PR titles follow Conventional Commits.\n * By default, all conventional commit types are allowed, providing flexibility\n * for different types of changes (features, fixes, documentation, refactoring, etc.).\n */\n pullRequestLintOptions: {\n semanticTitleOptions: {\n /**\n * Allowed conventional commit types for PR titles.\n * This includes all standard types from the Conventional Commits specification:\n * - feat: New features\n * - fix: Bug fixes\n * - docs: Documentation changes\n * - style: Code style changes (formatting, etc.)\n * - refactor: Code refactoring\n * - perf: Performance improvements\n * - test: Test additions or changes\n * - build: Build system changes\n * - ci: CI configuration changes\n * - chore: Maintenance tasks\n * - revert: Revert commits\n */\n types: [\n \"feat\",\n \"fix\",\n \"docs\",\n \"style\",\n \"refactor\",\n \"perf\",\n \"test\",\n \"build\",\n \"ci\",\n \"chore\",\n \"revert\",\n ],\n },\n },\n },\n\n /**\n * Default PNPM version to use in the monorepo.\n */\n pnpmVersion: VERSION.PNPM_VERSION,\n\n /**\n * We don't want sample code generated for the root project.\n */\n sampleCode: false,\n\n /**\n * Jest is not required in the root project.\n */\n jest: false,\n\n /**\n * Don't release the root project.\n */\n release: false,\n\n /**\n * Uppgrade dependencies automatically unless otherwise instructed.\n */\n depsUpgrade: true,\n depsUpgradeOptions: {\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.expressions([\"0 23 * * *\"]),\n },\n cooldown: 1,\n },\n\n /**\n * Disable tsconfig.dev.json in the root since we aren't going to be\n * developing any code here. It's just a task runner and configuration\n * tool for sub-projects.\n */\n disableTsconfigDev: true,\n\n /**\n * Kill the srcdir in the root since we aren't using one.\n */\n tsconfig: {\n compilerOptions: {\n rootDir: undefined,\n },\n exclude: [\"node_modules\"],\n },\n\n /**\n * Enable turborepo by default.\n */\n turbo: true,\n\n /**\n * Enable reset task by default.\n */\n resetTask: true,\n\n /**\n * Include self as a devDep\n */\n devDeps: [\"@codedrifters/configulator\"],\n\n /**\n * PNPM options for the monorepo.\n */\n pnpmOptions: {\n pnpmWorkspaceOptions: {\n defaultCatalog: {\n [\"aws-cdk\"]: VERSION.AWS_CDK_CLI_VERSION,\n [\"aws-cdk-lib\"]: VERSION.AWS_CDK_LIB_VERSION,\n [\"projen\"]: VERSION.PROJEN_VERSION,\n [\"constructs\"]: VERSION.AWS_CONSTRUCTS_VERSION,\n [\"turbo\"]: VERSION.TURBO_VERSION,\n },\n },\n },\n };\n\n /***************************************************************************\n *\n * REQUIRED OPTIONS\n *\n * These options cannot be changed by the user.\n *\n **************************************************************************/\n\n const requiredOptions: Omit<TypeScriptProjectOptions, \"name\"> = {\n /**\n * This is required because it's standard practice and also to simplify\n * some workflow design.\n */\n defaultReleaseBranch: \"main\",\n\n /**\n * Use PNPM instead of the default (Yarn). Much of the ecosystem depends\n * on PNPM and making monorepos PNPM only simplifies many configurations.\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Some additional pre-build steps if we're using turbo's remote cache.\n * Set BRANCH_NAME so Turborepo remote cache hashes match between local and CI.\n */\n buildWorkflowOptions: {\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n ...buildWorkflowOptions?.env,\n ...userOptions.buildWorkflowOptions?.env,\n },\n permissions: {\n ...buildWorkflowOptions?.permissions,\n ...userOptions.buildWorkflowOptions?.permissions,\n },\n preBuildSteps: [\n ...(buildWorkflowOptions?.preBuildSteps ?? []),\n ...(userOptions.buildWorkflowOptions?.preBuildSteps ?? []),\n ],\n },\n };\n\n /***************************************************************************\n *\n * CONSTRUCTOR\n *\n * Combines default options with user provided options and required options.\n * Store the options in a const so we can use them after super(), farther\n * into the constructor for additional configuration.\n *\n **************************************************************************/\n\n const options: AppliedOptions = merge(\n defaultOptions,\n userOptions,\n requiredOptions,\n );\n\n super({ ...options });\n\n /***************************************************************************\n *\n * PUBLIC PROPS\n *\n * Some props are hidden by Projen and we need to expose them for the\n * monorepo to work properly. This is where we store them.\n *\n **************************************************************************/\n\n this.pnpmVersion = options.pnpmVersion!;\n\n /***************************************************************************\n *\n * CUSTOM CONFIGS\n *\n * We add some additional configurations to the monorepo root project below\n * such as Turborepo, VS Code config, and the PNPM workspace file.\n *\n **************************************************************************/\n\n /**\n * Add VSCode configuration\n */\n new VSCodeConfig(this);\n\n /**\n * Add workspace definition to PNPM root\n */\n new PnpmWorkspace(this, options.pnpmOptions?.pnpmWorkspaceOptions);\n\n /**\n * Turn on turborepo support if requested.\n */\n if (options.turbo) {\n new TurboRepo(this, options.turboOptions);\n\n this.buildWorkflow?.addPostBuildSteps({\n name: \"Build Sub Projects\",\n run: `npx projen ${ROOT_CI_TASK_NAME}`,\n });\n }\n\n /**\n * Add reset task if enabled.\n */\n if (options.resetTask !== false) {\n const defaultResetTaskOptions: ResetTaskOptions = {\n pathsToRemove: [\"node_modules\", \".turbo\", \"dist\", \"lib\"],\n };\n const userResetTaskOptions = options.resetTaskOptions ?? {};\n const resetTaskOptions: ResetTaskOptions = merge(\n defaultResetTaskOptions,\n {\n ...userResetTaskOptions,\n pathsToRemove: [\n ...(defaultResetTaskOptions.pathsToRemove ?? []),\n ...(userResetTaskOptions.pathsToRemove ?? []),\n ],\n },\n );\n new ResetTask(this, resetTaskOptions);\n }\n\n /**\n * Specify package manager\n */\n // const pnpmVersion = options.pnpmVersion ?? VERSION.PNPM_VERSION;\n this.package.file.addOverride(\n \"packageManager\",\n `pnpm@${options.pnpmVersion}`,\n );\n\n /**\n * Add some silly things to the gitignore.\n */\n this.gitignore?.addPatterns(\".DS_Store\");\n\n /**\n * Use catalog version for constructs version\n */\n this.addDevDeps(\"constructs@catalog:\");\n\n /**\n * Add a task on the monorepo's root project that will attempt to upgrade\n * the @codedrifters/configulator package version on a schedule when\n * explicitly enabled. Off by default; use projen's upgrade workflow instead.\n */\n if (options.upgradeConfigulatorTask === true) {\n this.upgradeConfigulatorTask = new UpgradeDependencies(\n this,\n merge(\n {\n include: [\"@codedrifters/configulator\"],\n taskName: `upgrade-codedrifters-configulator`,\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.DAILY,\n },\n },\n options.upgradeConfigulatorTaskOptions ?? {},\n ),\n );\n }\n\n /**\n * Update all packages after the root of the monorepo's updated.\n * Run the default task after the upgrade to ensure all packages are\n * updated. In particular make sure the pnpm-workspace file was not\n * tampered with during the upgrade.\n */\n this.tasks.tryFind(\"post-upgrade\")?.exec(\"pnpm upgrade -r\");\n this.tasks.tryFind(\"post-upgrade\")?.spawn(this.defaultTask!);\n }\n\n /**\n * Allows a sub project to request installation of dependency at the Monorepo root\n * They must provide a function that is executed after dependencies have been installed\n * If this function returns true, the install command is run for a second time after all sub project requests have run.\n * This is used to resolve dependency versions from `*` to a concrete version constraint.\n */\n public requestInstallDependencies(resolver: IDependencyResolver) {\n this.postInstallDependencies.push(resolver.resolveDepsAndWritePackageJson);\n }\n\n /**\n * Hooks into the install dependencies cycle\n */\n public postSynthesize() {\n if (this.postInstallDependencies.length) {\n const nodePkg: any = this.package;\n nodePkg.installDependencies();\n\n const completedRequests = this.postInstallDependencies.map((request) =>\n request(),\n );\n if (completedRequests.some(Boolean)) {\n nodePkg.installDependencies();\n }\n\n this.postInstallDependencies = [];\n }\n }\n}\n","import { Component, Project } from \"projen\";\nimport { TypeScriptProject } from \"../projects/typescript-project\";\nimport { TurboRepo } from \"../turbo/turbo-repo\";\nimport { TurboRepoTask } from \"../turbo/turbo-repo-task\";\n\n/*******************************************************************************\n *\n * Reset Task Component\n *\n * Adds a \"reset\" task that deletes all build artifacts produced by the build\n * process. This includes node_modules, lib, dist, coverage, test-reports,\n * .turbo, and tsconfig.tsbuildinfo.\n *\n ******************************************************************************/\n\nexport interface ResetTaskOptions {\n /**\n * Custom output directory to delete (overrides tsconfig artifactsDirectory detection).\n *\n * @default - detected from typescript project.artifactsDirectory or \"lib\"\n */\n readonly artifactsDirectory?: string;\n\n /**\n * Array of glob patterns for paths to remove.\n * If empty, the artifactsDirectory will be added automatically.\n *\n * @default []\n */\n readonly pathsToRemove?: string[];\n\n /**\n * Name of the task to create.\n *\n * @default \"reset\"\n */\n readonly taskName?: string;\n}\n\nexport class ResetTask extends Component {\n /**\n * Static method to discover reset task in a project.\n */\n public static of(project: Project): ResetTask | undefined {\n const isDefined = (c: Component): c is ResetTask => c instanceof ResetTask;\n return project.components.find(isDefined);\n }\n\n /**\n * The output directory to delete (from tsconfig or custom).\n */\n public readonly artifactsDirectory: string;\n\n /**\n * The final array of paths that will be removed by the reset task.\n */\n public readonly pathsToRemove: string[];\n\n /**\n * The name of the task that was created.\n */\n public readonly taskName: string;\n\n constructor(\n public readonly project: Project,\n options: ResetTaskOptions = {},\n ) {\n super(project);\n\n /**\n * Determine the output directory.\n * 1. Use custom artifactsDirectory if provided\n * 2. Use the artifacts directory if project is TypeScriptProject\n * 3. Default to \"lib\"\n */\n this.artifactsDirectory = options.artifactsDirectory\n ? options.artifactsDirectory\n : project instanceof TypeScriptProject\n ? project.artifactsDirectory\n : \"lib\";\n\n /**\n * Build the paths array to remove.\n * If pathsToRemove is empty, add artifactsDirectory.\n * If pathsToRemove is not empty, use it as-is (artifactsDirectory is not automatically added).\n * Remove duplicate entries from the array.\n */\n const pathsToRemove = options.pathsToRemove ?? [];\n const finalPaths =\n pathsToRemove.length === 0 ? [this.artifactsDirectory] : pathsToRemove;\n\n /**\n * Remove duplicate paths from the array.\n */\n this.pathsToRemove = Array.from(new Set(finalPaths));\n\n /**\n * Determine the task name.\n */\n this.taskName = options.taskName ?? \"reset\";\n\n /**\n * Create the reset task.\n */\n const resetTask = this.project.tasks.addTask(this.taskName, {\n description:\n \"Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty\",\n });\n\n /**\n * Delete build artifacts with existence checks.\n * Using shell conditionals to only delete if paths exist.\n * Using -e to check existence (works for both files and directories).\n */\n this.pathsToRemove.forEach((path) => {\n resetTask.exec(`[ -e \"${path}\" ] && rm -rf ${path} || true`);\n });\n\n /**\n * Turbo tasks are added after all components are created.\n * This assumes turbo is built first so that it's available to be\n * referenced. This could introduce problems in future but works for now.\n */\n\n /**\n * Check if turborepo is active.\n */\n const rootHasTurbo = TurboRepo.of(this.project.root) !== undefined;\n const isSubproject = this.project !== this.project.root;\n const isRootProject = this.project === this.project.root;\n\n /**\n * If turborepo is active for the subproject, add turbo tasks.\n */\n if (isSubproject && rootHasTurbo) {\n /**\n * Get TurboRepo instance for this subproject.\n * It should exist by now since preSynthesize runs after all components are created.\n */\n const turbo = TurboRepo.of(this.project);\n if (turbo && !turbo.isRootProject) {\n /**\n * Create turbo:reset task (or turbo:${taskName}).\n */\n const turboResetTask = new TurboRepoTask(this.project, {\n name: `turbo:${this.taskName}`,\n cache: false,\n });\n turbo.tasks.push(turboResetTask);\n\n /**\n * Create a turbo task with the same name as the reset task.\n */\n const turboTaskWithSameName = new TurboRepoTask(this.project, {\n name: this.taskName,\n cache: false,\n });\n turbo.tasks.push(turboTaskWithSameName);\n\n /**\n * turboResetTask depends on turboTaskWithSameName so that the reset task\n * can be run across all suprojects using turbo:reset as the entry point.\n */\n turboResetTask.dependsOn.push(turboTaskWithSameName.name);\n }\n }\n\n /**\n * If reset-task is in the root project, add a turbo task that will trigger\n * all the subtasks using dependsOn of \"^turbo:reset\".\n */\n if (isRootProject && rootHasTurbo) {\n const turbo = TurboRepo.of(this.project);\n if (turbo && turbo.isRootProject) {\n /**\n * Create turbo:reset task (or turbo:${taskName}) in the root project.\n * The ^ prefix means \"run this task in all dependencies first\".\n */\n const rootTurboResetTask = new TurboRepoTask(this.project, {\n name: `turbo:${this.taskName}`,\n dependsOn: [`^turbo:${this.taskName}`],\n cache: false,\n });\n turbo.tasks.push(rootTurboResetTask);\n\n /**\n * Create a turbo task with the same name as the reset task.\n */\n const turboTaskWithSameName = new TurboRepoTask(this.project, {\n name: this.taskName,\n cache: false,\n });\n turbo.tasks.push(turboTaskWithSameName);\n\n /**\n * rootTurboResetTask depends on turboTaskWithSameName so that the reset task\n * can be run across all suprojects using turbo:reset as the entry point.\n */\n rootTurboResetTask.dependsOn.push(turboTaskWithSameName.name);\n\n /**\n * Create reset:all task - a projen task that calls the turbo task.\n * This is similar to build:all in turbo-repo.ts.\n */\n const resetAllTask = this.project.tasks.addTask(\n `${this.taskName}:all`,\n {\n description: `Reset all build artifacts across the monorepo by running turbo:${this.taskName} in all subprojects.`,\n },\n );\n resetAllTask.exec(\"turbo telemetry disable\");\n resetAllTask.exec(\n `turbo turbo:${this.taskName} --summarize --concurrency=10`,\n );\n resetAllTask.exec(`pnpm ${this.taskName}`);\n }\n }\n }\n}\n","import { typescript } from \"projen\";\nimport {\n NodePackageManager,\n Transform,\n UpgradeDependenciesSchedule,\n} from \"projen/lib/javascript\";\nimport { ReleaseTrigger } from \"projen/lib/release\";\nimport { merge } from \"ts-deepmerge\";\nimport { MonorepoProject } from \"./monorepo-project\";\nimport { PnpmWorkspace } from \"../pnpm\";\nimport { ResetTask, ResetTaskOptions } from \"../tasks/reset-task\";\nimport { TurboRepo } from \"../turbo\";\nimport { VERSION } from \"../versions\";\n\n/**\n * Configuration options for TypeScriptProject.\n */\nexport interface TypeScriptProjectOptions extends Omit<\n typescript.TypeScriptProjectOptions,\n \"defaultReleaseBranch\"\n> {\n /**\n * Enable the reset task that deletes all build artifacts.\n *\n * @default true\n */\n readonly resetTask?: boolean;\n\n /**\n * Options for the reset task.\n */\n readonly resetTaskOptions?: ResetTaskOptions;\n}\n\nexport class TypeScriptProject extends typescript.TypeScriptProject {\n constructor(userOptions: TypeScriptProjectOptions) {\n /**\n * Default PNPM version to use. This will either come from the MonoRepo\n * root or from the default specified in configulator. If the user passes\n * in a different pnpmVersion it will also override this.\n */\n const pnpmVersion =\n userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? userOptions.parent.pnpmVersion\n : VERSION.PNPM_VERSION;\n\n /**\n * Get the pnpm workspace from the parent project.\n */\n const pnpmWorkspace =\n userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? PnpmWorkspace.of(userOptions.parent as MonorepoProject)\n : undefined;\n\n /*************************************************************************\n *\n * Default Options\n *\n ************************************************************************/\n\n const defaultOptions: Omit<TypeScriptProjectOptions, \"name\"> & {\n defaultReleaseBranch: string;\n } = {\n /**\n * This is a standard, so don't require it to passed in everywhere.\n */\n defaultReleaseBranch: \"main\",\n\n /**\n * Enable reset task by default.\n */\n resetTask: true,\n\n /**\n * Packaging options\n */\n packageManager: NodePackageManager.PNPM,\n pnpmVersion: pnpmVersion,\n licensed: userOptions.license !== undefined || false,\n copyrightOwner: \"CodeDrifters\",\n release: false,\n\n /**\n * Don't add sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n roots: [`<rootDir>/src`],\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n moduleFileExtensions: [\"js\", \"ts\"],\n },\n },\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n\n /**\n * Options for the automated dependency upgrade task / workflow\n * Automatically exclude any packages that are managed by the root\n * project as default catalog dependencies since we want to let the\n * catalog manage those dependencies.\n */\n depsUpgrade: true,\n depsUpgradeOptions: {\n workflow: false,\n exclude: Object.keys(pnpmWorkspace?.defaultCatalog || {}),\n ...(userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? {\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.WEEKLY,\n },\n cooldown: 1,\n }\n : {}),\n },\n\n /**\n * Only release when the package folder source content or package.json\n * (version, dependencies) changes.\n */\n releaseTrigger: ReleaseTrigger.continuous({\n paths: [\n `${userOptions.outdir}/src/**`,\n `${userOptions.outdir}/package.json`,\n ],\n }),\n };\n\n /*************************************************************************\n *\n * Merge defaults into user options\n *\n ************************************************************************/\n\n const options: TypeScriptProjectOptions &\n typescript.TypeScriptProjectOptions = merge(defaultOptions, userOptions);\n\n super(options);\n\n /**\n * Remove jest since we've swapped in @swc/jest instead of ts-jest.\n */\n this.deps.removeDependency(\"ts-jest\");\n\n /**\n * Specify package manager\n */\n this.package.file.addOverride(\n \"packageManager\",\n `pnpm@${options.pnpmVersion}`,\n );\n\n /**\n *\n * Disable this rule for all test files.\n *\n * Unless we turn this off, ESLint will suggest that anything found in a test\n * needs to be a dep instead of a devDep. Projen actually already turns off\n * the rule for files in the tests/* folder but since we commonly put tests\n * next to the code it's testing, we need to do this ourselves.\n *\n */\n this.eslint?.addOverride({\n files: [\"**/*.test.*\", \"**/*.spec.*\"],\n rules: {\n \"import/no-extraneous-dependencies\": \"off\",\n },\n });\n\n /**\n * Some standard ignores for all projects.\n */\n this.gitignore?.addPatterns(\".DS_Store\");\n this.npmignore?.addPatterns(\"*.spec.*\", \"*.test.*\", \"__fixtures__\");\n\n /**\n * If turbo is active in the parent project, configure it here.\n */\n const turboActive =\n userOptions.parent && TurboRepo.of(userOptions.parent) !== undefined;\n if (turboActive) {\n const turbo = new TurboRepo(this);\n turbo.compileTask?.outputs.push(\"dist/**\");\n turbo.compileTask?.outputs.push(\"lib/**\");\n //turbo.testTask?.inputs.push(\"src/**\");\n }\n\n /**\n * Add reset task if enabled.\n */\n if (options.resetTask !== false) {\n const defaultResetTaskOptions: ResetTaskOptions = {\n pathsToRemove: [\n \"node_modules\",\n \"dist\",\n \"lib\",\n \"coverage\",\n \"test-reports\",\n \".turbo\",\n \"tsconfig.tsbuildinfo\",\n this.artifactsDirectory,\n ],\n };\n const userResetTaskOptions = options.resetTaskOptions ?? {};\n const resetTaskOptions: ResetTaskOptions = merge(\n defaultResetTaskOptions,\n {\n ...userResetTaskOptions,\n pathsToRemove: [\n ...(defaultResetTaskOptions.pathsToRemove ?? []),\n ...(userResetTaskOptions.pathsToRemove ?? []),\n ],\n },\n );\n new ResetTask(this, resetTaskOptions);\n }\n\n /**\n *\n */\n\n if (options.parent && options.parent instanceof MonorepoProject) {\n // Install dependencies via the parent project\n /* @ts-ignore access private method */\n const originalResolve = this.package.resolveDepsAndWritePackageJson;\n /* @ts-ignore access private method */\n this.package.installDependencies = () => {\n (options.parent as MonorepoProject).requestInstallDependencies({\n resolveDepsAndWritePackageJson: () =>\n originalResolve.apply(this.package),\n });\n };\n /* @ts-ignore access private method */\n this.package.resolveDepsAndWritePackageJson = () => {};\n }\n }\n}\n","import { Component, vscode } from \"projen\";\nimport { TypeScriptAppProject } from \"projen/lib/typescript\";\n\n/*******************************************************************************\n *\n * Configure VSCode Settings\n *\n ******************************************************************************/\n\nexport class VSCodeConfig extends Component {\n constructor(project: TypeScriptAppProject) {\n super(project);\n\n /**\n * Create instance of config file.\n */\n const vsConfig = new vscode.VsCode(project);\n\n /**\n * Add some basic configuration settings to the VS Code settings file:\n *\n * - Set the tab size to 2 spaces\n * - Enable bracket pair colorization\n * - Highlight active bracket pairs\n * - Add rulers at 80 and 120 characters\n */\n const vsSettings = new vscode.VsCodeSettings(vsConfig);\n vsSettings.addSetting(\"editor.tabSize\", 2);\n vsSettings.addSetting(\"editor.detectIndentation\", false);\n vsSettings.addSetting(\"editor.bracketPairColorization.enabled\", true);\n vsSettings.addSetting(\"editor.guides.bracketPairs\", \"active\");\n vsSettings.addSetting(\"editor.rulers\", [80, 120]);\n\n /**\n * Add some ESLint specific settings to the VS Code settings file.\n */\n vsSettings.addSetting(\n \"editor.codeActionsOnSave\",\n { \"source.fixAll.eslint\": \"explicit\" },\n \"typescript\",\n );\n }\n}\n","import { relative } from \"node:path\";\nimport { Component } from \"projen\";\nimport { TypeScriptProject } from \"projen/lib/typescript\";\nimport { ensureRelativePathStartsWithDot } from \"projen/lib/util/path\";\n\n/*******************************************************************************\n *\n * Update / customize typescript configs for a project.\n *\n * Update typescript paths in tsconfig so we don't have to compile packages to\n * dist in order to see changes.\n *\n ******************************************************************************/\nexport class TypeScriptConfig extends Component {\n constructor(project: TypeScriptProject) {\n super(project);\n\n /**\n * Container for paths to insert at the end.\n */\n let tsPaths = {};\n\n const workspaceDeps = project.deps.all.filter(\n (d) => d.version === \"workspace:*\",\n );\n\n workspaceDeps.forEach((dep) => {\n const subproject = (\n project.root.subprojects as Array<TypeScriptProject>\n ).find((p) => p.package.packageName === dep.name);\n\n if (!subproject) {\n throw new Error(`Could not find subproject ${dep.name} in monorepo.`);\n }\n\n tsPaths = {\n ...tsPaths,\n [dep.name]: [\n ensureRelativePathStartsWithDot(\n relative(project.outdir, subproject.outdir),\n ),\n ],\n };\n });\n\n project.tsconfig?.file.addOverride(\"compilerOptions.paths\", tsPaths);\n project.tsconfigDev?.file.addOverride(\"compilerOptions.paths\", tsPaths);\n }\n}\n","// eslint-disable-next-line import/no-extraneous-dependencies\nimport {\n AWS_STAGE_TYPE,\n AwsStageType,\n DEPLOYMENT_TARGET_ROLE,\n DeploymentTargetRoleType,\n} from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { BuildWorkflow, BuildWorkflowOptions } from \"projen/lib/build\";\nimport { GitHub } from \"projen/lib/github\";\nimport { JobPermission, JobStep } from \"projen/lib/github/workflows-model\";\nimport { ValueOf } from \"type-fest\";\nimport { AwsDeploymentConfig } from \"../aws\";\nimport { AwsDeploymentTarget } from \"../aws/aws-deployment-target\";\nimport { GitBranch } from \"../git\";\nimport { MonorepoProject } from \"../projects\";\nimport { ROOT_CI_TASK_NAME, TurboRepo } from \"../turbo\";\nimport { VERSION } from \"../versions\";\n\nexport const PROD_DEPLOY_NAME = \"prod-deploy\";\n\nexport interface DeployWorkflowOptions {\n /**\n * What type of deploy is this workflow for?\n *\n * @default AWS_STAGE_TYPE.DEV\n */\n readonly awsStageType?: ValueOf<typeof AWS_STAGE_TYPE>;\n\n /**\n * Optionally feed a list of targets to deploy to.\n *\n * @default discovers all targets using stageType\n */\n readonly awsDeploymentTargets?: Array<AwsDeploymentTarget>;\n\n /**\n * Existing workflow, useful if we're tacking deployments onto an existing\n * build workflow\n */\n readonly buildWorkflow?: BuildWorkflow;\n\n /**\n * Options for the build workflow, if no build workflow is provided.\n */\n readonly buildWorkflowOptions?: Partial<BuildWorkflowOptions>;\n\n /**\n * Projects that should complete deployment before this one starts.\n */\n readonly deployAfterTargets?: Array<AwsDeploymentTarget>;\n}\n\nexport class AwsDeployWorkflow extends Component {\n public static of(\n project: AwsCdkTypeScriptApp,\n buildWorkflow: BuildWorkflow,\n ): AwsDeployWorkflow | undefined {\n const isDefined = (c: Component): c is AwsDeployWorkflow =>\n c instanceof AwsDeployWorkflow && c.buildWorkflow === buildWorkflow;\n return project.components.find(isDefined);\n }\n\n /**\n * The root project for this deploy workflow. Must be a monorepo project.\n */\n private rootProject: MonorepoProject;\n\n /**\n * What type of deploy is this workflow for?\n */\n public awsStageType: AwsStageType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use deployment target role terminology elsewhere. This property is maintained for backward compatibility.\n * @default 'primary' (this is the only type supported currently)\n */\n public awsEnvironmentType: DeploymentTargetRoleType =\n DEPLOYMENT_TARGET_ROLE.PRIMARY;\n\n /**\n * The list of targets to deploy to.\n */\n readonly awsDeploymentTargets: Array<AwsDeploymentTarget>;\n\n /**\n * Hold the deploy workflow so we can add to it in preSynth\n */\n public buildWorkflow: BuildWorkflow;\n\n /**\n * Was this workflow created externally?\n */\n public externalWorkflow: boolean;\n\n /**\n * Projects that should complete deployment before this one starts.\n */\n public deployAfterTargets: Array<AwsDeploymentTarget>;\n\n constructor(\n public project: AwsCdkTypeScriptApp,\n public options: DeployWorkflowOptions = {},\n ) {\n super(project);\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(project.root instanceof MonorepoProject)) {\n throw new Error(\n \"AwsDeployWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsDeployWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * TurboRepo Check\n *\n * If turbo is enabled, we may need the options later in this file.\n *\n **************************************************************************/\n\n const turbo = TurboRepo.of(this.rootProject);\n const buildWorkflowOptions: Partial<BuildWorkflowOptions> =\n turbo?.remoteCacheOptions\n ? TurboRepo.buildWorkflowOptions(turbo.remoteCacheOptions)\n : {};\n\n /***************************************************************************\n *\n * Workflow Deploy Type\n *\n * What type of environments are we deploying into? We'll default to dev to\n * be safe.\n *\n **************************************************************************/\n\n this.awsStageType = options.awsStageType ?? AWS_STAGE_TYPE.DEV;\n\n /***************************************************************************\n *\n * Workflow Deploy Targets\n *\n * Use provided targets or discover them based on the deploy type. Only\n * include targets that are marked for CI/CD.\n *\n **************************************************************************/\n\n this.awsDeploymentTargets =\n options.awsDeploymentTargets ??\n AwsDeploymentConfig.of(project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === this.awsStageType && target.ciDeployment,\n ) ??\n [];\n\n this.deployAfterTargets = options.deployAfterTargets ?? [];\n\n /***************************************************************************\n *\n * Build Workflow Options\n *\n * Can't use the options if an existing workflow was passed in.\n *\n **************************************************************************/\n\n if (options.buildWorkflow && options.buildWorkflowOptions) {\n throw new Error(\n \"Cannot provide both buildWorkflow and buildWorkflowOptions\",\n );\n }\n\n this.externalWorkflow = !!options.buildWorkflow;\n\n /***************************************************************************\n *\n * Build Workflow\n *\n * Create a workflow either based on input or from scratch.\n *\n **************************************************************************/\n\n this.buildWorkflow =\n options.buildWorkflow ??\n new BuildWorkflow(this.rootProject, {\n /**\n * Name based on project and environment.\n */\n name:\n options.buildWorkflowOptions?.name ??\n [\n \"deploy\",\n project.name,\n this.awsStageType,\n this.awsEnvironmentType,\n ].join(\"-\"),\n\n /**\n * Use the root projects build task.\n */\n buildTask: this.rootProject.buildTask,\n\n /**\n * Use push triggers based n the branch config for each environment.\n */\n workflowTriggers: {\n push: {\n branches: [\n ...this.awsDeploymentTargets.flatMap((t) =>\n t.branches.map((b) => b.branch),\n ),\n ],\n },\n workflowDispatch: {},\n ...options.buildWorkflowOptions?.workflowTriggers,\n },\n\n /**\n * Never allow mutations for deploys. This should have been handled\n * during build.\n */\n mutableBuild: false,\n\n /**\n * Do this pre-merge of permissions and build steps\n */\n ...options.buildWorkflowOptions,\n\n /**\n * Set BRANCH_NAME so Turborepo remote cache hashes match between local and CI.\n */\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n ...options.buildWorkflowOptions?.env,\n ...buildWorkflowOptions?.env,\n },\n\n /**\n * Some additional permissions may be required when turbo's involved.\n */\n permissions: {\n ...options.buildWorkflowOptions?.permissions,\n ...buildWorkflowOptions?.permissions,\n },\n\n /**\n * Assemble all pre-build steps\n */\n preBuildSteps: [\n ...this.setupPnpm(),\n ...this.setupNode(),\n {\n name: \"Install dependencies\",\n run: \"pnpm i --no-frozen-lockfile\",\n },\n ...(options.buildWorkflowOptions?.preBuildSteps ?? []),\n ...(buildWorkflowOptions?.preBuildSteps ?? []),\n ],\n });\n\n /***************************************************************************\n *\n * Add Deployments to workflow\n *\n **************************************************************************/\n\n const buildJobName = (target: AwsDeploymentTarget) => {\n return [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n };\n\n this.awsDeploymentTargets.forEach((target) => {\n const deployJobName = buildJobName(target);\n\n // Build the branch filter condition\n const branchFilterCondition = this.buildBranchFilterCondition(\n target.branches,\n );\n\n // Combine with the existing build mutation check\n const jobCondition = branchFilterCondition\n ? \"${{ \" +\n [\n \"!needs.build.outputs.self_mutation_happened\",\n `(${branchFilterCondition})`,\n ].join(\" && \") +\n \" }}\"\n : \"${{ !needs.build.outputs.self_mutation_happened }}\";\n\n this.buildWorkflow.addPostBuildJob(deployJobName, {\n name: `Deploy ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,\n needs: [\n \"build\",\n ...this.deployAfterTargets.map((p) => {\n return buildJobName(p);\n }),\n ],\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n concurrency: deployJobName,\n if: jobCondition,\n steps: [...this.deploySteps(target)],\n });\n });\n }\n\n public setupNode = (): Array<JobStep> => {\n return [\n {\n name: \"Setup Node\",\n uses: \"actions/setup-node@v4\",\n with: {\n [\"node-version\"]: VERSION.NODE_WORKFLOWS,\n },\n // occasionally this step fails due to internal issues at github\n timeoutMinutes: 1,\n },\n ];\n };\n\n public setupPnpm = (): Array<JobStep> => {\n return [\n {\n name: \"Setup PNPM\",\n uses: \"pnpm/action-setup@v3\",\n with: {\n version: VERSION.PNPM_VERSION,\n },\n },\n ];\n };\n\n /**\n * Builds a GitHub Actions condition string that checks if the current branch\n * matches any of the provided branch patterns.\n *\n * Handles both exact matches (e.g., \"main\") and glob patterns (e.g., \"feature/*\").\n * Also allows workflow_dispatch (manual runs) to proceed.\n *\n * @param branches Array of GitBranch objects with branch patterns\n * @returns Condition string or empty string if no branches provided\n */\n private buildBranchFilterCondition = (branches: Array<GitBranch>): string => {\n if (!branches || branches.length === 0) {\n return \"\";\n }\n\n const conditions: Array<string> = [];\n\n // Always allow workflow_dispatch (manual workflow runs)\n conditions.push(\"github.event_name == 'workflow_dispatch'\");\n\n for (const branch of branches) {\n const branchPattern = branch.branch;\n\n // Handle glob patterns (e.g., \"feature/*\")\n if (branchPattern.includes(\"*\")) {\n // Replace * with proper startsWith check\n const prefix = branchPattern.replace(/\\*.*$/, \"\");\n conditions.push(`startsWith(github.ref, 'refs/heads/${prefix}')`);\n // PR support, unprefixed branch names\n conditions.push(`startsWith(github.head_ref, '${prefix}')`);\n } else {\n // Exact match\n conditions.push(`github.ref == 'refs/heads/${branchPattern}'`);\n }\n }\n\n /**\n * Combine all conditions with OR\n */\n return conditions.join(\" || \");\n };\n\n private deploySteps = (target: AwsDeploymentTarget): Array<JobStep> => {\n const {\n awsStageType,\n deploymentTargetRole,\n account,\n region,\n ciDeploymentConfig,\n awsDeploymentConfig,\n } = target;\n const { roleArn, stackPattern } = ciDeploymentConfig ?? {};\n const { rootCdkOut } = awsDeploymentConfig;\n\n return [\n ...this.setupPnpm(),\n ...this.setupNode(),\n\n /**\n * Install CDK\n */\n {\n name: \"Install CDK\",\n run: \"pnpm add aws-cdk\",\n },\n\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Run CDK Deploy\n */\n {\n name: `Deploy ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,\n run: `pnpm dlx aws-cdk deploy --no-rollback --require-approval=never --app=${rootCdkOut} \"${stackPattern}\"`,\n },\n ];\n };\n\n preSynthesize(): void {\n /**\n * Ensure turbo is active when needed.\n */\n if (!this.externalWorkflow && TurboRepo.of(this.rootProject)) {\n this.buildWorkflow.addPostBuildSteps({\n name: \"Build Sub Projects\",\n run: `npx projen ${ROOT_CI_TASK_NAME}`,\n });\n }\n\n super.preSynthesize();\n }\n}\n"],"mappings":"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","names":["exports","exports","exports","exports","import_lib","import_utils","import_projen","import_projen","import_projen","import_javascript","import_ts_deepmerge","import_projen","import_projen","import_projen","import_node_path","import_projen","import_path","import_utils","import_projen","import_workflows_model"]}
|
|
1
|
+
{"version":3,"sources":["../../utils/src/aws/aws-types.ts","../../utils/src/git/git-utils.ts","../../utils/src/string/string-utils.ts","../../utils/src/index.ts","../src/index.ts","../src/aws/aws-deployment-config.ts","../src/turbo/turbo-repo-task.ts","../src/turbo/turbo-repo.ts","../src/aws/aws-deployment-target.ts","../src/latest-eligible-version.ts","../src/version-package-map.ts","../src/versions.ts","../src/jsii/jsii-faker.ts","../src/pnpm/pnpm-workspace.ts","../src/projects/monorepo-project.ts","../src/tasks/reset-task.ts","../src/projects/typescript-project.ts","../src/vscode/vscode.ts","../src/typescript/typescript-config.ts","../src/workflows/aws-deploy-workflow.ts"],"sourcesContent":["/**\n * Stage Types\n *\n * What stage of deployment is this? Dev, staging, or prod?\n */\nexport const AWS_STAGE_TYPE = {\n /**\n * Development environment, typically used for testing and development.\n */\n DEV: \"dev\",\n\n /**\n * Staging environment, used for pre-production testing.\n */\n STAGE: \"stage\",\n\n /**\n * Production environment, used for live deployments.\n */\n PROD: \"prod\",\n} as const;\n\n/**\n * Above const as a type.\n */\nexport type AwsStageType = (typeof AWS_STAGE_TYPE)[keyof typeof AWS_STAGE_TYPE];\n\n/**\n * Deployment target role: whether an (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n */\nexport const DEPLOYMENT_TARGET_ROLE = {\n /**\n * Account and region that represents the primary region for this service.\n * For example, the base DynamoDB Region for global tables.\n */\n PRIMARY: \"primary\",\n /**\n * Account and region that represents a secondary region for this service.\n * For example, a replica region for a global DynamoDB table.\n */\n SECONDARY: \"secondary\",\n} as const;\n\n/**\n * Type for deployment target role values.\n */\nexport type DeploymentTargetRoleType =\n (typeof DEPLOYMENT_TARGET_ROLE)[keyof typeof DEPLOYMENT_TARGET_ROLE];\n\n/**\n * Environment types (primary/secondary).\n *\n * @deprecated Use {@link DEPLOYMENT_TARGET_ROLE} instead. This constant is maintained for backward compatibility.\n */\nexport const AWS_ENVIRONMENT_TYPE = DEPLOYMENT_TARGET_ROLE;\n\n/**\n * Type for environment type values.\n *\n * @deprecated Use {@link DeploymentTargetRoleType} instead. This type is maintained for backward compatibility.\n */\nexport type AwsEnvironmentType = DeploymentTargetRoleType;\n","import { execSync } from \"node:child_process\";\n\n/**\n * Returns the current full git branch name\n *\n * ie: feature/1234 returns feature/1234\n *\n */\nexport const findGitBranch = (): string => {\n return execSync(\"git rev-parse --abbrev-ref HEAD\")\n .toString(\"utf8\")\n .replace(/[\\n\\r\\s]+$/, \"\");\n};\n\nexport const findGitRepoName = (): string => {\n /**\n * When running in github actions this will be populated.\n */\n if (process.env.GITHUB_REPOSITORY) {\n return process.env.GITHUB_REPOSITORY;\n }\n\n /**\n * locally, we need to extract the repo name from the git config.\n */\n const remote = execSync(\"git config --get remote.origin.url\")\n .toString(\"utf8\")\n .replace(/[\\n\\r\\s]+$/, \"\")\n .trim();\n\n const match = remote.match(/[:\\/]([^/]+\\/[^/]+?)(?:\\.git)?$/);\n const repoName = match ? match[1] : \"error-repo-name\";\n\n return repoName;\n};\n","import * as crypto from \"node:crypto\";\n\n/**\n *\n * @param inString string to hash\n * @param trimLength trim to this length (defaults to 999 chars)\n * @returns\n */\nexport const hashString = (inString: string, trimLength: number = 999) => {\n return crypto\n .createHash(\"sha256\")\n .update(inString)\n .digest(\"hex\")\n .substring(0, trimLength);\n};\n\n/**\n *\n * @param inputString string to truncate\n * @param maxLength max length of this string\n * @returns trimmed string\n */\nexport const trimStringLength = (inputString: string, maxLength: number) => {\n return inputString.length < maxLength\n ? inputString\n : inputString.substring(0, maxLength);\n};\n","export * from \"./aws/aws-types\";\nexport * from \"./git/git-utils\";\nexport * from \"./string/string-utils\";\n","export * from \"./aws/\";\nexport * from \"./git/\";\nexport * from \"./latest-eligible-version\";\nexport * from \"./version-package-map\";\nexport * from \"./versions\";\nexport * from \"./jsii/\";\nexport * from \"./pnpm/\";\nexport * from \"./projects/\";\nexport * from \"./tasks/\";\nexport * from \"./turbo/\";\nexport * from \"./typescript/\";\nexport * from \"./vscode/\";\nexport * from \"./workflows/\";\n","import { join, relative } from \"node:path\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { AWS_STAGE_TYPE } from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { AwsDeploymentTarget } from \"./aws-deployment-target\";\nimport { TurboRepo } from \"../turbo\";\n\n/*******************************************************************************\n *\n * AWS Deployment Configuration\n *\n * This component allows configuration of multiple AWS deployment\n * targets, each with its own account, region, and deployment type\n * (dev, stage, prod). It supports both local and CI deployments,\n * with customizable settings for each target.\n *\n ******************************************************************************/\n\n/*\nexport interface AwsDeploymentConfigOptions {}\n*/\n\nexport class AwsDeploymentConfig extends Component {\n public static of(\n project: AwsCdkTypeScriptApp,\n ): AwsDeploymentConfig | undefined {\n const isDefined = (c: Component): c is AwsDeploymentConfig =>\n c instanceof AwsDeploymentConfig;\n return project.components.find(isDefined);\n }\n\n /**\n * Environment variables to be injected into all tasks.\n */\n public readonly env: Record<string, string>;\n\n /**\n * The relative path to the project directory from the root of the project.\n */\n public readonly projectPath: string;\n\n /**\n * The relative path to the root of the project from the output directory.\n */\n public readonly rootPath: string;\n\n /**\n * The output directory for the CDK synthesis, from the root directory.\n */\n public readonly rootCdkOut: string;\n\n /**\n * The output directory for the CDK synthesis.\n */\n public readonly cdkOut: string;\n\n /**\n * Array of targets for deployment.\n */\n public readonly awsDeploymentTargets: Array<AwsDeploymentTarget> = [];\n\n constructor(project: AwsCdkTypeScriptApp) {\n super(project);\n\n /**\n * Common variables used across tasks.\n */\n this.env = { GIT_BRANCH: \"$(git branch --show-current)\" };\n this.projectPath = relative(project.root.outdir, project.outdir);\n this.rootPath = relative(project.outdir, project.root.outdir);\n this.rootCdkOut = join(\"dist\", this.projectPath, \"cdk.out\");\n this.cdkOut = join(this.rootPath, \"dist\", this.projectPath, \"cdk.out\");\n\n /**\n * Reset some tasks we will rebuild below.\n */\n [\"deploy\", \"watch\"].forEach((taskName) => {\n const task = project.tasks.tryFind(taskName);\n if (task) {\n task.reset();\n task.say(\n \"Generic task is disabled. Please use the specific task for your deployment target.\",\n );\n }\n });\n\n /**\n * Redefine Synth here\n *\n * Deploy and watch get reconfigured per deployment target.\n * @see addDeploymentTarget()\n */\n this.configureSynthTask();\n }\n\n /*****************************************************************************\n *\n * Target filter helpers\n *\n * Return various targets for deployment scripts to use.\n *\n ****************************************************************************/\n\n /**\n * @returns All production deployment targets.\n */\n public get prodTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.PROD,\n );\n }\n public get prodTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.PROD && target.ciDeployment,\n );\n }\n public get prodTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.PROD && target.localDeployment,\n );\n }\n\n /**\n *\n * @returns All stage deployment targets.\n */\n public get stageTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.STAGE,\n );\n }\n public get stageTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.STAGE && target.ciDeployment,\n );\n }\n public get stageTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.STAGE && target.localDeployment,\n );\n }\n\n /**\n *\n * @returns All dev deployment targets.\n */\n public get devTargets(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) => target.awsStageType === AWS_STAGE_TYPE.DEV,\n );\n }\n public get devTargetsForCI(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.DEV && target.ciDeployment,\n );\n }\n public get devTargetsForLocal(): Array<AwsDeploymentTarget> {\n return this.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === AWS_STAGE_TYPE.DEV && target.localDeployment,\n );\n }\n\n /*****************************************************************************\n *\n * Synth Tasks\n *\n * - Configure synth task to use the branch name\n * - Change the output location for easier workflows.\n *\n ****************************************************************************/\n\n private configureSynthTask = (): void => {\n this.project.tasks.tryFind(\"synth\")?.reset(`rm -rf ${this.cdkOut}`);\n this.project.tasks\n .tryFind(\"synth\")\n ?.exec(`cdk synth --output ${this.cdkOut}`, { env: this.env });\n\n this.project.tasks.tryFind(\"synth:silent\")?.reset(`rm -rf ${this.cdkOut}`);\n this.project.tasks\n .tryFind(\"synth:silent\")\n ?.exec(`cdk synth -q --output ${this.cdkOut}`, { env: this.env });\n };\n\n preSynthesize(): void {\n super.preSynthesize();\n\n /**\n * If turbo's active we should ensure the post compile task\n * is configured to consider the cdk output directory in it's root location.\n */\n if (TurboRepo.of(this.project)) {\n const turbo = TurboRepo.of(this.project)!;\n turbo.postCompileTask?.outputs.push(join(this.cdkOut, \"**\"));\n }\n }\n}\n","import { Component, Project } from \"projen/lib\";\n\n/**\n * Each of the below options corresponds to a task property found here:\n * * https://turborepo.com/docs/reference/configuration#defining-tasks\n */\nexport interface TurboRepoTaskOptions {\n readonly name: string;\n readonly dependsOn?: Array<string>;\n readonly env?: Array<string>;\n readonly passThroughEnv?: Array<string>;\n readonly outputs?: Array<string>;\n readonly cache?: boolean;\n readonly inputs?: Array<string>;\n readonly outputLogs?:\n | \"full\"\n | \"hash-only\"\n | \"new-only\"\n | \"errors-only\"\n | \"none\";\n readonly persistent?: boolean;\n readonly interactive?: boolean;\n}\n\nexport class TurboRepoTask extends Component {\n public readonly name: string;\n public dependsOn: Array<string>;\n public readonly env: Array<string>;\n public readonly passThroughEnv: Array<string>;\n public outputs: Array<string>;\n public cache: boolean;\n public inputs: Array<string>;\n public readonly outputLogs:\n | \"full\"\n | \"hash-only\"\n | \"new-only\"\n | \"errors-only\"\n | \"none\";\n public readonly persistent: boolean;\n public readonly interactive: boolean;\n\n /**\n * Include this task in turbo.json output?\n */\n public isActive: boolean;\n\n constructor(\n public readonly project: Project,\n options: TurboRepoTaskOptions,\n ) {\n super(project);\n\n this.name = options.name;\n this.dependsOn = options.dependsOn ?? [];\n this.env = options.env ?? [];\n this.passThroughEnv = options.passThroughEnv ?? [];\n this.outputs = options.outputs ?? [];\n this.cache = options.cache ?? true;\n this.inputs = [\n ...(options.inputs ?? []),\n // rerun if projen config changes\n \".projen/**\",\n // ignore mac files\n \"!.DS_Store\",\n \"!**/.DS_Store\",\n ];\n this.outputLogs = options.outputLogs ?? \"new-only\";\n this.persistent = options.persistent ?? false;\n this.interactive = options.interactive ?? false;\n this.isActive = true;\n }\n\n public taskConfig(): Record<string, any> {\n return {\n dependsOn: this.dependsOn,\n env: this.env,\n passThroughEnv: this.passThroughEnv,\n outputs: this.outputs,\n cache: this.cache,\n inputs: this.inputs,\n outputLogs: this.outputLogs,\n persistent: this.persistent,\n interactive: this.interactive,\n };\n }\n}\n","import { Component, FileBase, JsonFile, Project, Task } from \"projen/lib\";\nimport { BuildWorkflowOptions } from \"projen/lib/build\";\nimport { JobPermission } from \"projen/lib/github/workflows-model\";\nimport { NodeProject } from \"projen/lib/javascript\";\nimport { TurboRepoTask } from \"./turbo-repo-task\";\n\n/*******************************************************************************\n *\n * Turbo Repo Config\n *\n ******************************************************************************/\n\nexport const ROOT_TURBO_TASK_NAME = \"turbo:build\";\nexport const ROOT_CI_TASK_NAME = \"build:all\";\n\nexport interface RemoteCacheOptions {\n /**\n * Local profile name to use when fetching the cache endpoint and token.\n */\n readonly profileName: string;\n\n /**\n * OIDC role to assume when fetching the cache endpoint and token.\n */\n readonly oidcRole: string;\n\n /**\n * Name for the params used to store the cache endpoint.\n */\n readonly endpointParamName: string;\n\n /**\n * Name for the params used to store the cache's API token.\n */\n readonly tokenParamName: string;\n\n /**\n * team name used in remote cache commands\n */\n readonly teamName: string;\n}\n\nexport interface TurboRepoOptions {\n /**\n * Version of turborepo to use.\n *\n * @default: specified in versions file\n */\n readonly turboVersion?: string;\n\n /**\n * Extend from the root turbo.json to create specific configuration for a package using Package Configurations.\n *\n * The only valid value for extends is [\"//\"] to inherit configuration from the root turbo.json.\n * If extends is used in the root turbo.json, it will be ignored.\n *\n * https://turbo.build/repo/docs/reference/configuration#extends\n */\n readonly extends?: Array<string>;\n\n /**\n * A list of globs that you want to include in all task hashes. If any file matching these globs changes, all tasks will miss cache. Globs are relative to the location of turbo.json.\n *\n * By default, all files in source control in the Workspace root are included in the global hash.\n *\n * Globs must be in the repository's source control root. Globs outside of the repository aren't supported.\n *\n * https://turbo.build/repo/docs/reference/configuration#globaldependencies\n */\n readonly globalDependencies?: Array<string>;\n\n /**\n * A list of environment variables that you want to impact the hash of all tasks. Any change to these environment variables will cause all tasks to miss cache.\n *\n * For more on wildcard and negation syntax, see the env section.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalenv\n */\n readonly globalEnv?: Array<string>;\n\n /**\n * A list of environment variables that you want to make available to tasks.\n * Using this key opts all tasks into Strict\n * Environment Variable Mode.\n *\n * Additionally, Turborepo has a built-in set of global passthrough variables\n * for common cases, like operating system environment variables. This\n * includes variables like HOME, PATH, APPDATA, SHELL, PWD, and more. The full\n * list can be found in the source code.\n *\n * Passthrough values do not contribute to hashes for caching\n *\n * If you want changes in these variables to cause cache misses, you will need\n * to include them in env or globalEnv.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalpassthroughenv\n */\n readonly globalPassThroughEnv?: Array<string>;\n\n /**\n * @default: \"stream\"\n *\n * Select a terminal UI for the repository.\n *\n * \"tui\" allows for viewing each log at once and interacting with the task.\n * \"stream\" outputs logs as they come in and is not interactive.\n *\n * https://turbo.build/repo/docs/reference/configuration#ui\n */\n readonly ui?: \"tui\" | \"stream\";\n\n /**\n * @default: false\n *\n * Turborepo uses your repository's lockfile to determine caching behavior,\n * Package Graphs, and more. Because of this, we use the packageManager field\n * to help you stabilize your Turborepo.\n *\n * To help with incremental migration or in situations where you can't use\n * the packageManager field, you may use\n * --dangerously-disable-package-manager-check to opt out of this check and\n * assume the risks of unstable lockfiles producing unpredictable behavior.\n * When disabled, Turborepo will attempt a best-effort discovery of the\n * intended package manager meant for the repository.\n *\n * https://turbo.build/repo/docs/reference/configuration#dangerouslydisablepackagemanagercheck\n */\n readonly dangerouslyDisablePackageManagerCheck?: boolean;\n\n /**\n * @default: \".turbo/cache\"\n *\n * Specify the filesystem cache directory.\n *\n * https://turbo.build/repo/docs/reference/configuration#cachedir\n */\n readonly cacheDir?: string;\n\n /**\n * @default: true\n *\n * Turborepo runs a background process to pre-calculate some expensive\n * operations. This standalone process (daemon) is a performance optimization,\n * and not required for proper functioning of turbo.\n *\n * https://turbo.build/repo/docs/reference/configuration#daemon\n */\n readonly daemon?: boolean;\n\n /**\n * @default: \"strict\"\n *\n * Turborepo's Environment Modes allow you to control which environment\n * variables are available to a task at runtime:\n *\n *\"strict\": Filter environment variables to only those that are specified\n * in the env and globalEnv keys in turbo.json.\n *\n * \"loose\": Allow all environment variables for the process to be available.\n *\n * https://turbo.build/repo/docs/reference/configuration#envmode\n */\n readonly envMode?: string;\n\n /*****************************************************************************\n *\n * Cache Settings\n *\n ****************************************************************************/\n\n /**\n * Cache settings, if using remote cache.\n */\n readonly remoteCacheOptions?: RemoteCacheOptions;\n\n /**\n * Env Args that will bre added to turbo's build:all task\n *\n * @default: {}\n */\n readonly buildAllTaskEnvVars?: Record<string, string>;\n\n /*****************************************************************************\n *\n * Tasks - Optionally define a different projen task for one of the lifecycle\n * steps.\n *\n ****************************************************************************/\n\n /**\n * Pre compile task\n *\n * @default: \"pre-compile\"\n */\n readonly preCompileTask?: Task;\n\n /**\n * Compile task\n *\n * @default: \"compile\"\n */\n readonly compileTask?: Task;\n\n /**\n * Post compile task\n *\n * @default: \"post-compile\"\n */\n readonly postCompileTask?: Task;\n\n /**\n * Test task\n *\n * @default: \"test\"\n */\n readonly testTask?: Task;\n\n /**\n * Package task\n *\n * @default: \"package\"\n */\n readonly packageTask?: Task;\n}\n\nexport class TurboRepo extends Component {\n /**\n * Static method to discovert turbo in a project.\n */\n public static of(project: Project): TurboRepo | undefined {\n const isDefined = (c: Component): c is TurboRepo => c instanceof TurboRepo;\n return project.components.find(isDefined);\n }\n\n public static buildWorkflowOptions = (\n remoteCacheOptions: RemoteCacheOptions,\n ): Partial<BuildWorkflowOptions> => {\n return {\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n },\n permissions: {\n contents: JobPermission.WRITE,\n idToken: JobPermission.WRITE,\n },\n preBuildSteps: [\n {\n name: \"AWS Creds for SSM\",\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n [\"role-to-assume\"]: remoteCacheOptions.oidcRole,\n [\"aws-region\"]: \"us-east-1\",\n [\"role-duration-seconds\"]: \"900\",\n },\n },\n ],\n };\n };\n\n /**\n * Version of turborepo to use.\n */\n public readonly turboVersion: string;\n\n /**\n * Extend from the root turbo.json to create specific configuration for a package using Package Configurations.\n *\n * The only valid value for extends is [\"//\"] to inherit configuration from the root turbo.json.\n * If extends is used in the root turbo.json, it will be ignored.\n *\n * https://turbo.build/repo/docs/reference/configuration#extends\n */\n public readonly extends: Array<string>;\n\n /**\n * A list of globs that you want to include in all task hashes. If any file matching these globs changes, all tasks will miss cache. Globs are relative to the location of turbo.json.\n *\n * By default, all files in source control in the Workspace root are included in the global hash.\n *\n * Globs must be in the repository's source control root. Globs outside of the repository aren't supported.\n *\n * https://turbo.build/repo/docs/reference/configuration#globaldependencies\n */\n public readonly globalDependencies: Array<string>;\n\n /**\n * A list of environment variables that you want to impact the hash of all tasks. Any change to these environment variables will cause all tasks to miss cache.\n *\n * For more on wildcard and negation syntax, see the env section.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalenv\n */\n public readonly globalEnv: Array<string>;\n\n /**\n * A list of environment variables that you want to make available to tasks.\n * Using this key opts all tasks into Strict\n * Environment Variable Mode.\n *\n * Additionally, Turborepo has a built-in set of global passthrough variables\n * for common cases, like operating system environment variables. This\n * includes variables like HOME, PATH, APPDATA, SHELL, PWD, and more. The full\n * list can be found in the source code.\n *\n * Passthrough values do not contribute to hashes for caching\n *\n * If you want changes in these variables to cause cache misses, you will need\n * to include them in env or globalEnv.\n *\n * https://turbo.build/repo/docs/reference/configuration#globalpassthroughenv\n */\n public readonly globalPassThroughEnv: Array<string>;\n\n /**\n * @default: \"stream\"\n *\n * Select a terminal UI for the repository.\n *\n * \"tui\" allows for viewing each log at once and interacting with the task.\n * \"stream\" outputs logs as they come in and is not interactive.\n *\n * https://turbo.build/repo/docs/reference/configuration#ui\n */\n public readonly ui: \"tui\" | \"stream\";\n\n /**\n * @default: false\n *\n * Turborepo uses your repository's lockfile to determine caching behavior,\n * Package Graphs, and more. Because of this, we use the packageManager field\n * to help you stabilize your Turborepo.\n *\n * To help with incremental migration or in situations where you can't use\n * the packageManager field, you may use\n * --dangerously-disable-package-manager-check to opt out of this check and\n * assume the risks of unstable lockfiles producing unpredictable behavior.\n * When disabled, Turborepo will attempt a best-effort discovery of the\n * intended package manager meant for the repository.\n *\n * https://turbo.build/repo/docs/reference/configuration#dangerouslydisablepackagemanagercheck\n */\n public readonly dangerouslyDisablePackageManagerCheck: boolean;\n\n /**\n * @default: \".turbo/cache\"\n *\n * Specify the filesystem cache directory.\n *\n * https://turbo.build/repo/docs/reference/configuration#cachedir\n */\n public readonly cacheDir: string;\n\n /**\n * @default: true\n *\n * Turborepo runs a background process to pre-calculate some expensive\n * operations. This standalone process (daemon) is a performance optimization,\n * and not required for proper functioning of turbo.\n *\n * https://turbo.build/repo/docs/reference/configuration#daemon\n */\n public readonly daemon: boolean;\n\n /**\n * @default: \"strict\"\n *\n * Turborepo's Environment Modes allow you to control which environment\n * variables are available to a task at runtime:\n *\n *\"strict\": Filter environment variables to only those that are specified\n * in the env and globalEnv keys in turbo.json.\n *\n * \"loose\": Allow all environment variables for the process to be available.\n *\n * https://turbo.build/repo/docs/reference/configuration#envmode\n */\n public readonly envMode: string;\n\n /*****************************************************************************\n *\n * Cache Settings\n *\n ****************************************************************************/\n\n /**\n * Cache settings, if using remote cache.\n */\n public readonly remoteCacheOptions?: RemoteCacheOptions;\n\n /**\n * is this the root project?\n */\n public readonly isRootProject: boolean;\n\n /**\n * Turbo's build:all task at the root of the monorepo.\n *\n * This is a normal projen task that runs the root turbo task.\n */\n public readonly buildAllTask?: Task;\n\n /**\n * Main turbo:build task\n *\n * This is a special Turbo task\n */\n public readonly buildTask: TurboRepoTask;\n\n /**\n * pre compile task\n */\n public readonly preCompileTask?: TurboRepoTask;\n\n /**\n * compile task\n */\n public readonly compileTask?: TurboRepoTask;\n\n /**\n * post compile task\n */\n public readonly postCompileTask?: TurboRepoTask;\n\n /**\n * Test task\n */\n public readonly testTask?: TurboRepoTask;\n\n /**\n * Package task\n */\n public readonly packageTask?: TurboRepoTask;\n\n /**\n * Sub-Tasks to run\n */\n public readonly tasks: Array<TurboRepoTask> = [];\n\n /**\n * Env Args that will bre added to turbo's build:all task\n */\n public readonly buildAllTaskEnvVars: Record<string, string>;\n\n constructor(\n public readonly project: NodeProject,\n options: TurboRepoOptions = {},\n ) {\n super(project);\n\n this.turboVersion = options.turboVersion ?? \"catalog:\";\n this.isRootProject = project === project.root;\n\n /**\n * Add turborepo package to root project.\n */\n if (this.isRootProject) {\n project.addDevDeps(`turbo@${this.turboVersion}`);\n }\n\n /**\n * Ignore the working cache for turbo.\n */\n project.gitignore.addPatterns(\"/.turbo\");\n project.npmignore?.addPatterns(\"/.turbo/\");\n\n /***************************************************************************\n *\n * Set some default options\n *\n **************************************************************************/\n\n this.extends = options.extends ?? (this.isRootProject ? [] : [\"//\"]);\n this.globalDependencies = options.globalDependencies ?? [];\n this.globalEnv = options.globalEnv ?? [];\n this.globalPassThroughEnv = options.globalPassThroughEnv ?? [];\n this.ui = options.ui ?? \"stream\";\n this.dangerouslyDisablePackageManagerCheck =\n options.dangerouslyDisablePackageManagerCheck ?? false;\n this.cacheDir = options.cacheDir ?? \".turbo/cache\";\n this.daemon = options.daemon ?? true;\n this.envMode = options.envMode ?? \"strict\";\n this.remoteCacheOptions = options.remoteCacheOptions;\n this.buildAllTaskEnvVars = options.buildAllTaskEnvVars ?? {};\n\n /***************************************************************************\n *\n * Turbo Build Task\n *\n * All turbo configs contain a turbo build task.\n *\n **************************************************************************/\n\n /**\n * The turbo entry point definition for the turbo:build task. This exists\n * in each project and is written tot he turbo.json file. This task is not\n * a projen task or a Node task.\n */\n this.buildTask = new TurboRepoTask(this.project, {\n name: ROOT_TURBO_TASK_NAME,\n dependsOn: this.isRootProject ? [`^${ROOT_TURBO_TASK_NAME}`] : [],\n });\n\n /***************************************************************************\n *\n * Turbo Build All Task\n *\n * The Projen entry point. This only exists in the root and is a projen\n * task that can be run using pnpm.\n *\n * - Turns off telemetry\n * - Runs root turbo task to build all sub-projects.\n *\n **************************************************************************/\n\n if (this.isRootProject) {\n /**\n * Create and configure the build all task.\n */\n this.buildAllTask = this.project.tasks.addTask(ROOT_CI_TASK_NAME, {\n description:\n \"Root build followed by sub-project builds. Mimics the CI build process in one step.\",\n });\n this.buildAllTask.exec(\"turbo telemetry disable\");\n\n /**\n * Any env vars that may need to be added to the build all task.\n */\n if (this.buildAllTaskEnvVars) {\n Object.entries(this.buildAllTaskEnvVars).forEach(([name, value]) => {\n this.addGlobalEnvVar(name, value);\n });\n }\n\n /**\n * No remote cache in use, so run the root turbo task to build all\n * sub-projects locally.\n */\n if (!this.remoteCacheOptions) {\n this.buildAllTask.exec(\n `turbo ${ROOT_TURBO_TASK_NAME} --summarize --concurrency=10`,\n );\n } else {\n /**\n * Remote cache in use, so run the root turbo task to build all\n * sub-projects using the remote cache.\n */\n this.buildAllTask.exec(\n `turbo turbo:build --summarize --concurrency=10 --cache=remote:rw --api=$TURBO_ENDPOINT --token=$TURBO_TOKEN --team=${this.remoteCacheOptions.teamName}`,\n {\n condition: '[ ! -n \"$CI\" ]',\n env: {\n TURBO_ENDPOINT: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.endpointParamName} --query Parameter.Value --output text --profile ${this.remoteCacheOptions.profileName})`,\n TURBO_TOKEN: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.tokenParamName} --query Parameter.Value --output text --profile ${this.remoteCacheOptions.profileName})`,\n },\n },\n );\n // running in CI, We'll depend on OIDC auth.\n this.buildAllTask.exec(\n `turbo turbo:build --summarize --concurrency=10 --cache=remote:rw --api=$TURBO_ENDPOINT --token=$TURBO_TOKEN --team=${this.remoteCacheOptions.teamName}`,\n {\n condition: '[ -n \"$CI\" ]',\n env: {\n TURBO_ENDPOINT: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.endpointParamName} --query Parameter.Value --output text)`,\n TURBO_TOKEN: `$(aws ssm get-parameter --name ${this.remoteCacheOptions.tokenParamName} --query Parameter.Value --output text)`,\n },\n },\n );\n }\n }\n\n /**\n * SUB-PROJECT\n *\n * Creates tasks for the typical lifecycle for all project projects.\n */\n if (!this.isRootProject) {\n /**\n * All generated files in the project. Include these as inputs to the\n * compile related tasks.\n */\n const generatedFiles = this.project.components\n .filter((c): c is FileBase => c instanceof FileBase)\n .map((c) => c.path);\n\n this.preCompileTask = new TurboRepoTask(project, {\n name: options.preCompileTask?.name ?? \"pre-compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.compileTask = new TurboRepoTask(project, {\n name: options.compileTask?.name ?? \"compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.postCompileTask = new TurboRepoTask(project, {\n name: options.postCompileTask?.name ?? \"post-compile\",\n inputs: [\"src/**\", ...generatedFiles],\n });\n this.testTask = new TurboRepoTask(project, {\n name: options.testTask?.name ?? \"test\",\n });\n this.packageTask = new TurboRepoTask(project, {\n name: options.packageTask?.name ?? \"package\",\n inputs: [\".npmignore\"],\n });\n this.tasks.push(\n this.preCompileTask,\n this.compileTask,\n this.postCompileTask,\n this.testTask,\n this.packageTask,\n );\n }\n }\n\n /**\n * Add an env var to the global env vars for all tasks.\n * This will also become an input for the build:all task cache at the root.\n */\n public addGlobalEnvVar(name: string, value: string) {\n /**\n * Add env var to global task env\n */\n this.buildAllTask?.env(name, value);\n\n /**\n * Add to global env vars for all tasks.\n */\n if (this.isRootProject) {\n this.globalEnv.push(name);\n }\n }\n\n public activateBranchNameEnvVar() {\n this.addGlobalEnvVar(\n \"BRANCH_NAME\",\n \"${BRANCH_NAME:-$(git rev-parse --abbrev-ref HEAD)}\",\n );\n }\n\n preSynthesize(): void {\n /**\n * Add any local workspace specific deps to dependsOn so that we know\n * compile has finished before attempting to use any distribution artifacts.\n *\n * Do this in presynth so that we can be sure all project dependencies have\n * been defined first.\n */\n let nextDependsOn = this.project.deps.all\n .filter((d) => d.version === \"workspace:*\")\n .map((d) => [d.name, ROOT_TURBO_TASK_NAME].join(\"#\"));\n\n /**\n * Loop over all projen tasks and their corresponding turbo task\n * definitions. Chain them together using dependsOn, along with any outside\n * package dependencies.\n */\n if (!this.isRootProject) {\n (\n [\n [this.project.preCompileTask, this.preCompileTask],\n [this.project.compileTask, this.compileTask],\n [this.project.postCompileTask, this.postCompileTask],\n [this.project.testTask, this.testTask],\n [this.project.packageTask, this.packageTask],\n ] as Array<[Task, TurboRepoTask]>\n ).forEach(([pjTask, turboTask]) => {\n /**\n * If steps exist chain using dependsOn\n */\n if (pjTask && turboTask && pjTask.steps.length > 0) {\n if (nextDependsOn.length > 0) {\n turboTask.dependsOn.push(...nextDependsOn);\n }\n nextDependsOn = [turboTask.name];\n\n /**\n * Otherwise, if a task doesn't do anything, deactivate it.\n */\n } else {\n turboTask.isActive = false;\n }\n });\n\n /**\n * Main build entry point depends on whatever was last.\n */\n this.buildTask.dependsOn.push(...nextDependsOn);\n }\n\n /**\n * The name for the turbo config file.\n */\n const fileName: string = \"turbo.json\";\n\n /**\n * Ensure that turbo config doesn't end up in any package distributions.\n */\n this.project.addPackageIgnore(fileName);\n\n /**\n * The content of this YAML file will be resolved at synth time. By then,\n * any sub-projects will be defined and this will be a complete list.\n */\n new JsonFile(this.project, fileName, {\n obj: {\n extends: this.extends.length ? this.extends : undefined,\n globalDependencies:\n this.isRootProject && this.globalDependencies.length\n ? this.globalDependencies\n : undefined,\n globalEnv:\n this.isRootProject && this.globalEnv.length\n ? this.globalEnv\n : undefined,\n globalPassThroughEnv:\n this.isRootProject && this.globalPassThroughEnv.length\n ? this.globalPassThroughEnv\n : undefined,\n ui: this.isRootProject ? this.ui : undefined,\n dangerouslyDisablePackageManagerCheck: this.isRootProject\n ? this.dangerouslyDisablePackageManagerCheck\n : undefined,\n cacheDir: this.isRootProject ? this.cacheDir : undefined,\n daemon: this.isRootProject ? this.daemon : undefined,\n envMode: this.isRootProject ? this.envMode : undefined,\n /**\n * All tasks\n */\n tasks: this.tasks\n .filter((task) => task.isActive)\n .reduce(\n (acc, task) => {\n acc[task.name] = {\n ...task.taskConfig(),\n };\n return acc;\n },\n {\n [this.buildTask.name]: { ...this.buildTask.taskConfig() },\n } as Record<string, any>,\n ),\n },\n });\n\n super.preSynthesize();\n }\n}\n","// eslint-disable-next-line import/no-extraneous-dependencies\nimport {\n AWS_STAGE_TYPE,\n AwsEnvironmentType,\n AwsStageType,\n DEPLOYMENT_TARGET_ROLE,\n DeploymentTargetRoleType,\n} from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { AwsDeploymentConfig } from \"./aws-deployment-config\";\nimport { GitBranch } from \"../git\";\n\n/*******************************************************************************\n *\n * AWS Deployment Configuration\n *\n * A single deployment target that CDK applications can be deployed into.\n *\n ******************************************************************************/\n\n/**\n * Represents the configuration for local deployment in AWS.\n */\nexport interface AwsLocalDeploymentConfig {\n /**\n * The AWS profile (in ~/.aws/config) to use for local deployment.\n *\n * @default generated dynamically based role name, account and region\n */\n readonly profile?: string;\n\n /**\n * Named Role used to conduct local deployments.\n *\n * @default \"poweruseraccess\"\n */\n readonly roleName?: string;\n\n /**\n * The pattern used to identify stacks to deploy in CI deployments.\n *\n * @default *-${account}-${region}\n */\n readonly stackPattern?: string;\n}\n\nexport interface CiDeploymentConfig {\n /**\n * The OIDC IAM Role to assume for CI deployments.\n */\n readonly roleArn: string;\n\n /**\n * The pattern used to identify stacks to deploy in CI deployments.\n *\n * @default *-${account}-${region}\n */\n readonly stackPattern?: string;\n}\n\n/**\n * Represents a deployment target in AWS, including account and region, and\n * branches allowed to deploy to this target.\n */\nexport interface AwsDeploymentTargetOptions {\n /**\n * The account name for the deployment target.\n */\n readonly account: string;\n\n /**\n * The AWS region for the deployment target.\n */\n readonly region: string;\n\n /**\n * AWS deployment type, such as dev, stage, or prod.\n *\n * @default 'dev'\n */\n readonly awsStageType?: AwsStageType;\n\n /**\n * Deployment target role: whether this (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n *\n * @default 'primary'\n */\n readonly deploymentTargetRole?: DeploymentTargetRoleType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use `deploymentTargetRole` instead. This property is maintained for backward compatibility.\n * @default 'primary'\n */\n readonly awsEnvironmentType?: AwsEnvironmentType;\n\n /**\n * The AWS profile to use for this deployment target.\n *\n * @default ['main'] when prod release type, ['feature/*'] when dev type\n */\n readonly branches?: Array<GitBranch>;\n\n /**\n * Can this deployment target be used for local development?\n *\n * @default true for dev environments, false for prod environments\n */\n readonly localDeployment?: boolean;\n\n /**\n * Configuration when deploying to this target locally.\n */\n readonly localDeploymentConfig?: AwsLocalDeploymentConfig;\n\n /**\n * Can this deployment target be used in CI deployments?\n *\n * @default false\n */\n readonly ciDeployment?: boolean;\n\n /*\n * Configuration when deploying to this target in CI.\n\n */\n readonly ciDeploymentConfig?: CiDeploymentConfig;\n}\n\nexport class AwsDeploymentTarget extends Component {\n /**\n * Static method to discovert targets in a project.\n */\n public static of(\n project: AwsCdkTypeScriptApp,\n ): Array<AwsDeploymentTarget> | undefined {\n const isDefined = (c: Component): c is AwsDeploymentTarget =>\n c instanceof AwsDeploymentTarget;\n return project.components.filter(isDefined);\n }\n\n /**\n * The account name for the deployment target.\n */\n public account: string;\n\n /**\n * The AWS region for the deployment target.\n */\n public region: string;\n\n /**'\n * AWS stage type, such as dev, stage, or prod.\n *\n * @default 'dev'\n */\n public awsStageType: AwsStageType;\n\n /**\n * Deployment target role: whether this (account, region) is the primary or\n * secondary deployment target (e.g. primary vs replica region).\n *\n * @default 'primary'\n */\n public deploymentTargetRole: DeploymentTargetRoleType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use `deploymentTargetRole` instead. This property is maintained for backward compatibility.\n * @default 'primary'\n */\n public awsEnvironmentType: AwsEnvironmentType;\n\n /**\n * The AWS profile to use for this deployment target.\n *\n * @default ['main'] when prod release type, ['feature/*'] when dev type\n */\n public branches: Array<GitBranch> = [];\n\n /**\n * Can this deployment target be used for local development?\n *\n * @default true for dev environments, false for prod environments\n */\n public localDeployment?: boolean;\n\n /**\n * Configuration when deploying to this target locally.\n */\n public localDeploymentConfig?: AwsLocalDeploymentConfig;\n\n /**\n * Can this deployment target be used in CI deployments?\n *\n * @default false\n */\n public ciDeployment?: boolean;\n\n /*\n * Configuration when deploying to this target in CI.\n */\n public ciDeploymentConfig?: Required<CiDeploymentConfig>;\n\n /**\n * Configuration for the CDK output directory for this deployment target.\n */\n public awsDeploymentConfig: AwsDeploymentConfig;\n\n constructor(\n project: AwsCdkTypeScriptApp,\n options: AwsDeploymentTargetOptions,\n ) {\n super(project);\n\n /**\n * Set target region and account.\n */\n this.account = options.account;\n this.region = options.region;\n\n /**\n * Set default type\n */\n this.awsStageType = options.awsStageType || AWS_STAGE_TYPE.DEV;\n\n /**\n * Set deployment target role (preferred) or fall back to deprecated awsEnvironmentType.\n */\n const role =\n options.deploymentTargetRole ??\n options.awsEnvironmentType ??\n DEPLOYMENT_TARGET_ROLE.PRIMARY;\n this.deploymentTargetRole = role;\n this.awsEnvironmentType = role;\n\n /**\n * Set default Branches\n */\n\n this.branches =\n options.branches ??\n (this.awsStageType === AWS_STAGE_TYPE.PROD\n ? [\n {\n branch: \"main\",\n },\n ]\n : [\n {\n branch: \"feature/*\",\n },\n ]);\n\n /**\n * Set default for local deployment\n */\n this.localDeployment =\n options.localDeployment ?? this.awsStageType === AWS_STAGE_TYPE.DEV;\n\n /**\n * Some default configurations for local deployments.\n */\n if (this.localDeployment) {\n const roleName =\n options.localDeploymentConfig?.roleName?.toLowerCase() ||\n \"poweruseraccess\";\n const profile =\n options.localDeploymentConfig?.profile ||\n `${roleName}-${this.awsStageType}-${this.account}-${this.region}`;\n\n const stackPattern =\n options.localDeploymentConfig?.stackPattern ||\n `${this.awsStageType}/${this.awsEnvironmentType}/*-${this.account}-${this.region}`;\n\n this.localDeploymentConfig = {\n profile,\n roleName,\n stackPattern,\n ...options.localDeploymentConfig,\n };\n }\n\n /**\n * Set CI deployment default\n */\n this.ciDeployment = options.ciDeployment ?? false;\n\n /**\n * Some defaults for CI deployments.\n */\n if (this.ciDeployment) {\n const roleArn =\n options.ciDeploymentConfig?.roleArn ||\n `arn:aws:iam::${this.account}:role/GitHubDeployer}`;\n\n const stackPattern =\n options.ciDeploymentConfig?.stackPattern ||\n `${this.awsStageType}/${this.awsEnvironmentType}/*-${this.account}-${this.region}`;\n\n this.ciDeploymentConfig = {\n roleArn,\n stackPattern,\n ...options.ciDeploymentConfig,\n };\n }\n\n /**\n * Find or create CDK folder config for this project.\n */\n this.awsDeploymentConfig =\n AwsDeploymentConfig.of(project) || new AwsDeploymentConfig(project);\n\n /**\n * Add the target to the deployment targets array.\n */\n this.awsDeploymentConfig.awsDeploymentTargets.push(this);\n\n // Deploy tasks are configured per target.\n this.configureDeployTask();\n\n // Watch tasks are configured per target.\n this.configureWatchTask();\n }\n\n /*****************************************************************************\n *\n * Deploy Tasks\n *\n * - If local deploy, add a deploy task.\n *\n ****************************************************************************/\n\n private configureDeployTask = (): void => {\n if (this.localDeployment) {\n const taskName = [\n \"deploy\",\n this.awsStageType,\n this.account,\n this.region,\n ].join(\":\");\n const deployTask = this.project.tasks.addTask(taskName, {\n env: this.awsDeploymentConfig.env,\n });\n deployTask.exec(\n `cdk deploy --lookups=false --require-approval=never --profile=${this.localDeploymentConfig?.profile} --app=${this.awsDeploymentConfig.cdkOut} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n }\n };\n\n /*****************************************************************************\n *\n * Watch tasks\n *\n * - Configure watch task to use the branch name\n * - configure watch task to use the correct synth output location.\n *\n ****************************************************************************/\n\n private configureWatchTask = (): void => {\n if (this.localDeployment) {\n const taskName = [\n \"watch\",\n this.awsStageType,\n this.account,\n this.region,\n ].join(\":\");\n const watchTask = this.project.tasks.addTask(taskName, {\n env: this.awsDeploymentConfig.env,\n });\n\n // update the synth first\n const synthSilent = this.project.tasks.tryFind(\"synth:silent\");\n if (synthSilent) {\n watchTask.spawn(synthSilent);\n }\n\n // do a normal deploy\n watchTask.exec(\n `cdk deploy --lookups=false --require-approval=never --profile=${this.localDeploymentConfig?.profile} --app=${this.awsDeploymentConfig.cdkOut} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n\n // watch for changes and log output\n watchTask.exec(\n `cdk watch --lookups=false --require-approval=never --hotswap --profile=${this.localDeploymentConfig?.profile} \"${this.localDeploymentConfig?.stackPattern}\"`,\n );\n }\n };\n}\n","const NPM_REGISTRY = \"https://registry.npmjs.org\";\n\n/**\n * Metadata for a package from the npm registry. Only the fields we use are typed.\n *\n * @see https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md\n */\ninterface NpmPackageMetadata {\n name?: string;\n \"dist-tags\"?: { latest?: string };\n time?: Record<string, string>;\n versions?: Record<string, unknown>;\n}\n\n/**\n * Returns true if the version has a semver prerelease segment (e.g. -canary, -alpha, -beta).\n * Full releases like 1.2.3 or 1.2.3+build.1 return false.\n */\nfunction isPrerelease(version: string): boolean {\n const v = version.replace(/^v/, \"\");\n return /^\\d+\\.\\d+\\.\\d+-/.test(v);\n}\n\n/**\n * Compares two semver-like version strings (e.g. \"1.2.3\").\n * Returns negative if a < b, positive if a > b, 0 if equal.\n * Prerelease segments are treated as less than release.\n */\nfunction compareVersions(a: string, b: string): number {\n const parse = (v: string): number[] => {\n const parts = v.replace(/^v/, \"\").split(/[-+]/)[0].split(\".\");\n return parts.map((p) => {\n const n = parseInt(p, 10);\n return Number.isNaN(n) ? 0 : n;\n });\n };\n const pa = parse(a);\n const pb = parse(b);\n const len = Math.max(pa.length, pb.length);\n for (let i = 0; i < len; i++) {\n const na = pa[i] ?? 0;\n const nb = pb[i] ?? 0;\n if (na !== nb) return na - nb;\n }\n return 0;\n}\n\n/**\n * Returns the latest full-release version of an npm package that has been\n * published for at least `minimumReleaseAgeMinutes` minutes. Prefers the\n * version indicated by the registry's \"latest\" dist-tag when it is a full\n * release: if that version's publish time is in the registry and old enough,\n * it is used; if it is not in the registry's \"time\" object (e.g. truncated\n * for large packages), the dist-tag is still used so npm's \"latest\" is\n * followed. When the dist-tag version is too new (in time but not old enough),\n * we fall back to the highest full-release version that is old enough and\n * ≤ latest (e.g. latest 2.x that's old enough, not 3.0.0). Prerelease\n * versions are excluded. Returns null if `time` is missing or no version is\n * eligible.\n *\n * @param packageName - npm package name (e.g. \"projen\").\n * @param minimumReleaseAgeMinutes - minimum age in minutes (e.g. 1440 for 24h).\n * @returns The latest eligible version string, or null.\n */\nexport async function getLatestEligibleVersion(\n packageName: string,\n minimumReleaseAgeMinutes: number,\n): Promise<string | null> {\n const url = `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`;\n let res: Response;\n try {\n res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n } catch {\n return null;\n }\n if (!res.ok) return null;\n let data: NpmPackageMetadata;\n try {\n data = (await res.json()) as NpmPackageMetadata;\n } catch {\n return null;\n }\n const time = data.time;\n if (!time || typeof time !== \"object\") return null;\n\n const nowMs = Date.now();\n const minAgeMs = minimumReleaseAgeMinutes * 60 * 1000;\n\n const distTagLatest = data[\"dist-tags\"]?.latest;\n if (distTagLatest && !isPrerelease(distTagLatest)) {\n const publishedAtStr = time[distTagLatest];\n if (typeof publishedAtStr === \"string\") {\n const publishedAt = Date.parse(publishedAtStr);\n if (!Number.isNaN(publishedAt) && nowMs - publishedAt >= minAgeMs) {\n return distTagLatest;\n }\n } else {\n return distTagLatest;\n }\n }\n\n const versionTimestamps: { version: string; publishedAt: number }[] = [];\n for (const [key, value] of Object.entries(time)) {\n if (key === \"created\" || key === \"modified\" || typeof value !== \"string\") {\n continue;\n }\n if (isPrerelease(key)) continue;\n const publishedAt = Date.parse(value);\n if (Number.isNaN(publishedAt)) continue;\n const ageMs = nowMs - publishedAt;\n if (ageMs >= minAgeMs) {\n versionTimestamps.push({ version: key, publishedAt });\n }\n }\n\n if (versionTimestamps.length === 0) return null;\n\n let candidates = versionTimestamps;\n if (distTagLatest && !isPrerelease(distTagLatest)) {\n candidates = versionTimestamps.filter(\n (e) => compareVersions(e.version, distTagLatest) <= 0,\n );\n }\n if (candidates.length === 0) return null;\n\n candidates.sort((a, b) => compareVersions(b.version, a.version));\n return candidates[0].version;\n}\n","import { VERSION } from \"./versions\";\n\n/**\n * Keys of the VERSION object in versions.ts.\n */\nexport type VersionKey = keyof typeof VERSION;\n\n/**\n * Mapping of VERSION keys that are backed by an npm package and eligible\n * for auto-update. Only these keys should be updated by version-update\n * automation; others (e.g. NODE_WORKFLOWS) are skipped.\n *\n * @see {@link VERSION_KEYS_SKIP} for keys that must not be auto-updated.\n */\nexport const VERSION_NPM_PACKAGES: ReadonlyArray<{\n key: VersionKey;\n npmPackage: string;\n}> = [\n { key: \"AWS_CDK_CLI_VERSION\", npmPackage: \"aws-cdk\" },\n { key: \"AWS_CDK_LIB_VERSION\", npmPackage: \"aws-cdk-lib\" },\n { key: \"AWS_CONSTRUCTS_VERSION\", npmPackage: \"constructs\" },\n { key: \"PNPM_VERSION\", npmPackage: \"pnpm\" },\n { key: \"PROJEN_VERSION\", npmPackage: \"projen\" },\n { key: \"TURBO_VERSION\", npmPackage: \"turbo\" },\n] as const;\n\n/**\n * VERSION keys that are not backed by npm and must be skipped by\n * auto-update (e.g. runtime versions like Node.js).\n */\nexport const VERSION_KEYS_SKIP: ReadonlyArray<VersionKey> = [\"NODE_WORKFLOWS\"];\n","export const VERSION = {\n /**\n * CDK CLI for workflows and command line operations.\n *\n * CLI and lib are versioned separately, so this is the CLI version.\n */\n AWS_CDK_CLI_VERSION: \"2.1106.1\",\n\n /**\n * CDK Version to use for construct projects.\n *\n * CLI and lib are versioned separately, so this is the lib version.\n */\n AWS_CDK_LIB_VERSION: \"2.239.0\",\n\n /**\n * Version of the AWS Constructs library to use.\n */\n AWS_CONSTRUCTS_VERSION: \"10.5.1\",\n\n /**\n * Version of Node.js to use in CI workflows at github actions.\n */\n NODE_WORKFLOWS: \"24\",\n\n /**\n * Version of PNPM to use in workflows at github actions.\n */\n PNPM_VERSION: \"10.30.1\",\n\n /**\n * Version of Projen to use.\n */\n PROJEN_VERSION: \"0.99.15\",\n\n /**\n * What version of the turborepo library should we use?\n */\n TURBO_VERSION: \"2.8.10\",\n} as const;\n","import * as spec from \"@jsii/spec\";\nimport { Component, JsonFile } from \"projen\";\nimport { TypeScriptProject } from \"projen/lib/typescript\";\nimport { ValueOf } from \"type-fest\";\n\n/**\n * The FQNs for the base classes and options used by Jsii.\n *\n * These are the defaults used by Projen's TypeScriptProject.\n */\nconst ProjenBaseFqn = {\n TYPESCRIPT_PROJECT: \"projen.typescript.TypeScriptProject\",\n TYPESCRIPT_PROJECT_OPTIONS: \"projen.typescript.TypeScriptProjectOptions\",\n} as const;\n\nexport interface ClassTypeOptions {\n /**\n * The name of the class.\n *\n * @example \"MyProject\"\n */\n name: string;\n\n /**\n * The FQN for the base class this class is extending.\n *\n * @default ProjenBaseFqn.TYPESCRIPT_PROJECT\n */\n baseFqn?: ValueOf<typeof ProjenBaseFqn> | string;\n\n /**\n * The FQN for the options for this class.\n *\n * @default ProjenBaseFqn.TYPESCRIPT_PROJECT_OPTIONS\n */\n optionsFqn?: ValueOf<typeof ProjenBaseFqn> | string;\n}\n\nexport class JsiiFaker extends Component {\n // find project singleton\n public static of(project: TypeScriptProject): JsiiFaker | undefined {\n const isDefined = (c: Component): c is JsiiFaker => c instanceof JsiiFaker;\n return project.components.find(isDefined);\n }\n\n private _assemblyName: string;\n private _types: { [name: string]: spec.Type } = {};\n\n constructor(public readonly project: TypeScriptProject) {\n super(project);\n\n /**\n * In JSII, the assembly name is essentially the package name. It's used as a\n * scope when targeting types and metadata in other \"jsii assemblies\" that\n * might be in sub-packages used by the project.\n *\n * For this case, we'll just use the package name from Projen.\n */\n this._assemblyName = this.project.package.packageName;\n\n new JsonFile(project, \".jsii\", {\n obj: () => {\n return {\n name: this._assemblyName,\n types: this._types,\n };\n },\n });\n }\n\n public toJSON = () => {\n return {\n types: this._types,\n };\n };\n\n public addClassType(options: ClassTypeOptions) {\n const fqn = [this._assemblyName, options.name].join(\".\");\n const type: spec.ClassType = {\n assembly: this._assemblyName,\n base: options.baseFqn ?? ProjenBaseFqn.TYPESCRIPT_PROJECT,\n fqn,\n kind: spec.TypeKind.Class,\n name: options.name,\n initializer: {\n parameters: [\n {\n name: \"options\",\n type: {\n fqn:\n options.optionsFqn ?? ProjenBaseFqn.TYPESCRIPT_PROJECT_OPTIONS,\n },\n },\n ],\n },\n };\n\n this._types[fqn] = type;\n }\n}\n","import { relative } from \"path\";\nimport { Component, Project, YamlFile } from \"projen\";\nimport { ValueOf } from \"type-fest\";\n\n/**\n * Predefined minimum release age values in minutes.\n */\nexport const MIMIMUM_RELEASE_AGE = {\n ZERO_DAYS: 0,\n ONE_HOUR: 60,\n SIX_HOURS: 360,\n TWELVE_HOURS: 720,\n ONE_DAY: 1440,\n TWO_DAYS: 2880,\n THREE_DAYS: 4320,\n FOUR_DAYS: 5760,\n FIVE_DAYS: 7200,\n SIX_DAYS: 8640,\n ONE_WEEK: 10080,\n};\n\nexport interface PnpmWorkspaceOptions {\n /**\n * Filename for the pnpm workspace file. This should probably never change.\n *\n * @default \"pnpm-workspace.yaml\"\n */\n readonly fileName?: string;\n\n /**\n * To reduce the risk of installing compromised packages, you can delay the\n * installation of newly published versions. In most cases, malicious releases\n * are discovered and removed from the registry within an hour.\n *\n * minimumReleaseAge defines the minimum number of minutes that must pass\n * after a version is published before pnpm will install it. This applies to\n * all dependencies, including transitive ones.\n *\n * Note: this should match depsUpgradeOptions.cooldown in the project config.\n *\n * See: https://pnpm.io/settings#minimumreleaseage\n *\n * @default MIMIMUM_RELEASE_AGE.ONE_DAY\n */\n readonly minimumReleaseAge?: ValueOf<typeof MIMIMUM_RELEASE_AGE>;\n\n /**\n * If you set minimumReleaseAge but need certain dependencies to always\n * install the newest version immediately, you can list them under\n * minimumReleaseAgeExclude. The exclusion works by package name and applies\n * to all versions of that package.\n *\n * @default - no exclusions (empty array)\n *\n * See: https://pnpm.io/settings#minimumreleaseageexclude\n */\n readonly minimumReleaseAgeExclude?: Array<string>;\n\n /**\n * A list of package names that are allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation. Only the\n * packages listed in this array will be able to run those lifecycle scripts.\n * If onlyBuiltDependenciesFile and neverBuiltDependencies are omitted, this\n * configuration option will default to blocking all install scripts.\n *\n * You may restrict allowances to specific versions (and lists of versions\n * using a disjunction with ||). When versions are specified, only those\n * versions of the package may run lifecycle scripts:\n *\n * See: https://pnpm.io/settings#onlybuiltdependencies\n *\n * @default none (empty array)\n */\n readonly onlyBuiltDependencies?: Array<string>;\n\n /**\n * A list of package names that are NOT allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation and will not\n * warn or ask to be executed.\n *\n * This is useful when you want to hide the warning because you know the\n * lifecycle scripts are not needed.\n *\n * https://pnpm.io/settings#ignoredbuiltdependencies\n *\n * @default none (empty array)\n */\n readonly ignoredBuiltDependencies?: Array<string>;\n\n /**\n * Additional subproject paths to include in the workspace packages array.\n * These will be combined with any subprojects discovered via projen's\n * project.subprojects property. Paths should be relative to the project root.\n *\n * @default none (empty array)\n */\n readonly subprojects?: Array<string>;\n\n /**\n * Catalog of reusable dependency version ranges.\n *\n * The catalog allows you to define dependency versions as reusable constants\n * that can be referenced in package.json files using the catalog: protocol.\n *\n * Example:\n * ```yaml\n * catalog:\n * react: ^18.0.0\n * typescript: ^5.0.0\n * ```\n *\n * Then in package.json:\n * ```json\n * {\n * \"dependencies\": {\n * \"react\": \"catalog:react\"\n * }\n * }\n * ```\n *\n * @default undefined (not included in output)\n *\n * See: https://pnpm.io/pnpm-workspace_yaml#catalog\n */\n readonly defaultCatalog?: { [key: string]: string };\n\n /**\n * Named catalogs of reusable dependency version ranges.\n *\n * Multiple named catalogs with arbitrarily chosen names can be configured under the namedCatalogs key.\n *\n * Example:\n * ```yaml\n * namedCatalogs:\n * frontend:\n * react: ^18.0.0\n * typescript: ^5.0.0\n * backend:\n * express: ^4.18.0\n * ```\n *\n * Then in package.json:\n * ```json\n * {\n * \"dependencies\": {\n * \"react\": \"catalog:frontend/react\"\n * }\n * }\n * ```\n *\n * @default undefined (not included in output)\n *\n * See: https://pnpm.io/catalogs\n */\n readonly namedCatalogs?: {\n [catalogName: string]: { [dependencyName: string]: string };\n };\n}\n\nexport class PnpmWorkspace extends Component {\n /**\n * Get the pnpm workspace component of a project. If it does not exist,\n * return undefined.\n *\n * @param project\n * @returns\n */\n public static of(project: Project): PnpmWorkspace | undefined {\n const isDefined = (c: Component): c is PnpmWorkspace =>\n c instanceof PnpmWorkspace;\n return project.root.components.find(isDefined);\n }\n\n /**\n * Filename for the pnpm workspace file.\n */\n public readonly fileName: string;\n\n /**\n * To reduce the risk of installing compromised packages, you can delay the\n * installation of newly published versions. In most cases, malicious releases\n * are discovered and removed from the registry within an hour.\n *\n * minimumReleaseAge defines the minimum number of minutes that must pass\n * after a version is published before pnpm will install it. This applies to\n * all dependencies, including transitive ones.\n *\n * Note: this should match depsUpgradeOptions.cooldown in the project config.\n *\n * See: https://pnpm.io/settings#minimumreleaseage\n */\n public minimumReleaseAge: ValueOf<typeof MIMIMUM_RELEASE_AGE>;\n\n /**\n * If you set minimumReleaseAge but need certain dependencies to always\n * install the newest version immediately, you can list them under\n * minimumReleaseAgeExclude. The exclusion works by package name and applies\n * to all versions of that package.\n *\n * See: https://pnpm.io/settings#minimumreleaseageexclude\n */\n public minimumReleaseAgeExclude: Array<string>;\n\n /**\n * A list of package names that are allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation. Only the\n * packages listed in this array will be able to run those lifecycle scripts.\n * If onlyBuiltDependenciesFile and neverBuiltDependencies are omitted, this\n * configuration option will default to blocking all install scripts.\n *\n * You may restrict allowances to specific versions (and lists of versions\n * using a disjunction with ||). When versions are specified, only those\n * versions of the package may run lifecycle scripts:\n *\n * See: https://pnpm.io/settings#onlybuiltdependencies\n */\n public onlyBuiltDependencies: Array<string>;\n\n /**\n * A list of package names that are NOT allowed to execute \"preinstall\",\n * \"install\", and/or \"postinstall\" scripts during installation and will not\n * warn or ask to be executed.\n *\n * This is useful when you want to hide the warning because you know the\n * lifecycle scripts are not needed.\n *\n * https://pnpm.io/settings#ignoredbuiltdependencies\n */\n public ignoredBuiltDependencies: Array<string>;\n\n /**\n * Additional subproject paths to include in the workspace packages array.\n * These will be combined with any subprojects discovered via projen's\n * project.subprojects property.\n */\n public subprojects: Array<string>;\n\n /**\n * Default catalog of reusable dependency version ranges.\n *\n * The default catalog is used to define dependency versions as reusable constants\n * that can be referenced in package.json files using the catalog: protocol.\n *\n * See:https://pnpm.io/catalogs\n */\n public defaultCatalog?: { [key: string]: string };\n\n /**\n * Named catalogs of reusable dependency version ranges.\n *\n * Multiple named catalogs with arbitrarily chosen names can be configured under the namedCatalogs key.\n *\n * See: https://pnpm.io/catalogs\n */\n public namedCatalogs?: {\n [catalogName: string]: { [dependencyName: string]: string };\n };\n\n constructor(project: Project, options: PnpmWorkspaceOptions = {}) {\n super(project);\n\n /***************************************************************************\n *\n * CLEAR package,json\n *\n * It appears that if ANY pnpm settings exist in the package.json file, all\n * of the setting in the pnpm-workspace.yaml file are ignored. so we need to\n * clear out anything that was placed into the package.json file.\n *\n **************************************************************************/\n\n project.tryFindObjectFile(\"package.json\")?.addDeletionOverride(\"pnpm\");\n\n /***************************************************************************\n * \n * Setup pnpm-workspace.yaml file.\n * \n * Now that the package.json file is cleared of any pnpm settings, we can\n * safely write settings to the pnpm-workspace.yaml file.\n * \n **************************************************************************\n\n /**\n * Set filename to default if not provided.\n */\n this.fileName = options.fileName ?? \"pnpm-workspace.yaml\";\n\n /**\n * Set minimum release age; default ONE_DAY when not provided.\n */\n this.minimumReleaseAge =\n options.minimumReleaseAge ?? MIMIMUM_RELEASE_AGE.ONE_DAY;\n\n /**\n * Set minimum release age exclude to empty array if not provided\n */\n this.minimumReleaseAgeExclude = options.minimumReleaseAgeExclude\n ? [\"@codedrifters/*\", ...options.minimumReleaseAgeExclude]\n : [\"@codedrifters/*\"];\n\n /**\n * Set only built dependencies to empty array if not provided\n */\n this.onlyBuiltDependencies = options.onlyBuiltDependencies\n ? options.onlyBuiltDependencies\n : [];\n\n /**\n * Set ignored built dependencies to empty array if not provided\n */\n this.ignoredBuiltDependencies = options.ignoredBuiltDependencies\n ? options.ignoredBuiltDependencies\n : [];\n\n /**\n * Store additional subproject paths if provided\n */\n this.subprojects = options.subprojects ?? [];\n\n /**\n * Store catalog if provided\n */\n this.defaultCatalog = options.defaultCatalog;\n\n /**\n * Store named catalogs if provided\n */\n this.namedCatalogs = options.namedCatalogs;\n\n /**\n * In case that this file is in a package, don't package it.\n */\n project.addPackageIgnore(this.fileName);\n\n /**\n * Write pnpm workspace file\n */\n new YamlFile(this.project, this.fileName, {\n obj: () => {\n const pnpmConfig: any = {};\n const packages = new Array<string>();\n\n /**\n * Add projen subprojects to the packages array.\n */\n for (const subproject of project.subprojects) {\n // grab the relative out directory\n packages.push(relative(this.project.outdir, subproject.outdir));\n }\n\n /**\n * Add additional subproject paths provided via options.\n * Use a Set to deduplicate paths to avoid including the same\n * subproject multiple times.\n */\n const packageSet = new Set(packages);\n for (const subprojectPath of this.subprojects) {\n packageSet.add(subprojectPath);\n }\n\n /**\n * Convert back to array if we added any additional paths\n */\n if (this.subprojects.length > 0) {\n packages.length = 0;\n packages.push(...packageSet);\n }\n\n /**\n * Set minimum release age.\n */\n pnpmConfig.minimumReleaseAge = this.minimumReleaseAge;\n\n /**\n * Set minimum release age exclude if any are provided.\n */\n if (this.minimumReleaseAgeExclude.length > 0) {\n pnpmConfig.minimumReleaseAgeExclude = this.minimumReleaseAgeExclude;\n }\n\n /**\n * Set only built dependencies if any are provided.\n */\n if (this.onlyBuiltDependencies.length > 0) {\n pnpmConfig.onlyBuiltDependencies = this.onlyBuiltDependencies;\n }\n\n /**\n * Set ignored built dependencies if any are provided.\n */\n if (this.ignoredBuiltDependencies.length > 0) {\n pnpmConfig.ignoreBuiltDependencies = this.ignoredBuiltDependencies;\n }\n\n /**\n * Set default catalog if provided.\n */\n if (\n this.defaultCatalog &&\n Object.keys(this.defaultCatalog).length > 0\n ) {\n pnpmConfig.catalog = this.defaultCatalog;\n }\n\n /**\n * Set named catalogs if provided.\n */\n if (this.namedCatalogs && Object.keys(this.namedCatalogs).length > 0) {\n pnpmConfig.namedCatalogs = this.namedCatalogs;\n }\n\n /**\n * Return the final pnpm config object.\n */\n return {\n ...(packages.length > 0 ? { packages } : {}),\n ...(pnpmConfig ? { ...pnpmConfig } : {}),\n };\n },\n });\n }\n}\n","import { BuildWorkflowOptions } from \"projen/lib/build\";\nimport {\n NodePackageManager,\n UpgradeDependencies,\n UpgradeDependenciesOptions,\n UpgradeDependenciesSchedule,\n} from \"projen/lib/javascript\";\nimport {\n TypeScriptAppProject,\n TypeScriptProjectOptions,\n} from \"projen/lib/typescript\";\nimport { merge } from \"ts-deepmerge\";\nimport { PnpmWorkspace, PnpmWorkspaceOptions } from \"../pnpm/pnpm-workspace\";\nimport { ResetTask, ResetTaskOptions } from \"../tasks/reset-task\";\nimport {\n ROOT_CI_TASK_NAME,\n TurboRepo,\n TurboRepoOptions,\n} from \"../turbo/turbo-repo\";\nimport { VERSION } from \"../versions\";\nimport { VSCodeConfig } from \"../vscode/vscode\";\n\n/*******************************************************************************\n *\n * Monorepo Root Project\n *\n * This project should be used as the base project for other projects in a\n * monorepo. The Monorepo root project generally won't contain any code, but it\n * will contain configuration for the monorepo, such as package management,\n * linting, testing, and other project-wide settings.\n *\n ******************************************************************************/\n\nexport interface IDependencyResolver {\n resolveDepsAndWritePackageJson(): boolean;\n}\n\n/**\n * Configuration options for the monorepo.\n */\nexport interface MonorepoProjectOptions extends Omit<\n TypeScriptProjectOptions,\n \"defaultReleaseBranch\"\n> {\n /**\n * Turn on Turborepo support.\n *\n * @default true\n */\n turbo?: boolean;\n\n /**\n * Optionsal options for turborepo config\n */\n turboOptions?: TurboRepoOptions;\n\n /**\n * Enable the reset task that deletes all build artifacts.\n *\n * @default true\n */\n resetTask?: boolean;\n\n /**\n * Options for the reset task.\n */\n resetTaskOptions?: ResetTaskOptions;\n\n /**\n * PNPM options for the monorepo.\n */\n pnpmOptions?: {\n /**\n * The version of PNPM to use in the monorepo.\n * @default VERSION.PNPM_VERSION\n * @see {@link src/versions.ts}\n */\n version?: string;\n\n /**\n * Optional pnpm options for the monorepo workspace file.\n */\n pnpmWorkspaceOptions?: PnpmWorkspaceOptions;\n };\n\n /**\n * Turn on a dedicated workflow that upgrades only\n * @codedrifters/configulator on a schedule (e.g. nightly). When false or\n * unset, rely on projen's default upgrade workflow for all dependency\n * upgrades instead.\n *\n * @default false\n */\n readonly upgradeConfigulatorTask?: boolean;\n\n /**\n * Options for the upgrade configurator task.\n *\n * @default: daily schedule\n */\n readonly upgradeConfigulatorTaskOptions?: UpgradeDependenciesOptions;\n}\n\ninterface AppliedOptions\n extends TypeScriptProjectOptions, MonorepoProjectOptions {}\n\nexport class MonorepoProject extends TypeScriptAppProject {\n /**\n * Version of PNPM which the whole monorepo should use.\n */\n readonly pnpmVersion: string;\n\n /**\n * Optional task that will attempt to upgrade the @codedrifters/configulator\n * package version nightly. This keeps the project up-to-date with the latest\n * official CodeDrifters configs.\n */\n readonly upgradeConfigulatorTask?: UpgradeDependencies;\n\n /**\n * List of functions to call after dependencies have been installed.\n */\n private postInstallDependencies = new Array<() => boolean>();\n\n constructor(userOptions: MonorepoProjectOptions) {\n /***************************************************************************\n *\n * BUILD WORKFLOW OPTIONS\n *\n * discover some turbo options for build workflow, if needed.\n *\n **************************************************************************/\n\n const buildWorkflowOptions: Partial<BuildWorkflowOptions> = userOptions\n .turboOptions?.remoteCacheOptions\n ? TurboRepo.buildWorkflowOptions(\n userOptions.turboOptions.remoteCacheOptions,\n )\n : {};\n\n /***************************************************************************\n *\n * DEFAULT OPTIONS\n *\n * These are the default options unless you override with option inputs.\n *\n **************************************************************************/\n\n const defaultOptions: Omit<\n MonorepoProjectOptions,\n \"name\" | \"defaultReleaseBranch\"\n > = {\n /**\n * Use typescript based config file.\n */\n projenrcTs: true,\n\n /**\n * Projen version should be pinned to the local specified version.\n */\n projenVersion: \"catalog:\",\n\n /**\n * Use Prettier for code formatting.\n */\n prettier: true,\n\n /**\n * Not licensed by default.\n */\n licensed: false,\n\n /**\n * GitHub options for the monorepo.\n * Don't enable mergify by default.\n */\n githubOptions: {\n mergify: false,\n\n /**\n * Configure pull request linting to validate PR titles follow Conventional Commits.\n * By default, all conventional commit types are allowed, providing flexibility\n * for different types of changes (features, fixes, documentation, refactoring, etc.).\n */\n pullRequestLintOptions: {\n semanticTitleOptions: {\n /**\n * Allowed conventional commit types for PR titles.\n * This includes all standard types from the Conventional Commits specification:\n * - feat: New features\n * - fix: Bug fixes\n * - docs: Documentation changes\n * - style: Code style changes (formatting, etc.)\n * - refactor: Code refactoring\n * - perf: Performance improvements\n * - test: Test additions or changes\n * - build: Build system changes\n * - ci: CI configuration changes\n * - chore: Maintenance tasks\n * - revert: Revert commits\n */\n types: [\n \"feat\",\n \"fix\",\n \"docs\",\n \"style\",\n \"refactor\",\n \"perf\",\n \"test\",\n \"build\",\n \"ci\",\n \"chore\",\n \"revert\",\n ],\n },\n },\n },\n\n /**\n * Default PNPM version to use in the monorepo.\n */\n pnpmVersion: VERSION.PNPM_VERSION,\n\n /**\n * We don't want sample code generated for the root project.\n */\n sampleCode: false,\n\n /**\n * Jest is not required in the root project.\n */\n jest: false,\n\n /**\n * Don't release the root project.\n */\n release: false,\n\n /**\n * Uppgrade dependencies automatically unless otherwise instructed.\n */\n depsUpgrade: true,\n depsUpgradeOptions: {\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.expressions([\"0 23 * * *\"]),\n },\n cooldown: 1,\n },\n\n /**\n * Disable tsconfig.dev.json in the root since we aren't going to be\n * developing any code here. It's just a task runner and configuration\n * tool for sub-projects.\n */\n disableTsconfigDev: true,\n\n /**\n * Kill the srcdir in the root since we aren't using one.\n */\n tsconfig: {\n compilerOptions: {\n rootDir: undefined,\n },\n exclude: [\"node_modules\"],\n },\n\n /**\n * Enable turborepo by default.\n */\n turbo: true,\n\n /**\n * Enable reset task by default.\n */\n resetTask: true,\n\n /**\n * Include self as a devDep\n */\n devDeps: [\"@codedrifters/configulator\"],\n\n /**\n * PNPM options for the monorepo.\n */\n pnpmOptions: {\n pnpmWorkspaceOptions: {\n defaultCatalog: {\n [\"aws-cdk\"]: VERSION.AWS_CDK_CLI_VERSION,\n [\"aws-cdk-lib\"]: VERSION.AWS_CDK_LIB_VERSION,\n [\"projen\"]: VERSION.PROJEN_VERSION,\n [\"constructs\"]: VERSION.AWS_CONSTRUCTS_VERSION,\n [\"turbo\"]: VERSION.TURBO_VERSION,\n },\n },\n },\n };\n\n /***************************************************************************\n *\n * REQUIRED OPTIONS\n *\n * These options cannot be changed by the user.\n *\n **************************************************************************/\n\n const requiredOptions: Omit<TypeScriptProjectOptions, \"name\"> = {\n /**\n * This is required because it's standard practice and also to simplify\n * some workflow design.\n */\n defaultReleaseBranch: \"main\",\n\n /**\n * Use PNPM instead of the default (Yarn). Much of the ecosystem depends\n * on PNPM and making monorepos PNPM only simplifies many configurations.\n */\n packageManager: NodePackageManager.PNPM,\n\n /**\n * Some additional pre-build steps if we're using turbo's remote cache.\n * Set BRANCH_NAME so Turborepo remote cache hashes match between local and CI.\n */\n buildWorkflowOptions: {\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n ...buildWorkflowOptions?.env,\n ...userOptions.buildWorkflowOptions?.env,\n },\n permissions: {\n ...buildWorkflowOptions?.permissions,\n ...userOptions.buildWorkflowOptions?.permissions,\n },\n preBuildSteps: [\n ...(buildWorkflowOptions?.preBuildSteps ?? []),\n ...(userOptions.buildWorkflowOptions?.preBuildSteps ?? []),\n ],\n },\n };\n\n /***************************************************************************\n *\n * CONSTRUCTOR\n *\n * Combines default options with user provided options and required options.\n * Store the options in a const so we can use them after super(), farther\n * into the constructor for additional configuration.\n *\n **************************************************************************/\n\n const options: AppliedOptions = merge(\n defaultOptions,\n userOptions,\n requiredOptions,\n );\n\n super({ ...options });\n\n /***************************************************************************\n *\n * PUBLIC PROPS\n *\n * Some props are hidden by Projen and we need to expose them for the\n * monorepo to work properly. This is where we store them.\n *\n **************************************************************************/\n\n this.pnpmVersion = options.pnpmVersion!;\n\n /***************************************************************************\n *\n * CUSTOM CONFIGS\n *\n * We add some additional configurations to the monorepo root project below\n * such as Turborepo, VS Code config, and the PNPM workspace file.\n *\n **************************************************************************/\n\n /**\n * Add VSCode configuration\n */\n new VSCodeConfig(this);\n\n /**\n * Add workspace definition to PNPM root\n */\n new PnpmWorkspace(this, options.pnpmOptions?.pnpmWorkspaceOptions);\n\n /**\n * Turn on turborepo support if requested.\n */\n if (options.turbo) {\n new TurboRepo(this, options.turboOptions);\n\n this.buildWorkflow?.addPostBuildSteps({\n name: \"Build Sub Projects\",\n run: `npx projen ${ROOT_CI_TASK_NAME}`,\n });\n }\n\n /**\n * Add reset task if enabled.\n */\n if (options.resetTask !== false) {\n const defaultResetTaskOptions: ResetTaskOptions = {\n pathsToRemove: [\"node_modules\", \".turbo\", \"dist\", \"lib\"],\n };\n const userResetTaskOptions = options.resetTaskOptions ?? {};\n const resetTaskOptions: ResetTaskOptions = merge(\n defaultResetTaskOptions,\n {\n ...userResetTaskOptions,\n pathsToRemove: [\n ...(defaultResetTaskOptions.pathsToRemove ?? []),\n ...(userResetTaskOptions.pathsToRemove ?? []),\n ],\n },\n );\n new ResetTask(this, resetTaskOptions);\n }\n\n /**\n * Specify package manager\n */\n // const pnpmVersion = options.pnpmVersion ?? VERSION.PNPM_VERSION;\n this.package.file.addOverride(\n \"packageManager\",\n `pnpm@${options.pnpmVersion}`,\n );\n\n /**\n * Add some silly things to the gitignore.\n */\n this.gitignore?.addPatterns(\".DS_Store\");\n\n /**\n * Use catalog version for constructs version\n */\n this.addDevDeps(\"constructs@catalog:\");\n\n /**\n * Add a task on the monorepo's root project that will attempt to upgrade\n * the @codedrifters/configulator package version on a schedule when\n * explicitly enabled. Off by default; use projen's upgrade workflow instead.\n */\n if (options.upgradeConfigulatorTask === true) {\n this.upgradeConfigulatorTask = new UpgradeDependencies(\n this,\n merge(\n {\n include: [\"@codedrifters/configulator\"],\n taskName: `upgrade-codedrifters-configulator`,\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.DAILY,\n },\n },\n options.upgradeConfigulatorTaskOptions ?? {},\n ),\n );\n }\n\n /**\n * Update all packages after the root of the monorepo's updated.\n * Run the default task after the upgrade to ensure all packages are\n * updated. In particular make sure the pnpm-workspace file was not\n * tampered with during the upgrade.\n */\n this.tasks.tryFind(\"post-upgrade\")?.exec(\"pnpm upgrade -r\");\n this.tasks.tryFind(\"post-upgrade\")?.spawn(this.defaultTask!);\n }\n\n /**\n * Allows a sub project to request installation of dependency at the Monorepo root\n * They must provide a function that is executed after dependencies have been installed\n * If this function returns true, the install command is run for a second time after all sub project requests have run.\n * This is used to resolve dependency versions from `*` to a concrete version constraint.\n */\n public requestInstallDependencies(resolver: IDependencyResolver) {\n this.postInstallDependencies.push(resolver.resolveDepsAndWritePackageJson);\n }\n\n /**\n * Hooks into the install dependencies cycle\n */\n public postSynthesize() {\n if (this.postInstallDependencies.length) {\n const nodePkg: any = this.package;\n nodePkg.installDependencies();\n\n const completedRequests = this.postInstallDependencies.map((request) =>\n request(),\n );\n if (completedRequests.some(Boolean)) {\n nodePkg.installDependencies();\n }\n\n this.postInstallDependencies = [];\n }\n }\n}\n","import { Component, Project } from \"projen\";\nimport { TypeScriptProject } from \"../projects/typescript-project\";\nimport { TurboRepo } from \"../turbo/turbo-repo\";\nimport { TurboRepoTask } from \"../turbo/turbo-repo-task\";\n\n/*******************************************************************************\n *\n * Reset Task Component\n *\n * Adds a \"reset\" task that deletes all build artifacts produced by the build\n * process. This includes node_modules, lib, dist, coverage, test-reports,\n * .turbo, and tsconfig.tsbuildinfo.\n *\n ******************************************************************************/\n\nexport interface ResetTaskOptions {\n /**\n * Custom output directory to delete (overrides tsconfig artifactsDirectory detection).\n *\n * @default - detected from typescript project.artifactsDirectory or \"lib\"\n */\n readonly artifactsDirectory?: string;\n\n /**\n * Array of glob patterns for paths to remove.\n * If empty, the artifactsDirectory will be added automatically.\n *\n * @default []\n */\n readonly pathsToRemove?: string[];\n\n /**\n * Name of the task to create.\n *\n * @default \"reset\"\n */\n readonly taskName?: string;\n}\n\nexport class ResetTask extends Component {\n /**\n * Static method to discover reset task in a project.\n */\n public static of(project: Project): ResetTask | undefined {\n const isDefined = (c: Component): c is ResetTask => c instanceof ResetTask;\n return project.components.find(isDefined);\n }\n\n /**\n * The output directory to delete (from tsconfig or custom).\n */\n public readonly artifactsDirectory: string;\n\n /**\n * The final array of paths that will be removed by the reset task.\n */\n public readonly pathsToRemove: string[];\n\n /**\n * The name of the task that was created.\n */\n public readonly taskName: string;\n\n constructor(\n public readonly project: Project,\n options: ResetTaskOptions = {},\n ) {\n super(project);\n\n /**\n * Determine the output directory.\n * 1. Use custom artifactsDirectory if provided\n * 2. Use the artifacts directory if project is TypeScriptProject\n * 3. Default to \"lib\"\n */\n this.artifactsDirectory = options.artifactsDirectory\n ? options.artifactsDirectory\n : project instanceof TypeScriptProject\n ? project.artifactsDirectory\n : \"lib\";\n\n /**\n * Build the paths array to remove.\n * If pathsToRemove is empty, add artifactsDirectory.\n * If pathsToRemove is not empty, use it as-is (artifactsDirectory is not automatically added).\n * Remove duplicate entries from the array.\n */\n const pathsToRemove = options.pathsToRemove ?? [];\n const finalPaths =\n pathsToRemove.length === 0 ? [this.artifactsDirectory] : pathsToRemove;\n\n /**\n * Remove duplicate paths from the array.\n */\n this.pathsToRemove = Array.from(new Set(finalPaths));\n\n /**\n * Determine the task name.\n */\n this.taskName = options.taskName ?? \"reset\";\n\n /**\n * Create the reset task.\n */\n const resetTask = this.project.tasks.addTask(this.taskName, {\n description:\n \"Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty\",\n });\n\n /**\n * Delete build artifacts with existence checks.\n * Using shell conditionals to only delete if paths exist.\n * Using -e to check existence (works for both files and directories).\n */\n this.pathsToRemove.forEach((path) => {\n resetTask.exec(`[ -e \"${path}\" ] && rm -rf ${path} || true`);\n });\n\n /**\n * Turbo tasks are added after all components are created.\n * This assumes turbo is built first so that it's available to be\n * referenced. This could introduce problems in future but works for now.\n */\n\n /**\n * Check if turborepo is active.\n */\n const rootHasTurbo = TurboRepo.of(this.project.root) !== undefined;\n const isSubproject = this.project !== this.project.root;\n const isRootProject = this.project === this.project.root;\n\n /**\n * If turborepo is active for the subproject, add turbo tasks.\n */\n if (isSubproject && rootHasTurbo) {\n /**\n * Get TurboRepo instance for this subproject.\n * It should exist by now since preSynthesize runs after all components are created.\n */\n const turbo = TurboRepo.of(this.project);\n if (turbo && !turbo.isRootProject) {\n /**\n * Create turbo:reset task (or turbo:${taskName}).\n */\n const turboResetTask = new TurboRepoTask(this.project, {\n name: `turbo:${this.taskName}`,\n cache: false,\n });\n turbo.tasks.push(turboResetTask);\n\n /**\n * Create a turbo task with the same name as the reset task.\n */\n const turboTaskWithSameName = new TurboRepoTask(this.project, {\n name: this.taskName,\n cache: false,\n });\n turbo.tasks.push(turboTaskWithSameName);\n\n /**\n * turboResetTask depends on turboTaskWithSameName so that the reset task\n * can be run across all suprojects using turbo:reset as the entry point.\n */\n turboResetTask.dependsOn.push(turboTaskWithSameName.name);\n }\n }\n\n /**\n * If reset-task is in the root project, add a turbo task that will trigger\n * all the subtasks using dependsOn of \"^turbo:reset\".\n */\n if (isRootProject && rootHasTurbo) {\n const turbo = TurboRepo.of(this.project);\n if (turbo && turbo.isRootProject) {\n /**\n * Create turbo:reset task (or turbo:${taskName}) in the root project.\n * The ^ prefix means \"run this task in all dependencies first\".\n */\n const rootTurboResetTask = new TurboRepoTask(this.project, {\n name: `turbo:${this.taskName}`,\n dependsOn: [`^turbo:${this.taskName}`],\n cache: false,\n });\n turbo.tasks.push(rootTurboResetTask);\n\n /**\n * Create a turbo task with the same name as the reset task.\n */\n const turboTaskWithSameName = new TurboRepoTask(this.project, {\n name: this.taskName,\n cache: false,\n });\n turbo.tasks.push(turboTaskWithSameName);\n\n /**\n * rootTurboResetTask depends on turboTaskWithSameName so that the reset task\n * can be run across all suprojects using turbo:reset as the entry point.\n */\n rootTurboResetTask.dependsOn.push(turboTaskWithSameName.name);\n\n /**\n * Create reset:all task - a projen task that calls the turbo task.\n * This is similar to build:all in turbo-repo.ts.\n */\n const resetAllTask = this.project.tasks.addTask(\n `${this.taskName}:all`,\n {\n description: `Reset all build artifacts across the monorepo by running turbo:${this.taskName} in all subprojects.`,\n },\n );\n resetAllTask.exec(\"turbo telemetry disable\");\n resetAllTask.exec(\n `turbo turbo:${this.taskName} --summarize --concurrency=10`,\n );\n resetAllTask.exec(`pnpm ${this.taskName}`);\n }\n }\n }\n}\n","import { typescript } from \"projen\";\nimport {\n NodePackageManager,\n Transform,\n UpgradeDependenciesSchedule,\n} from \"projen/lib/javascript\";\nimport { ReleaseTrigger } from \"projen/lib/release\";\nimport { merge } from \"ts-deepmerge\";\nimport { MonorepoProject } from \"./monorepo-project\";\nimport { PnpmWorkspace } from \"../pnpm\";\nimport { ResetTask, ResetTaskOptions } from \"../tasks/reset-task\";\nimport { TurboRepo } from \"../turbo\";\nimport { VERSION } from \"../versions\";\n\n/**\n * Configuration options for TypeScriptProject.\n */\nexport interface TypeScriptProjectOptions extends Omit<\n typescript.TypeScriptProjectOptions,\n \"defaultReleaseBranch\"\n> {\n /**\n * Enable the reset task that deletes all build artifacts.\n *\n * @default true\n */\n readonly resetTask?: boolean;\n\n /**\n * Options for the reset task.\n */\n readonly resetTaskOptions?: ResetTaskOptions;\n}\n\nexport class TypeScriptProject extends typescript.TypeScriptProject {\n constructor(userOptions: TypeScriptProjectOptions) {\n /**\n * Default PNPM version to use. This will either come from the MonoRepo\n * root or from the default specified in configulator. If the user passes\n * in a different pnpmVersion it will also override this.\n */\n const pnpmVersion =\n userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? userOptions.parent.pnpmVersion\n : VERSION.PNPM_VERSION;\n\n /**\n * Get the pnpm workspace from the parent project.\n */\n const pnpmWorkspace =\n userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? PnpmWorkspace.of(userOptions.parent as MonorepoProject)\n : undefined;\n\n /*************************************************************************\n *\n * Default Options\n *\n ************************************************************************/\n\n const defaultOptions: Omit<TypeScriptProjectOptions, \"name\"> & {\n defaultReleaseBranch: string;\n } = {\n /**\n * This is a standard, so don't require it to passed in everywhere.\n */\n defaultReleaseBranch: \"main\",\n\n /**\n * Enable reset task by default.\n */\n resetTask: true,\n\n /**\n * Packaging options\n */\n packageManager: NodePackageManager.PNPM,\n pnpmVersion: pnpmVersion,\n licensed: userOptions.license !== undefined || false,\n copyrightOwner: \"CodeDrifters\",\n release: false,\n\n /**\n * Don't add sample code.\n */\n sampleCode: false,\n\n /**\n * Make sure jest config is stored outside of package.json\n */\n jestOptions: {\n configFilePath: \"jest.config.json\",\n jestConfig: {\n roots: [`<rootDir>/src`],\n transform: {\n [\"^.+\\\\.[t]sx?$\"]: new Transform(\"@swc/jest\"),\n },\n moduleFileExtensions: [\"js\", \"ts\"],\n },\n },\n\n /**\n * Turn on prettier formatting\n */\n prettier: true,\n\n /**\n * SWC for faster testing\n */\n devDeps: [\"@swc/jest\", \"@swc/core\"],\n\n /**\n * Don't package test files.\n */\n npmIgnoreOptions: {\n ignorePatterns: [\"*.spec.*\", \"*.test.*\"],\n },\n\n /**\n * Options for the automated dependency upgrade task / workflow\n * Automatically exclude any packages that are managed by the root\n * project as default catalog dependencies since we want to let the\n * catalog manage those dependencies.\n */\n depsUpgrade: true,\n depsUpgradeOptions: {\n workflow: false,\n exclude: Object.keys(pnpmWorkspace?.defaultCatalog || {}),\n ...(userOptions.parent && userOptions.parent instanceof MonorepoProject\n ? {\n workflowOptions: {\n schedule: UpgradeDependenciesSchedule.WEEKLY,\n },\n cooldown: 1,\n }\n : {}),\n },\n\n /**\n * Only release when the package folder source content or package.json\n * (version, dependencies) changes.\n */\n releaseTrigger: ReleaseTrigger.continuous({\n paths: [\n `${userOptions.outdir}/src/**`,\n `${userOptions.outdir}/package.json`,\n ],\n }),\n };\n\n /*************************************************************************\n *\n * Merge defaults into user options\n *\n ************************************************************************/\n\n const options: TypeScriptProjectOptions &\n typescript.TypeScriptProjectOptions = merge(defaultOptions, userOptions);\n\n super(options);\n\n /**\n * Remove jest since we've swapped in @swc/jest instead of ts-jest.\n */\n this.deps.removeDependency(\"ts-jest\");\n\n /**\n * Specify package manager\n */\n this.package.file.addOverride(\n \"packageManager\",\n `pnpm@${options.pnpmVersion}`,\n );\n\n /**\n *\n * Disable this rule for all test files.\n *\n * Unless we turn this off, ESLint will suggest that anything found in a test\n * needs to be a dep instead of a devDep. Projen actually already turns off\n * the rule for files in the tests/* folder but since we commonly put tests\n * next to the code it's testing, we need to do this ourselves.\n *\n */\n this.eslint?.addOverride({\n files: [\"**/*.test.*\", \"**/*.spec.*\"],\n rules: {\n \"import/no-extraneous-dependencies\": \"off\",\n },\n });\n\n /**\n * Some standard ignores for all projects.\n */\n this.gitignore?.addPatterns(\".DS_Store\");\n this.npmignore?.addPatterns(\"*.spec.*\", \"*.test.*\", \"__fixtures__\");\n\n /**\n * If turbo is active in the parent project, configure it here.\n */\n const turboActive =\n userOptions.parent && TurboRepo.of(userOptions.parent) !== undefined;\n if (turboActive) {\n const turbo = new TurboRepo(this);\n turbo.compileTask?.outputs.push(\"dist/**\");\n turbo.compileTask?.outputs.push(\"lib/**\");\n //turbo.testTask?.inputs.push(\"src/**\");\n }\n\n /**\n * Add reset task if enabled.\n */\n if (options.resetTask !== false) {\n const defaultResetTaskOptions: ResetTaskOptions = {\n pathsToRemove: [\n \"node_modules\",\n \"dist\",\n \"lib\",\n \"coverage\",\n \"test-reports\",\n \".turbo\",\n \"tsconfig.tsbuildinfo\",\n this.artifactsDirectory,\n ],\n };\n const userResetTaskOptions = options.resetTaskOptions ?? {};\n const resetTaskOptions: ResetTaskOptions = merge(\n defaultResetTaskOptions,\n {\n ...userResetTaskOptions,\n pathsToRemove: [\n ...(defaultResetTaskOptions.pathsToRemove ?? []),\n ...(userResetTaskOptions.pathsToRemove ?? []),\n ],\n },\n );\n new ResetTask(this, resetTaskOptions);\n }\n\n /**\n *\n */\n\n if (options.parent && options.parent instanceof MonorepoProject) {\n // Install dependencies via the parent project\n /* @ts-ignore access private method */\n const originalResolve = this.package.resolveDepsAndWritePackageJson;\n /* @ts-ignore access private method */\n this.package.installDependencies = () => {\n (options.parent as MonorepoProject).requestInstallDependencies({\n resolveDepsAndWritePackageJson: () =>\n originalResolve.apply(this.package),\n });\n };\n /* @ts-ignore access private method */\n this.package.resolveDepsAndWritePackageJson = () => {};\n }\n }\n}\n","import { Component, vscode } from \"projen\";\nimport { TypeScriptAppProject } from \"projen/lib/typescript\";\n\n/*******************************************************************************\n *\n * Configure VSCode Settings\n *\n ******************************************************************************/\n\nexport class VSCodeConfig extends Component {\n constructor(project: TypeScriptAppProject) {\n super(project);\n\n /**\n * Create instance of config file.\n */\n const vsConfig = new vscode.VsCode(project);\n\n /**\n * Add some basic configuration settings to the VS Code settings file:\n *\n * - Set the tab size to 2 spaces\n * - Enable bracket pair colorization\n * - Highlight active bracket pairs\n * - Add rulers at 80 and 120 characters\n */\n const vsSettings = new vscode.VsCodeSettings(vsConfig);\n vsSettings.addSetting(\"editor.tabSize\", 2);\n vsSettings.addSetting(\"editor.detectIndentation\", false);\n vsSettings.addSetting(\"editor.bracketPairColorization.enabled\", true);\n vsSettings.addSetting(\"editor.guides.bracketPairs\", \"active\");\n vsSettings.addSetting(\"editor.rulers\", [80, 120]);\n\n /**\n * Add some ESLint specific settings to the VS Code settings file.\n */\n vsSettings.addSetting(\n \"editor.codeActionsOnSave\",\n { \"source.fixAll.eslint\": \"explicit\" },\n \"typescript\",\n );\n }\n}\n","import { relative } from \"node:path\";\nimport { Component } from \"projen\";\nimport { TypeScriptProject } from \"projen/lib/typescript\";\nimport { ensureRelativePathStartsWithDot } from \"projen/lib/util/path\";\n\n/*******************************************************************************\n *\n * Update / customize typescript configs for a project.\n *\n * Update typescript paths in tsconfig so we don't have to compile packages to\n * dist in order to see changes.\n *\n ******************************************************************************/\nexport class TypeScriptConfig extends Component {\n constructor(project: TypeScriptProject) {\n super(project);\n\n /**\n * Container for paths to insert at the end.\n */\n let tsPaths = {};\n\n const workspaceDeps = project.deps.all.filter(\n (d) => d.version === \"workspace:*\",\n );\n\n workspaceDeps.forEach((dep) => {\n const subproject = (\n project.root.subprojects as Array<TypeScriptProject>\n ).find((p) => p.package.packageName === dep.name);\n\n if (!subproject) {\n throw new Error(`Could not find subproject ${dep.name} in monorepo.`);\n }\n\n tsPaths = {\n ...tsPaths,\n [dep.name]: [\n ensureRelativePathStartsWithDot(\n relative(project.outdir, subproject.outdir),\n ),\n ],\n };\n });\n\n project.tsconfig?.file.addOverride(\"compilerOptions.paths\", tsPaths);\n project.tsconfigDev?.file.addOverride(\"compilerOptions.paths\", tsPaths);\n }\n}\n","// eslint-disable-next-line import/no-extraneous-dependencies\nimport {\n AWS_STAGE_TYPE,\n AwsStageType,\n DEPLOYMENT_TARGET_ROLE,\n DeploymentTargetRoleType,\n} from \"@codedrifters/utils\";\nimport { Component } from \"projen\";\nimport { AwsCdkTypeScriptApp } from \"projen/lib/awscdk\";\nimport { BuildWorkflow, BuildWorkflowOptions } from \"projen/lib/build\";\nimport { GitHub } from \"projen/lib/github\";\nimport { JobPermission, JobStep } from \"projen/lib/github/workflows-model\";\nimport { ValueOf } from \"type-fest\";\nimport { AwsDeploymentConfig } from \"../aws\";\nimport { AwsDeploymentTarget } from \"../aws/aws-deployment-target\";\nimport { GitBranch } from \"../git\";\nimport { MonorepoProject } from \"../projects\";\nimport { ROOT_CI_TASK_NAME, TurboRepo } from \"../turbo\";\nimport { VERSION } from \"../versions\";\n\nexport const PROD_DEPLOY_NAME = \"prod-deploy\";\n\nexport interface DeployWorkflowOptions {\n /**\n * What type of deploy is this workflow for?\n *\n * @default AWS_STAGE_TYPE.DEV\n */\n readonly awsStageType?: ValueOf<typeof AWS_STAGE_TYPE>;\n\n /**\n * Optionally feed a list of targets to deploy to.\n *\n * @default discovers all targets using stageType\n */\n readonly awsDeploymentTargets?: Array<AwsDeploymentTarget>;\n\n /**\n * Existing workflow, useful if we're tacking deployments onto an existing\n * build workflow\n */\n readonly buildWorkflow?: BuildWorkflow;\n\n /**\n * Options for the build workflow, if no build workflow is provided.\n */\n readonly buildWorkflowOptions?: Partial<BuildWorkflowOptions>;\n\n /**\n * Projects that should complete deployment before this one starts.\n */\n readonly deployAfterTargets?: Array<AwsDeploymentTarget>;\n}\n\nexport class AwsDeployWorkflow extends Component {\n public static of(\n project: AwsCdkTypeScriptApp,\n buildWorkflow: BuildWorkflow,\n ): AwsDeployWorkflow | undefined {\n const isDefined = (c: Component): c is AwsDeployWorkflow =>\n c instanceof AwsDeployWorkflow && c.buildWorkflow === buildWorkflow;\n return project.components.find(isDefined);\n }\n\n /**\n * The root project for this deploy workflow. Must be a monorepo project.\n */\n private rootProject: MonorepoProject;\n\n /**\n * What type of deploy is this workflow for?\n */\n public awsStageType: AwsStageType;\n\n /**\n * AWS environment type, such as primary or secondary.\n *\n * @deprecated Use deployment target role terminology elsewhere. This property is maintained for backward compatibility.\n * @default 'primary' (this is the only type supported currently)\n */\n public awsEnvironmentType: DeploymentTargetRoleType =\n DEPLOYMENT_TARGET_ROLE.PRIMARY;\n\n /**\n * The list of targets to deploy to.\n */\n readonly awsDeploymentTargets: Array<AwsDeploymentTarget>;\n\n /**\n * Hold the deploy workflow so we can add to it in preSynth\n */\n public buildWorkflow: BuildWorkflow;\n\n /**\n * Was this workflow created externally?\n */\n public externalWorkflow: boolean;\n\n /**\n * Projects that should complete deployment before this one starts.\n */\n public deployAfterTargets: Array<AwsDeploymentTarget>;\n\n constructor(\n public project: AwsCdkTypeScriptApp,\n public options: DeployWorkflowOptions = {},\n ) {\n super(project);\n\n /***************************************************************************\n *\n * Root project check\n *\n * Detect the root project and ensure it's of type MonorepoProject.\n *\n **************************************************************************/\n\n if (!(project.root instanceof MonorepoProject)) {\n throw new Error(\n \"AwsDeployWorkflow requires the root project to be a MonorepoProject\",\n );\n }\n\n this.rootProject = project.root;\n\n /***************************************************************************\n *\n * GitHub Check\n *\n * Make sure github config is active in the project. This is to ensure all\n * workflows will be output properly during synth.\n *\n **************************************************************************/\n\n const github = GitHub.of(this.rootProject);\n\n if (!github) {\n throw new Error(\n \"AwsDeployWorkflow requires a GitHub component in the root project\",\n );\n }\n\n /***************************************************************************\n *\n * TurboRepo Check\n *\n * If turbo is enabled, we may need the options later in this file.\n *\n **************************************************************************/\n\n const turbo = TurboRepo.of(this.rootProject);\n const buildWorkflowOptions: Partial<BuildWorkflowOptions> =\n turbo?.remoteCacheOptions\n ? TurboRepo.buildWorkflowOptions(turbo.remoteCacheOptions)\n : {};\n\n /***************************************************************************\n *\n * Workflow Deploy Type\n *\n * What type of environments are we deploying into? We'll default to dev to\n * be safe.\n *\n **************************************************************************/\n\n this.awsStageType = options.awsStageType ?? AWS_STAGE_TYPE.DEV;\n\n /***************************************************************************\n *\n * Workflow Deploy Targets\n *\n * Use provided targets or discover them based on the deploy type. Only\n * include targets that are marked for CI/CD.\n *\n **************************************************************************/\n\n this.awsDeploymentTargets =\n options.awsDeploymentTargets ??\n AwsDeploymentConfig.of(project)?.awsDeploymentTargets.filter(\n (target) =>\n target.awsStageType === this.awsStageType && target.ciDeployment,\n ) ??\n [];\n\n this.deployAfterTargets = options.deployAfterTargets ?? [];\n\n /***************************************************************************\n *\n * Build Workflow Options\n *\n * Can't use the options if an existing workflow was passed in.\n *\n **************************************************************************/\n\n if (options.buildWorkflow && options.buildWorkflowOptions) {\n throw new Error(\n \"Cannot provide both buildWorkflow and buildWorkflowOptions\",\n );\n }\n\n this.externalWorkflow = !!options.buildWorkflow;\n\n /***************************************************************************\n *\n * Build Workflow\n *\n * Create a workflow either based on input or from scratch.\n *\n **************************************************************************/\n\n this.buildWorkflow =\n options.buildWorkflow ??\n new BuildWorkflow(this.rootProject, {\n /**\n * Name based on project and environment.\n */\n name:\n options.buildWorkflowOptions?.name ??\n [\n \"deploy\",\n project.name,\n this.awsStageType,\n this.awsEnvironmentType,\n ].join(\"-\"),\n\n /**\n * Use the root projects build task.\n */\n buildTask: this.rootProject.buildTask,\n\n /**\n * Use push triggers based n the branch config for each environment.\n */\n workflowTriggers: {\n push: {\n branches: [\n ...this.awsDeploymentTargets.flatMap((t) =>\n t.branches.map((b) => b.branch),\n ),\n ],\n },\n workflowDispatch: {},\n ...options.buildWorkflowOptions?.workflowTriggers,\n },\n\n /**\n * Never allow mutations for deploys. This should have been handled\n * during build.\n */\n mutableBuild: false,\n\n /**\n * Do this pre-merge of permissions and build steps\n */\n ...options.buildWorkflowOptions,\n\n /**\n * Set BRANCH_NAME so Turborepo remote cache hashes match between local and CI.\n */\n env: {\n BRANCH_NAME: \"${{ github.head_ref || github.ref_name }}\",\n ...options.buildWorkflowOptions?.env,\n ...buildWorkflowOptions?.env,\n },\n\n /**\n * Some additional permissions may be required when turbo's involved.\n */\n permissions: {\n ...options.buildWorkflowOptions?.permissions,\n ...buildWorkflowOptions?.permissions,\n },\n\n /**\n * Assemble all pre-build steps\n */\n preBuildSteps: [\n ...this.setupPnpm(),\n ...this.setupNode(),\n {\n name: \"Install dependencies\",\n run: \"pnpm i --no-frozen-lockfile\",\n },\n ...(options.buildWorkflowOptions?.preBuildSteps ?? []),\n ...(buildWorkflowOptions?.preBuildSteps ?? []),\n ],\n });\n\n /***************************************************************************\n *\n * Add Deployments to workflow\n *\n **************************************************************************/\n\n const buildJobName = (target: AwsDeploymentTarget) => {\n return [\n target.awsStageType,\n target.deploymentTargetRole,\n \"deploy\",\n target.project.name,\n target.account,\n target.region,\n ].join(\"-\");\n };\n\n this.awsDeploymentTargets.forEach((target) => {\n const deployJobName = buildJobName(target);\n\n // Build the branch filter condition\n const branchFilterCondition = this.buildBranchFilterCondition(\n target.branches,\n );\n\n // Combine with the existing build mutation check\n const jobCondition = branchFilterCondition\n ? \"${{ \" +\n [\n \"!needs.build.outputs.self_mutation_happened\",\n `(${branchFilterCondition})`,\n ].join(\" && \") +\n \" }}\"\n : \"${{ !needs.build.outputs.self_mutation_happened }}\";\n\n this.buildWorkflow.addPostBuildJob(deployJobName, {\n name: `Deploy ${this.project.name} ${target.awsStageType}/${target.deploymentTargetRole}/${target.account}/${target.region}`,\n needs: [\n \"build\",\n ...this.deployAfterTargets.map((p) => {\n return buildJobName(p);\n }),\n ],\n runsOn: [\"ubuntu-latest\"],\n permissions: {\n contents: JobPermission.READ,\n idToken: JobPermission.WRITE,\n },\n concurrency: deployJobName,\n if: jobCondition,\n steps: [...this.deploySteps(target)],\n });\n });\n }\n\n public setupNode = (): Array<JobStep> => {\n return [\n {\n name: \"Setup Node\",\n uses: \"actions/setup-node@v4\",\n with: {\n [\"node-version\"]: VERSION.NODE_WORKFLOWS,\n },\n // occasionally this step fails due to internal issues at github\n timeoutMinutes: 1,\n },\n ];\n };\n\n public setupPnpm = (): Array<JobStep> => {\n return [\n {\n name: \"Setup PNPM\",\n uses: \"pnpm/action-setup@v3\",\n with: {\n version: VERSION.PNPM_VERSION,\n },\n },\n ];\n };\n\n /**\n * Builds a GitHub Actions condition string that checks if the current branch\n * matches any of the provided branch patterns.\n *\n * Handles both exact matches (e.g., \"main\") and glob patterns (e.g., \"feature/*\").\n * Also allows workflow_dispatch (manual runs) to proceed.\n *\n * @param branches Array of GitBranch objects with branch patterns\n * @returns Condition string or empty string if no branches provided\n */\n private buildBranchFilterCondition = (branches: Array<GitBranch>): string => {\n if (!branches || branches.length === 0) {\n return \"\";\n }\n\n const conditions: Array<string> = [];\n\n // Always allow workflow_dispatch (manual workflow runs)\n conditions.push(\"github.event_name == 'workflow_dispatch'\");\n\n for (const branch of branches) {\n const branchPattern = branch.branch;\n\n // Handle glob patterns (e.g., \"feature/*\")\n if (branchPattern.includes(\"*\")) {\n // Replace * with proper startsWith check\n const prefix = branchPattern.replace(/\\*.*$/, \"\");\n conditions.push(`startsWith(github.ref, 'refs/heads/${prefix}')`);\n // PR support, unprefixed branch names\n conditions.push(`startsWith(github.head_ref, '${prefix}')`);\n } else {\n // Exact match\n conditions.push(`github.ref == 'refs/heads/${branchPattern}'`);\n }\n }\n\n /**\n * Combine all conditions with OR\n */\n return conditions.join(\" || \");\n };\n\n private deploySteps = (target: AwsDeploymentTarget): Array<JobStep> => {\n const {\n awsStageType,\n deploymentTargetRole,\n account,\n region,\n ciDeploymentConfig,\n awsDeploymentConfig,\n } = target;\n const { roleArn, stackPattern } = ciDeploymentConfig ?? {};\n const { rootCdkOut } = awsDeploymentConfig;\n\n return [\n ...this.setupPnpm(),\n ...this.setupNode(),\n\n /**\n * Install CDK\n */\n {\n name: \"Install CDK\",\n run: \"pnpm add aws-cdk\",\n },\n\n /**\n * Configure AWS creds.\n */\n {\n name: `AWS Creds ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,\n uses: \"aws-actions/configure-aws-credentials@v4\",\n with: {\n \"role-to-assume\": roleArn,\n \"aws-region\": region,\n \"role-duration-seconds\": 900, // 15 minutes\n },\n },\n\n /**\n * Run CDK Deploy\n */\n {\n name: `Deploy ${awsStageType}/${deploymentTargetRole}/${account}/${region}`,\n run: `pnpm dlx aws-cdk deploy --no-rollback --require-approval=never --app=${rootCdkOut} \"${stackPattern}\"`,\n },\n ];\n };\n\n preSynthesize(): void {\n /**\n * Ensure turbo is active when needed.\n */\n if (!this.externalWorkflow && TurboRepo.of(this.rootProject)) {\n this.buildWorkflow.addPostBuildSteps({\n name: \"Build Sub Projects\",\n run: `npx projen ${ROOT_CI_TASK_NAME}`,\n });\n }\n\n super.preSynthesize();\n }\n}\n"],"mappings":"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","names":["exports","exports","exports","exports","import_lib","import_utils","import_projen","import_projen","import_projen","import_javascript","import_ts_deepmerge","import_projen","import_projen","import_projen","import_node_path","import_projen","import_path","import_utils","import_projen","import_workflows_model"]}
|