@xpertss/projen-types 0.0.12 → 0.0.13

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/.jsii CHANGED
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "name": "@xpertss/projen-types",
108
108
  "readme": {
109
- "markdown": "# @xpertss/projen-types\n\nProjen project types for CDK/TypeScript and Java/Maven projects.\n\nInstead of hand-maintaining `pom.xml`, `cdk.json`, and GitHub workflows, you declare a project type in a `.projenrc.ts` file and let [projen](https://github.com/projen/projen) generate (and keep up to date) the whole scaffold: build files, source skeletons, CI workflows, and deploy pipelines.\n\n## Project types at a glance\n\n| Type | What it is | Publishes to | Generated workflows |\n| --- | --- | --- | --- |\n| `CdkInfraProject` | Pure-infrastructure CDK stacks (CloudFront, Route53, SQS, API Gateway, Cognito, ECR/ECS for externally-built images) | - | `build` (PR checks), `deploy` (manual dispatch) |\n| `CdkAppProject` | Full TypeScript service behind API Gateway: infra + app source + database | - | `build`, `deploy`, `app-build` (PR checks) |\n| `JavaLibraryProject` | Reusable Java library | Maven Central | `build`, `upgrade` (nightly), `publish-maven-central`, `codeindex` |\n| `JavaServiceProject` | Spring Boot service | Docker Hub | `build`, `upgrade` (nightly), `publish-docker`, `deploy-cdk` |\n| `JavaAppProject` | GUI/TUI/CLI Java application | GitHub Packages | `build`, `upgrade` (nightly), `publish-ghpackages` |\n| `GitHubActionProject` | Reusable GitHub Action or Workflow | GitHub Releases | `build`, `test-dogfood`, `sonar`, `release` |\n\nTwo foundation classes are also exported for advanced use: `CdkTypescriptProject` (shared CDK + TypeScript base for the CDK types) and `JavaMavenProject` (shared Maven base for the Java types).\n\nAll project types:\n\n- run a **drift check** in PR builds - a job that re-runs projen and fails if generated files were hand-edited. Edit `.projenrc.ts`, then run `npx projen`; never edit generated files directly.\n- use the GitHub secret `PROJEN_GITHUB_TOKEN` (a fine-grained PAT) for projen's automation. Override with `gheTokenSecret`.\n- make all publishing/deploying **manual** (workflow_dispatch) rather than on every merge.\n\n## Getting started\n\nScaffold the repo with projen's own bootstrap, pointed at this package:\n\n```bash\nmkdir my-project && cd my-project\ngit init\nnpx projen new --from @xpertss/projen-types cdk_infra --name my-project\n```\n\nThat writes a starter `.projenrc.ts`, synthesizes the whole scaffold and\ninstalls dependencies. The type names `projen new` accepts are `cdk_infra`,\n`cdk_app`, `java_library`, `java_service`, `java_app` and\n`git_hub_action`; pass a bogus one to have it list them. Required options\nbecome flags: `--name` for every type, plus `--group-id`/`--artifact-id`\n(Java) and `--sonar-host-url` (`git_hub_action`). Any other plainly-typed\noption can be passed the same way - `--cdk-deploy-target-repo owner/repo`,\n`--docker-registry ghcr.io`, `--no-use-flyway`, and so on.\n\nCommit the result. From then on, every change to the scaffold goes through\n`.projenrc.ts` followed by `npx projen`:\n\n```bash\nnpx projen\n```\n\nEvery type scaffolds from that one command; no option is *required* that\n`projen new` cannot pass. The structured options - `environments` and\n`GitHubActionProject`'s `dogfood` - are ones projen's CLI cannot render\ninto a projenrc, so they are added afterwards by editing `.projenrc.ts` and\nre-running `npx projen`. Leaving `environments` out simply generates no\ndeploy workflow; leaving `dogfood` out (or a service's\n`cdkDeployTargetRepo`) still generates the workflow, with one step that\nfails and tells you what to add - a gate this package considers load-bearing\nis allowed to be missing loudly, never silently.\n\nThe `name` option must match the `name` field in the project's `package.json` (for the CDK types) or the project name used by projen's `java.JavaProject` (for the Java types).\n\n## Updating an existing project when this package changes\n\nYour generated scaffold reflects the *installed* version of `@xpertss/projen-types` - `npx projen` reads your project type from the package in `node_modules`, not from this repository. So when this package ships a change (a bug fix, a new generated file, or altered workflow behavior), an existing project picks it up by bumping the dependency and re-synthesizing. A stale `node_modules` silently regenerates with the old behavior, so the bump is the load-bearing step.\n\nUsing the [`auto-commit` action](#githubactionproject) as a running example, say a new release adds the `# Purpose:` workflow header and SonarCloud wording. In the `auto-commit` repo:\n\n```bash\nnpm view @xpertss/projen-types version # what's the newest release?\nnpm i -D @xpertss/projen-types@latest # bump the installed project type\nnpx projen # re-synthesize every generated file\ngit diff # review before committing\n```\n\nThe diff here is the workflows gaining a `# Purpose:` comment and `sonar.yml` reflecting the SonarCloud wording. Commit the result with a normal `chore:` or `fix:` message - you never hand-edit the generated files themselves.\n\n## Examples\n\n### CdkInfraProject\n\nPure infrastructure stacks with optional ECR/ECS and edge-networking constructs.\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'media-edge-infra',\n environments: [\n 'dev',\n { name: 'stage', accountId: '111111111111', region: 'eu-central-1' },\n { name: 'prod', accountId: '222222222222', region: 'eu-central-1', requiresApproval: true },\n ],\n edgeResources: ['cloudfront', 'route53', 'sqs'],\n ecrEcs: { enabled: true, externalImageSource: true },\n slackWebhookSecret: 'SLACK_DEPLOY_WEBHOOK',\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `cdk.json`, `cdk synth` / `cdk diff` / `cdk deploy` tasks, and the standard `AwsCdkTypeScriptApp` layout (CDK 2.189.1 by default).\n- `.github/workflows/build.yml` - PR build that hard-fails on projen drift.\n- `.github/workflows/deploy.yml` - manual dispatch with one `deploy-<env>` job per environment (runs `cdk deploy --all` with `--context environment=<env>`); `requiresApproval` environments get a GitHub Environment approval gate; a Slack notification step is added when `slackWebhookSecret` is set.\n- `src/constructs/edge-networking.ts` - helper constructs only for the requested `edgeResources` (`cloudfront`, `route53`, `apigateway`, `cognito`, `sqs`).\n- `src/constructs/ecr-ecs.ts` when `ecrEcs.enabled` - ECR repo + Fargate service; `externalImageSource: true` (default) means the service pulls an image built outside this repo.\n\n### CdkAppProject\n\n`CdkInfraProject` plus application source, a database construct, and an app-level build workflow.\n\n```typescript\n// .projenrc.ts\nimport { CdkAppProject } from '@xpertss/projen-types';\n\nconst project = new CdkAppProject({\n name: 'video-api',\n environments: ['dev', 'prod'],\n edgeResources: ['apigateway'],\n database: { engine: 'postgres', migrationTool: 'flyway' },\n appEntryPoint: 'src/app.ts',\n});\n\nproject.synth();\n```\n\nEverything from `CdkInfraProject`, plus:\n\n- `src/app.ts` - application entrypoint stub (`export function handler()`).\n- `src/handlers/example.ts` - API Gateway proxy handler stub, with `@types/aws-lambda` added as a dev dependency.\n- `src/constructs/database.ts` - a `Database` construct stub for the chosen engine (`postgres`/`mysql` -> RDS, `dynamodb` -> DynamoDB). `migrationTool` (no default, intentionally) is added as a dev dependency and referenced in the stub - wiring it up is left to you.\n- `.github/workflows/app-build.yml` - runs the project's test task on every PR, then checks for projen drift.\n\n### JavaLibraryProject\n\nA reusable Java library published to Maven Central.\n\n```typescript\n// .projenrc.ts\nimport { JavaLibraryProject } from '@xpertss/projen-types';\n\nconst project = new JavaLibraryProject({\n name: 'common-utils',\n groupId: 'org.xpertss',\n artifactId: 'common-utils',\n version: '1.0.0',\n sonarProjectKey: 'org.xpertss:common-utils',\n mavenCentralOidc: true,\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `pom.xml` (via projen's `java.JavaProject`) with the given GAV coordinates.\n- `.github/workflows/build.yml` - PR build + projen drift check, plus a SonarQube scan step when `sonarProjectKey` is set (needs a `SONAR_TOKEN` secret).\n- `.github/workflows/upgrade.yml` - nightly (03:00 UTC) PR running `mvn versions:use-latest-releases versions:update-properties`.\n- `.github/workflows/publish-maven-central.yml` - manual dispatch running `mvn -B deploy -P release`. With `mavenCentralOidc: true` it uses Maven Central's OIDC trusted publishing (no GPG secrets needed); otherwise it expects the secrets `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD`.\n- `.github/workflows/codeindex.yml` - on push to `main`, generates a Java source index under `.cai/` (disable with `publishCodeIndex: false`).\n\n### JavaServiceProject\n\nA Spring Boot service that publishes a Docker image and can trigger deploys in a companion CDK repo.\n\n```typescript\n// .projenrc.ts\nimport { JavaServiceProject } from '@xpertss/projen-types';\n\nconst project = new JavaServiceProject({\n name: 'stream-processor',\n groupId: 'org.xpertss',\n artifactId: 'stream-processor',\n dockerRegistry: 'docker.io/xpertss',\n cdkDeployTargetRepo: 'xpertss/stream-infra',\n environments: ['dev', { name: 'prod', requiresApproval: true }],\n});\n\nproject.synth();\n```\n\nYou get (everything from `JavaMavenProject` - `pom.xml`, `build` + drift check, nightly `upgrade` - plus):\n\n- `spring-boot-starter-web` added to the pom.\n- `.github/workflows/publish-docker.yml` - manual dispatch: `mvn -B package && docker build -t <registry>/<name>:<sha>`, logged in with the `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets. `dockerRegistry` defaults to `docker.io`.\n- Flyway wiring when `useFlyway` (default `true`): `flyway-maven-plugin` ^10 + `flyway-core` ^10 in the pom, and `src/main/resources/db/migration/V1__init.sql`.\n- `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, generated by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `cdkDeployTargetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). With no `cdkDeployTargetRepo` set, the workflow is still generated but each job's only step fails with instructions - it is dispatch-only, so that lands on whoever tries to deploy rather than on every PR. Turn the workflow off entirely with `cdkDeployHook: false`. `environments` defaults to `['prod']`.\n\n### JavaAppProject\n\nA GUI/TUI/CLI Java application published to GitHub Packages only - no Maven Central, no Docker, no CDK deploy hook.\n\n```typescript\n// .projenrc.ts\nimport { JavaAppProject } from '@xpertss/projen-types';\n\nconst project = new JavaAppProject({\n name: 'studio-cli',\n groupId: 'org.xpertss',\n artifactId: 'studio-cli',\n ghPackagesRegistry: 'https://maven.pkg.github.com/xpertss/studio-cli',\n});\n\nproject.synth();\n```\n\nYou get everything from `JavaMavenProject`, plus `.github/workflows/publish-ghpackages.yml` - manual dispatch running `mvn -B deploy -DaltDeploymentRepository=github::<registry>`, authenticated with `GITHUB_TOKEN`. `ghPackagesRegistry` defaults to `https://maven.pkg.github.com/<repo>` derived from the repository URL.\n\n### GitHubActionProject\n\nA reusable GitHub Action or Workflow. This example scaffolds an action that stages a folder and, only if it changed, commits and pushes it.\n\n```typescript\n// .projenrc.ts\nimport { GitHubActionProject } from '@xpertss/projen-types';\n\nconst project = new GitHubActionProject({\n name: 'auto-commit',\n description: 'Stage a folder and, only if it changed, commit and push it',\n sonarHostUrl: 'https://sonarcloud.io', // required, no default - your SonarCloud URL\n dogfood: {\n // Two scenario steps: the \"changed\" path and the \"no-op\" path are both\n // load-bearing behavior for this action (a double-commit or a\n // push-when-empty bug is the failure mode a hand-rolled inline-shell\n // alternative is most likely to introduce).\n scenario: [\n {\n name: 'Changed path',\n fixtureSteps: [\n 'echo \"$(date -u +%Y%m%dT%H%M%SZ)\" >> test/fixtures/dogfood-state.txt',\n ],\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n // step id defaults to a slug of `name` - here \"changed-path-0\"\n '[ \"${{ steps.changed-path-0.outputs.committed }}\" = \"true\" ]',\n ],\n },\n {\n // No fixture change this time - nothing new to commit.\n name: 'No-op path',\n id: 'no-op-check', // pin an explicit id instead of relying on the default slug\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n '[ \"${{ steps.no-op-check.outputs.committed }}\" = \"false\" ]',\n ],\n },\n ],\n cleanup: [\n 'git push origin --delete test/dogfood || true',\n ],\n },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.\n- `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` alongside `sonar.yml`.\n- `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: .`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.\n- `.github/workflows/sonar.yml` - SonarCloud scan via the Scanner CLI (the quality gate blocks the PR), scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly.\n- `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.\n- `.github/workflows/projen-drift-check.yml` and `workflow-change-notice.yml` - drift detection and a change notice, always included.\n- `package.json` (**private**, version source only), `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.\n\nNeeds the same two secrets as everything else in this package: `PROJEN_GITHUB_TOKEN` (used for automated PR comments) and `SONAR_TOKEN` (the Sonar scan). Onboard a brand-new action repo following [Getting started](#getting-started), write the `.projenrc.ts` above, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`.\n\n## Common options\n\nCDK project types (`CdkInfraProjectOptions` / `CdkAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name; must match `package.json` |\n| `cdkVersion` | `2.189.1` | AWS CDK version |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `slackWebhookSecret` | - | GitHub secret with a Slack webhook URL for deploy notifications |\n| `environments` | - (no `deploy` workflow) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |\n| `ecrEcs` | - | `EcrEcsOptions` - `enabled`, `externalImageSource` (default `true`) |\n| `edgeResources` | - | Subset of `cloudfront`, `route53`, `apigateway`, `cognito`, `sqs` |\n| `database` | - (app only) | `DatabaseOptions` - `engine` (`postgres`/`mysql`/`dynamodb`, default `postgres`), `migrationTool` |\n| `appEntryPoint` | `src/app.ts` (app only) | Path of the generated application entrypoint |\n\nJava project types (`JavaLibraryProjectOptions` / `JavaServiceProjectOptions` / `JavaAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `groupId` | - (required) | Maven group id |\n| `artifactId` | - (required) | Maven artifact id |\n| `version` | `0.1.0` | Maven version |\n| `sonarProjectKey` | - | SonarQube project key; the sonar step is skipped when unset |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `cdkDeployTargetRepo` | - (service only; `deploy-cdk.yml` fails until set) | Companion CDK repo (`owner/repo`) whose `deploy.yml` the deploy hook dispatches |\n| `cdkDeployHook` | `true` (service only) | Whether to generate `deploy-cdk.yml` at all |\n| `dockerRegistry` | `docker.io` (service only) | Registry the Docker image is pushed to |\n| `useFlyway` | `true` (service only) | Flyway plugin/dependency + `V1__init.sql` |\n\n`EnvironmentOptions` for deploy targets:\n\n```text\ninterface EnvironmentOptions {\n readonly name: string; // e.g. \"dev\", \"stage\", \"prod\"\n readonly accountId?: string; // AWS account id (CDK deploys)\n readonly region?: string; // AWS region (CDK deploys)\n readonly requiresApproval?: boolean; // GitHub Environment approval gate (default false)\n}\n```\n\nPlain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.\n\n`GitHubActionProjectOptions`:\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `description` | - | One-line description; used in the default README template and recorded in the private `package.json` |\n| `sonarHostUrl` | - (required) | URL of your SonarCloud instance (e.g. `https://sonarcloud.io`); must be reachable from github.com-hosted runners |\n| `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |\n| `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |\n| `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: .` |\n| `license` | `MIT` | SPDX identifier for the generated `LICENSE` |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n\n`ActionDogfoodOptions`/`ActionDogfoodStep` - the dogfood scenario (`test-dogfood.yml`):\n\n```text\ninterface ActionDogfoodOptions {\n readonly scenario: ActionDogfoodStep[]; // one or more, run in order - required\n readonly cleanup: string[]; // shared, run once at the end with `if: always()` - required\n}\n\ninterface ActionDogfoodStep {\n readonly name: string; // labels this step-group's generated workflow steps\n readonly id?: string; // step id for the `uses: .` call; default: a slug of `name`\n readonly fixtureSteps?: string[]; // shell, before the invocation (default: none)\n readonly inputs?: Record<string, string>; // `with:` for this invocation (default: none)\n readonly assertions: string[]; // shell, after the invocation - required, job fails unless all exit 0\n}\n```\n\nMost actions need exactly one `scenario` step. Actions with a re-run/no-op/idempotency behavior to verify (e.g. `auto-commit`'s no-op-on-no-change path, `create-pull-request`'s reuse-the-PR path) declare two - the second typically omits `fixtureSteps` so its invocation sees no new state, and its assertion checks the opposite outcome of the first. Reference an invocation's own outputs from a later assertion via `${{ steps.<id>.outputs.<name> }}`, using either the default slug or an explicit `id`.\n\n## Required GitHub secrets\n\n| Secret | Used by | Notes |\n| --- | --- | --- |\n| `PROJEN_GITHUB_TOKEN` | all types | PAT for projen's self-mutation/automation; override via `gheTokenSecret` |\n| `SONAR_TOKEN` | Java types with `sonarProjectKey`; `GitHubActionProject` | SonarQube scan step in `build.yml` / `sonar.yml`; override via `sonarTokenSecret` on `GitHubActionProject` |\n| `DOCKER_USERNAME` / `DOCKER_PASSWORD` | `JavaServiceProject` | Docker image push |\n| `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD` | `JavaLibraryProject` without `mavenCentralOidc` | Not needed with OIDC trusted publishing |\n| (your Slack webhook secret) | CDK types with `slackWebhookSecret` | Deploy notifications |\n\n## Going further\n\nThe project types are composed from smaller components you can also attach to your own projects:\n\n| Component | Applies to | Purpose |\n| --- | --- | --- |\n| `AppRuntimeScaffold` | `NodeProject` | App source skeleton (`app.ts` + handlers) |\n| `DatabaseComponent` | `NodeProject` | Database construct stub + migration tool wiring |\n| `EcrEcsConstructs` | `Project` | ECR + Fargate ECS construct helper |\n| `EdgeNetworkingConstructs` | `Project` | Per-resource edge networking construct helpers |\n| `MavenCentralPublish` | `JavaProject` | Manual-dispatch Maven Central publish workflow |\n| `DockerPublish` | `JavaProject` | Manual-dispatch Docker build+push workflow |\n| `GitHubPackagesPublish` | `JavaProject` | Manual-dispatch GitHub Packages publish workflow |\n| `FlywayMigration` | `JavaProject` | Flyway plugin/dependency + migrations directory |\n| `CdkDeployHook` | `JavaProject` | Manual-dispatch workflow that triggers `deploy.yml` in a companion CDK repo |\n| `CodeIndexWorkflow` | `JavaProject` | Code index generation on push to `main` |\n| `ActionBuildWorkflow` | `GitHubProject` | The `lint` task (shellcheck/yamllint/pinned actionlint) + `build.yml` |\n| `ActionDogfoodWorkflow` | `GitHubProject` | `test-dogfood.yml` from an `ActionDogfoodOptions` scenario |\n| `ActionSonarWorkflow` | `GitHubProject` | `sonar.yml` (SonarCloud scan via the Scanner CLI) |\n\nExample - adding a Docker publish to a plain projen `JavaProject`:\n\n```typescript\nimport { java } from 'projen';\nimport { DockerPublish } from '@xpertss/projen-types';\n\nconst project = new java.JavaProject({\n name: 'my-service',\n groupId: 'org.xpertss',\n artifactId: 'my-service',\n});\n\nnew DockerPublish(project, { dockerRegistry: 'ghcr.io' });\n\nproject.synth();\n```\n\nThe full API reference, including every option and property, is in [API.md](./API.md).\n"
109
+ "markdown": "# @xpertss/projen-types\n\nProjen project types for CDK/TypeScript and Java/Maven projects.\n\nInstead of hand-maintaining `pom.xml`, `cdk.json`, and GitHub workflows, you declare a project type in a `.projenrc.ts` file and let [projen](https://github.com/projen/projen) generate (and keep up to date) the whole scaffold: build files, source skeletons, CI workflows, and deploy pipelines.\n\n## Project types at a glance\n\n| Type | What it is | Publishes to | Generated workflows |\n| --- | --- | --- | --- |\n| `CdkInfraProject` | Pure-infrastructure CDK stacks (CloudFront, Route53, SQS, API Gateway, Cognito, ECR/ECS for externally-built images) | - | `build` (PR checks), `deploy` (manual dispatch) |\n| `CdkAppProject` | Full TypeScript service behind API Gateway: infra + app source + database | - | `build`, `deploy`, `app-build` (PR checks) |\n| `JavaLibraryProject` | Reusable Java library | Maven Central | `build`, `upgrade` (nightly), `publish-maven-central`, `codeindex` |\n| `JavaServiceProject` | Spring Boot service | Docker Hub | `build`, `upgrade` (nightly), `publish-docker`, `deploy-cdk` |\n| `JavaAppProject` | GUI/TUI/CLI Java application | GitHub Packages | `build`, `upgrade` (nightly), `publish-ghpackages` |\n| `GitHubActionProject` | Reusable GitHub Action or Workflow | GitHub Releases | `build`, `test-dogfood`, `sonar`, `release` |\n\nTwo foundation classes are also exported for advanced use: `CdkTypescriptProject` (shared CDK + TypeScript base for the CDK types) and `JavaMavenProject` (shared Maven base for the Java types).\n\nAll project types:\n\n- run a **drift check** in PR builds - a job that re-runs projen and fails if generated files were hand-edited. Edit `.projenrc.ts`, then run `npx projen`; never edit generated files directly.\n- use the GitHub secret `PROJEN_GITHUB_TOKEN` (a fine-grained PAT) for projen's automation. Override with `gheTokenSecret`.\n- make all publishing/deploying **manual** (workflow_dispatch) rather than on every merge.\n\n## Getting started\n\nScaffold the repo with projen's own bootstrap, pointed at this package:\n\n```bash\nmkdir my-project && cd my-project\ngit init\nnpx projen new --from @xpertss/projen-types cdk_infra --name my-project\n```\n\nThat writes a starter `.projenrc.ts`, synthesizes the whole scaffold and\ninstalls dependencies. The type names `projen new` accepts are `cdk_infra`,\n`cdk_app`, `java_library`, `java_service`, `java_app` and\n`git_hub_action`; pass a bogus one to have it list them. Required options\nbecome flags: `--name` for every type, plus `--group-id`/`--artifact-id`\n(Java) and `--sonar-host-url` (`git_hub_action`). Any other plainly-typed\noption can be passed the same way - `--cdk-deploy-target-repo owner/repo`,\n`--docker-registry ghcr.io`, `--no-use-flyway`, and so on.\n\nCommit the result. From then on, every change to the scaffold goes through\n`.projenrc.ts` followed by `npx projen`:\n\n```bash\nnpx projen\n```\n\nEvery type scaffolds from that one command; no option is *required* that\n`projen new` cannot pass. The structured options - `environments` and\n`GitHubActionProject`'s `dogfood` - are ones projen's CLI cannot render\ninto a projenrc, so they are added afterwards by editing `.projenrc.ts` and\nre-running `npx projen`. Leaving `environments` out simply generates no\ndeploy workflow; leaving `dogfood` out (or a service's\n`cdkDeployTargetRepo`) still generates the workflow, with one step that\nfails and tells you what to add - a gate this package considers load-bearing\nis allowed to be missing loudly, never silently.\n\nThe `name` option must match the `name` field in the project's `package.json` (for the CDK types) or the project name used by projen's `java.JavaProject` (for the Java types).\n\n## Updating an existing project when this package changes\n\nYour generated scaffold reflects the *installed* version of `@xpertss/projen-types` - `npx projen` reads your project type from the package in `node_modules`, not from this repository. So when this package ships a change (a bug fix, a new generated file, or altered workflow behavior), an existing project picks it up by bumping the dependency and re-synthesizing. A stale `node_modules` silently regenerates with the old behavior, so the bump is the load-bearing step.\n\nUsing the [`auto-commit` action](#githubactionproject) as a running example, say a new release adds the `# Purpose:` workflow header and SonarCloud wording. In the `auto-commit` repo:\n\n```bash\nnpm view @xpertss/projen-types version # what's the newest release?\nnpm i -D @xpertss/projen-types@latest # bump the installed project type\nnpx projen # re-synthesize every generated file\ngit diff # review before committing\n```\n\nThe diff here is the workflows gaining a `# Purpose:` comment and `sonar.yml` reflecting the SonarCloud wording. Commit the result with a normal `chore:` or `fix:` message - you never hand-edit the generated files themselves.\n\n## Examples\n\n### CdkInfraProject\n\nPure infrastructure stacks with optional ECR/ECS and edge-networking constructs.\n\nScaffold it with the `cdk_infra` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_infra --name media-edge-infra\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'media-edge-infra',\n environments: [\n 'dev',\n { name: 'stage', accountId: '111111111111', region: 'eu-central-1' },\n { name: 'prod', accountId: '222222222222', region: 'eu-central-1', requiresApproval: true },\n ],\n edgeResources: ['cloudfront', 'route53', 'sqs'],\n ecrEcs: { enabled: true, externalImageSource: true },\n slackWebhookSecret: 'SLACK_DEPLOY_WEBHOOK',\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `cdk.json`, `cdk synth` / `cdk diff` / `cdk deploy` tasks, and the standard `AwsCdkTypeScriptApp` layout (CDK 2.189.1 by default).\n- `.github/workflows/build.yml` - PR build that hard-fails on projen drift.\n- `.github/workflows/deploy.yml` - manual dispatch with one `deploy-<env>` job per environment (runs `cdk deploy --all` with `--context environment=<env>`); `requiresApproval` environments get a GitHub Environment approval gate; a Slack notification step is added when `slackWebhookSecret` is set.\n- `src/constructs/edge-networking.ts` - helper constructs only for the requested `edgeResources` (`cloudfront`, `route53`, `apigateway`, `cognito`, `sqs`).\n- `src/constructs/ecr-ecs.ts` when `ecrEcs.enabled` - ECR repo + Fargate service; `externalImageSource: true` (default) means the service pulls an image built outside this repo.\n\n### CdkAppProject\n\n`CdkInfraProject` plus application source, a database construct, and an app-level build workflow.\n\nScaffold it with the `cdk_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types cdk_app --name video-api\n```\n\n```typescript\n// .projenrc.ts\nimport { CdkAppProject } from '@xpertss/projen-types';\n\nconst project = new CdkAppProject({\n name: 'video-api',\n environments: ['dev', 'prod'],\n edgeResources: ['apigateway'],\n database: { engine: 'postgres', migrationTool: 'flyway' },\n appEntryPoint: 'src/app.ts',\n});\n\nproject.synth();\n```\n\nEverything from `CdkInfraProject`, plus:\n\n- `src/app.ts` - application entrypoint stub (`export function handler()`).\n- `src/handlers/example.ts` - API Gateway proxy handler stub, with `@types/aws-lambda` added as a dev dependency.\n- `src/constructs/database.ts` - a `Database` construct stub for the chosen engine (`postgres`/`mysql` -> RDS, `dynamodb` -> DynamoDB). `migrationTool` (no default, intentionally) is added as a dev dependency and referenced in the stub - wiring it up is left to you.\n- `.github/workflows/app-build.yml` - runs the project's test task on every PR, then checks for projen drift.\n\n### JavaLibraryProject\n\nA reusable Java library published to Maven Central.\n\nScaffold it with the `java_library` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_library --name common-utils --group-id org.xpertss --artifact-id common-utils\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaLibraryProject } from '@xpertss/projen-types';\n\nconst project = new JavaLibraryProject({\n name: 'common-utils',\n groupId: 'org.xpertss',\n artifactId: 'common-utils',\n version: '1.0.0',\n sonarProjectKey: 'org.xpertss:common-utils',\n mavenCentralOidc: true,\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `pom.xml` (via projen's `java.JavaProject`) with the given GAV coordinates.\n- `.github/workflows/build.yml` - PR build + projen drift check, plus a SonarQube scan step when `sonarProjectKey` is set (needs a `SONAR_TOKEN` secret).\n- `.github/workflows/upgrade.yml` - nightly (03:00 UTC) PR running `mvn versions:use-latest-releases versions:update-properties`.\n- `.github/workflows/publish-maven-central.yml` - manual dispatch running `mvn -B deploy -P release`. With `mavenCentralOidc: true` it uses Maven Central's OIDC trusted publishing (no GPG secrets needed); otherwise it expects the secrets `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD`.\n- `.github/workflows/codeindex.yml` - on push to `main`, generates a Java source index under `.cai/` (disable with `publishCodeIndex: false`).\n\n### JavaServiceProject\n\nA Spring Boot service that publishes a Docker image and can trigger deploys in a companion CDK repo.\n\nScaffold it with the `java_service` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_service --name stream-processor --group-id org.xpertss --artifact-id stream-processor\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaServiceProject } from '@xpertss/projen-types';\n\nconst project = new JavaServiceProject({\n name: 'stream-processor',\n groupId: 'org.xpertss',\n artifactId: 'stream-processor',\n dockerRegistry: 'docker.io/xpertss',\n cdkDeployTargetRepo: 'xpertss/stream-infra',\n environments: ['dev', { name: 'prod', requiresApproval: true }],\n});\n\nproject.synth();\n```\n\nYou get (everything from `JavaMavenProject` - `pom.xml`, `build` + drift check, nightly `upgrade` - plus):\n\n- `spring-boot-starter-web` added to the pom.\n- `.github/workflows/publish-docker.yml` - manual dispatch: `mvn -B package && docker build -t <registry>/<name>:<sha>`, logged in with the `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets. `dockerRegistry` defaults to `docker.io`.\n- Flyway wiring when `useFlyway` (default `true`): `flyway-maven-plugin` ^10 + `flyway-core` ^10 in the pom, and `src/main/resources/db/migration/V1__init.sql`.\n- `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, generated by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `cdkDeployTargetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). With no `cdkDeployTargetRepo` set, the workflow is still generated but each job's only step fails with instructions - it is dispatch-only, so that lands on whoever tries to deploy rather than on every PR. Turn the workflow off entirely with `cdkDeployHook: false`. `environments` defaults to `['prod']`.\n\n### JavaAppProject\n\nA GUI/TUI/CLI Java application published to GitHub Packages only - no Maven Central, no Docker, no CDK deploy hook.\n\nScaffold it with the `java_app` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types java_app --name studio-cli --group-id org.xpertss --artifact-id studio-cli\n```\n\n```typescript\n// .projenrc.ts\nimport { JavaAppProject } from '@xpertss/projen-types';\n\nconst project = new JavaAppProject({\n name: 'studio-cli',\n groupId: 'org.xpertss',\n artifactId: 'studio-cli',\n ghPackagesRegistry: 'https://maven.pkg.github.com/xpertss/studio-cli',\n});\n\nproject.synth();\n```\n\nYou get everything from `JavaMavenProject`, plus `.github/workflows/publish-ghpackages.yml` - manual dispatch running `mvn -B deploy -DaltDeploymentRepository=github::<registry>`, authenticated with `GITHUB_TOKEN`. `ghPackagesRegistry` defaults to `https://maven.pkg.github.com/<repo>` derived from the repository URL.\n\n### GitHubActionProject\n\nA reusable GitHub Action or Workflow. This example scaffolds an action that stages a folder and, only if it changed, commits and pushes it.\n\nScaffold it with the `git_hub_action` type:\n\n```bash\nnpx projen new --from @xpertss/projen-types git_hub_action --name auto-commit --sonar-host-url https://sonarcloud.io\n```\n\n```typescript\n// .projenrc.ts\nimport { GitHubActionProject } from '@xpertss/projen-types';\n\nconst project = new GitHubActionProject({\n name: 'auto-commit',\n description: 'Stage a folder and, only if it changed, commit and push it',\n sonarHostUrl: 'https://sonarcloud.io', // required, no default - your SonarCloud URL\n dogfood: {\n // Two scenario steps: the \"changed\" path and the \"no-op\" path are both\n // load-bearing behavior for this action (a double-commit or a\n // push-when-empty bug is the failure mode a hand-rolled inline-shell\n // alternative is most likely to introduce).\n scenario: [\n {\n name: 'Changed path',\n fixtureSteps: [\n 'echo \"$(date -u +%Y%m%dT%H%M%SZ)\" >> test/fixtures/dogfood-state.txt',\n ],\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n // step id defaults to a slug of `name` - here \"changed-path-0\"\n '[ \"${{ steps.changed-path-0.outputs.committed }}\" = \"true\" ]',\n ],\n },\n {\n // No fixture change this time - nothing new to commit.\n name: 'No-op path',\n id: 'no-op-check', // pin an explicit id instead of relying on the default slug\n inputs: {\n commit_message: 'test: dogfood',\n branches: 'test/dogfood',\n },\n assertions: [\n '[ \"${{ steps.no-op-check.outputs.committed }}\" = \"false\" ]',\n ],\n },\n ],\n cleanup: [\n 'git push origin --delete test/dogfood || true',\n ],\n },\n});\n\nproject.synth();\n```\n\nYou get:\n\n- `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.\n- `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` alongside `sonar.yml`.\n- `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: ./`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.\n- `.github/workflows/sonar.yml` - SonarCloud scan via the Scanner CLI (the quality gate blocks the PR), scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly.\n- `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.\n- `.github/workflows/projen-drift-check.yml` and `workflow-change-notice.yml` - drift detection and a change notice, always included.\n- `package.json` (**private**, version source only), `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.\n\nNeeds the same two secrets as everything else in this package: `PROJEN_GITHUB_TOKEN` (used for automated PR comments) and `SONAR_TOKEN` (the Sonar scan). Onboard a brand-new action repo following [Getting started](#getting-started), write the `.projenrc.ts` above, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`.\n\n## Common options\n\nCDK project types (`CdkInfraProjectOptions` / `CdkAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name; must match `package.json` |\n| `cdkVersion` | `2.189.1` | AWS CDK version |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `slackWebhookSecret` | - | GitHub secret with a Slack webhook URL for deploy notifications |\n| `environments` | - (no `deploy` workflow) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |\n| `ecrEcs` | - | `EcrEcsOptions` - `enabled`, `externalImageSource` (default `true`) |\n| `edgeResources` | - | Subset of `cloudfront`, `route53`, `apigateway`, `cognito`, `sqs` |\n| `database` | - (app only) | `DatabaseOptions` - `engine` (`postgres`/`mysql`/`dynamodb`, default `postgres`), `migrationTool` |\n| `appEntryPoint` | `src/app.ts` (app only) | Path of the generated application entrypoint |\n\nJava project types (`JavaLibraryProjectOptions` / `JavaServiceProjectOptions` / `JavaAppProjectOptions`):\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `groupId` | - (required) | Maven group id |\n| `artifactId` | - (required) | Maven artifact id |\n| `version` | `0.1.0` | Maven version |\n| `sonarProjectKey` | - | SonarQube project key; the sonar step is skipped when unset |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n| `cdkDeployTargetRepo` | - (service only; `deploy-cdk.yml` fails until set) | Companion CDK repo (`owner/repo`) whose `deploy.yml` the deploy hook dispatches |\n| `cdkDeployHook` | `true` (service only) | Whether to generate `deploy-cdk.yml` at all |\n| `dockerRegistry` | `docker.io` (service only) | Registry the Docker image is pushed to |\n| `useFlyway` | `true` (service only) | Flyway plugin/dependency + `V1__init.sql` |\n\n`EnvironmentOptions` for deploy targets:\n\n```text\ninterface EnvironmentOptions {\n readonly name: string; // e.g. \"dev\", \"stage\", \"prod\"\n readonly accountId?: string; // AWS account id (CDK deploys)\n readonly region?: string; // AWS region (CDK deploys)\n readonly requiresApproval?: boolean; // GitHub Environment approval gate (default false)\n}\n```\n\nPlain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.\n\n`GitHubActionProjectOptions`:\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `name` | - (required) | Project name |\n| `description` | - | One-line description; used in the default README template and recorded in the private `package.json` |\n| `sonarHostUrl` | - (required) | URL of your SonarCloud instance (e.g. `https://sonarcloud.io`); must be reachable from github.com-hosted runners |\n| `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |\n| `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |\n| `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: ./` |\n| `license` | `MIT` | SPDX identifier for the generated `LICENSE` |\n| `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |\n\n`ActionDogfoodOptions`/`ActionDogfoodStep` - the dogfood scenario (`test-dogfood.yml`):\n\n```text\ninterface ActionDogfoodOptions {\n readonly scenario: ActionDogfoodStep[]; // one or more, run in order - required\n readonly cleanup: string[]; // shared, run once at the end with `if: always()` - required\n}\n\ninterface ActionDogfoodStep {\n readonly name: string; // labels this step-group's generated workflow steps\n readonly id?: string; // step id for the `uses: ./` call; default: a slug of `name`\n readonly fixtureSteps?: string[]; // shell, before the invocation (default: none)\n readonly inputs?: Record<string, string>; // `with:` for this invocation (default: none)\n readonly assertions: string[]; // shell, after the invocation - required, job fails unless all exit 0\n}\n```\n\nMost actions need exactly one `scenario` step. Actions with a re-run/no-op/idempotency behavior to verify (e.g. `auto-commit`'s no-op-on-no-change path, `create-pull-request`'s reuse-the-PR path) declare two - the second typically omits `fixtureSteps` so its invocation sees no new state, and its assertion checks the opposite outcome of the first. Reference an invocation's own outputs from a later assertion via `${{ steps.<id>.outputs.<name> }}`, using either the default slug or an explicit `id`.\n\n## Required GitHub secrets\n\n| Secret | Used by | Notes |\n| --- | --- | --- |\n| `PROJEN_GITHUB_TOKEN` | all types | PAT for projen's self-mutation/automation; override via `gheTokenSecret` |\n| `SONAR_TOKEN` | Java types with `sonarProjectKey`; `GitHubActionProject` | SonarQube scan step in `build.yml` / `sonar.yml`; override via `sonarTokenSecret` on `GitHubActionProject` |\n| `DOCKER_USERNAME` / `DOCKER_PASSWORD` | `JavaServiceProject` | Docker image push |\n| `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD` | `JavaLibraryProject` without `mavenCentralOidc` | Not needed with OIDC trusted publishing |\n| (your Slack webhook secret) | CDK types with `slackWebhookSecret` | Deploy notifications |\n\n## Customizing `.gitignore`\n\nEvery project type already ignores JetBrains IDE state (`/.idea/*`). To ignore more, call the inherited `addGitIgnore()` method after constructing the project in your `.projenrc.ts`:\n\n```typescript\n// .projenrc.ts\nimport { CdkInfraProject } from '@xpertss/projen-types';\n\nconst project = new CdkInfraProject({\n name: 'my-infra',\n});\n\nproject.addGitIgnore('*.log');\nproject.addGitIgnore('.env.*');\nproject.addGitIgnore('/build/');\n\nproject.synth();\n```\n\nThe same works for every type - just swap the class (e.g. `JavaServiceProject`, `GitHubActionProject`). Each call takes one standard gitignore glob pattern. There is no `gitignore` constructor option: the project types' option interfaces do not expose one, so patterns go through `addGitIgnore()` instead.\n\nRe-run `npx projen` after editing - `.gitignore` is a generated file, so hand-editing it is caught by the drift check.\n\n## Going further\n\nThe project types are composed from smaller components you can also attach to your own projects:\n\n| Component | Applies to | Purpose |\n| --- | --- | --- |\n| `AppRuntimeScaffold` | `NodeProject` | App source skeleton (`app.ts` + handlers) |\n| `DatabaseComponent` | `NodeProject` | Database construct stub + migration tool wiring |\n| `EcrEcsConstructs` | `Project` | ECR + Fargate ECS construct helper |\n| `EdgeNetworkingConstructs` | `Project` | Per-resource edge networking construct helpers |\n| `MavenCentralPublish` | `JavaProject` | Manual-dispatch Maven Central publish workflow |\n| `DockerPublish` | `JavaProject` | Manual-dispatch Docker build+push workflow |\n| `GitHubPackagesPublish` | `JavaProject` | Manual-dispatch GitHub Packages publish workflow |\n| `FlywayMigration` | `JavaProject` | Flyway plugin/dependency + migrations directory |\n| `CdkDeployHook` | `JavaProject` | Manual-dispatch workflow that triggers `deploy.yml` in a companion CDK repo |\n| `CodeIndexWorkflow` | `JavaProject` | Code index generation on push to `main` |\n| `ActionBuildWorkflow` | `GitHubProject` | The `lint` task (shellcheck/yamllint/pinned actionlint) + `build.yml` |\n| `ActionDogfoodWorkflow` | `GitHubProject` | `test-dogfood.yml` from an `ActionDogfoodOptions` scenario |\n| `ActionSonarWorkflow` | `GitHubProject` | `sonar.yml` (SonarCloud scan via the Scanner CLI) |\n\nExample - adding a Docker publish to a plain projen `JavaProject`:\n\n```typescript\nimport { java } from 'projen';\nimport { DockerPublish } from '@xpertss/projen-types';\n\nconst project = new java.JavaProject({\n name: 'my-service',\n groupId: 'org.xpertss',\n artifactId: 'my-service',\n});\n\nnew DockerPublish(project, { dockerRegistry: 'ghcr.io' });\n\nproject.synth();\n```\n\nThe full API reference, including every option and property, is in [API.md](./API.md).\n"
110
110
  },
111
111
  "repository": {
112
112
  "type": "git",
@@ -247,7 +247,7 @@
247
247
  "datatype": true,
248
248
  "docs": {
249
249
  "stability": "experimental",
250
- "summary": "One invocation of the action within the dogfood scenario: optional fixture setup, the `uses: .` call with this step's inputs, then this step's assertions. Most actions need exactly one; actions with a re-run/no-op behavior to verify (e.g. F006's reuse-the-PR path, F007's no-op-commit path) declare two."
250
+ "summary": "One invocation of the action within the dogfood scenario: optional fixture setup, the `uses: ./` call with this step's inputs, then this step's assertions. Most actions need exactly one; actions with a re-run/no-op behavior to verify (e.g. F006's reuse-the-PR path, F007's no-op-commit path) declare two."
251
251
  },
252
252
  "fqn": "@xpertss/projen-types.ActionDogfoodStep",
253
253
  "kind": "interface",
@@ -322,7 +322,7 @@
322
322
  "docs": {
323
323
  "default": "- a slug derived from `name`, disambiguated by position",
324
324
  "stability": "experimental",
325
- "summary": "Step id for the `uses: .` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`."
325
+ "summary": "Step id for the `uses: ./` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`."
326
326
  },
327
327
  "immutable": true,
328
328
  "locationInModule": {
@@ -340,7 +340,7 @@
340
340
  "docs": {
341
341
  "default": "{}",
342
342
  "stability": "experimental",
343
- "summary": "`with:` inputs for this invocation's local `uses: .` call."
343
+ "summary": "`with:` inputs for this invocation's local `uses: ./` call."
344
344
  },
345
345
  "immutable": true,
346
346
  "locationInModule": {
@@ -367,7 +367,7 @@
367
367
  "docs": {
368
368
  "remarks": "Omitting `options` generates the workflow with a single failing step (see\n`UNCONFIGURED_STEPS`). A *partially* declared dogfood is still a synth\nerror: if you wrote a scenario by hand, you can write its cleanup too.",
369
369
  "stability": "experimental",
370
- "summary": "Per AD-001's dogfood test: the composite action is run **against this repo**, end-to-end, via a local `uses: .` reference - no external harness. Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps (see `ActionDogfoodStep`) followed by a shared cleanup step."
370
+ "summary": "Per AD-001's dogfood test: the composite action is run **against this repo**, end-to-end, via a local `uses: ./` reference - no external harness. Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps (see `ActionDogfoodStep`) followed by a shared cleanup step."
371
371
  },
372
372
  "fqn": "@xpertss/projen-types.ActionDogfoodWorkflow",
373
373
  "initializer": {
@@ -2631,6 +2631,6 @@
2631
2631
  "symbolId": "src/common/workflow-change-notice-workflow:WorkflowChangeNoticeWorkflowOptions"
2632
2632
  }
2633
2633
  },
2634
- "version": "0.0.12",
2635
- "fingerprint": "lk0vEhtStEKqxFZK4iPE2+7zS+gMZuy8LsBForNtypg="
2634
+ "version": "0.0.13",
2635
+ "fingerprint": "AxsRe54Gs4ErbSVILQsB2XaRdXp6lwSlghS1nKZ0bOw="
2636
2636
  }
package/API.md CHANGED
@@ -256,7 +256,7 @@ public readonly workflow: TaskWorkflow;
256
256
 
257
257
  ### ActionDogfoodWorkflow <a name="ActionDogfoodWorkflow" id="@xpertss/projen-types.ActionDogfoodWorkflow"></a>
258
258
 
259
- Per AD-001's dogfood test: the composite action is run **against this repo**, end-to-end, via a local `uses: .` reference - no external harness. Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps (see `ActionDogfoodStep`) followed by a shared cleanup step.
259
+ Per AD-001's dogfood test: the composite action is run **against this repo**, end-to-end, via a local `uses: ./` reference - no external harness. Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps (see `ActionDogfoodStep`) followed by a shared cleanup step.
260
260
 
261
261
  Omitting `options` generates the workflow with a single failing step (see
262
262
  `UNCONFIGURED_STEPS`). A *partially* declared dogfood is still a synth
@@ -12647,7 +12647,7 @@ One or more scenario steps, run in order, in the dogfood job.
12647
12647
 
12648
12648
  ### ActionDogfoodStep <a name="ActionDogfoodStep" id="@xpertss/projen-types.ActionDogfoodStep"></a>
12649
12649
 
12650
- One invocation of the action within the dogfood scenario: optional fixture setup, the `uses: .` call with this step's inputs, then this step's assertions. Most actions need exactly one; actions with a re-run/no-op behavior to verify (e.g. F006's reuse-the-PR path, F007's no-op-commit path) declare two.
12650
+ One invocation of the action within the dogfood scenario: optional fixture setup, the `uses: ./` call with this step's inputs, then this step's assertions. Most actions need exactly one; actions with a re-run/no-op behavior to verify (e.g. F006's reuse-the-PR path, F007's no-op-commit path) declare two.
12651
12651
 
12652
12652
  #### Initializer <a name="Initializer" id="@xpertss/projen-types.ActionDogfoodStep.Initializer"></a>
12653
12653
 
@@ -12664,8 +12664,8 @@ const actionDogfoodStep: ActionDogfoodStep = { ... }
12664
12664
  | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.assertions">assertions</a></code> | <code>string[]</code> | Shell assertions after this invocation - the job fails unless every one exits 0. |
12665
12665
  | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.name">name</a></code> | <code>string</code> | Label used to name this step-group's generated workflow steps. |
12666
12666
  | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.fixtureSteps">fixtureSteps</a></code> | <code>string[]</code> | Shell steps executed before this invocation, to produce or alter fixture state. |
12667
- | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.id">id</a></code> | <code>string</code> | Step id for the `uses: .` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`. |
12668
- | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.inputs">inputs</a></code> | <code>{[ key: string ]: string}</code> | `with:` inputs for this invocation's local `uses: .` call. |
12667
+ | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.id">id</a></code> | <code>string</code> | Step id for the `uses: ./` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`. |
12668
+ | <code><a href="#@xpertss/projen-types.ActionDogfoodStep.property.inputs">inputs</a></code> | <code>{[ key: string ]: string}</code> | `with:` inputs for this invocation's local `uses: ./` call. |
12669
12669
 
12670
12670
  ---
12671
12671
 
@@ -12715,7 +12715,7 @@ public readonly id: string;
12715
12715
  - *Type:* string
12716
12716
  - *Default:* a slug derived from `name`, disambiguated by position
12717
12717
 
12718
- Step id for the `uses: .` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`.
12718
+ Step id for the `uses: ./` invocation, so a later assertion can reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`.
12719
12719
 
12720
12720
  ---
12721
12721
 
@@ -12728,7 +12728,7 @@ public readonly inputs: {[ key: string ]: string};
12728
12728
  - *Type:* {[ key: string ]: string}
12729
12729
  - *Default:* {}
12730
12730
 
12731
- `with:` inputs for this invocation's local `uses: .` call.
12731
+ `with:` inputs for this invocation's local `uses: ./` call.
12732
12732
 
12733
12733
  ---
12734
12734
 
package/README.md CHANGED
@@ -82,6 +82,12 @@ The diff here is the workflows gaining a `# Purpose:` comment and `sonar.yml` re
82
82
 
83
83
  Pure infrastructure stacks with optional ECR/ECS and edge-networking constructs.
84
84
 
85
+ Scaffold it with the `cdk_infra` type:
86
+
87
+ ```bash
88
+ npx projen new --from @xpertss/projen-types cdk_infra --name media-edge-infra
89
+ ```
90
+
85
91
  ```typescript
86
92
  // .projenrc.ts
87
93
  import { CdkInfraProject } from '@xpertss/projen-types';
@@ -113,6 +119,12 @@ You get:
113
119
 
114
120
  `CdkInfraProject` plus application source, a database construct, and an app-level build workflow.
115
121
 
122
+ Scaffold it with the `cdk_app` type:
123
+
124
+ ```bash
125
+ npx projen new --from @xpertss/projen-types cdk_app --name video-api
126
+ ```
127
+
116
128
  ```typescript
117
129
  // .projenrc.ts
118
130
  import { CdkAppProject } from '@xpertss/projen-types';
@@ -139,6 +151,12 @@ Everything from `CdkInfraProject`, plus:
139
151
 
140
152
  A reusable Java library published to Maven Central.
141
153
 
154
+ Scaffold it with the `java_library` type:
155
+
156
+ ```bash
157
+ npx projen new --from @xpertss/projen-types java_library --name common-utils --group-id org.xpertss --artifact-id common-utils
158
+ ```
159
+
142
160
  ```typescript
143
161
  // .projenrc.ts
144
162
  import { JavaLibraryProject } from '@xpertss/projen-types';
@@ -167,6 +185,12 @@ You get:
167
185
 
168
186
  A Spring Boot service that publishes a Docker image and can trigger deploys in a companion CDK repo.
169
187
 
188
+ Scaffold it with the `java_service` type:
189
+
190
+ ```bash
191
+ npx projen new --from @xpertss/projen-types java_service --name stream-processor --group-id org.xpertss --artifact-id stream-processor
192
+ ```
193
+
170
194
  ```typescript
171
195
  // .projenrc.ts
172
196
  import { JavaServiceProject } from '@xpertss/projen-types';
@@ -194,6 +218,12 @@ You get (everything from `JavaMavenProject` - `pom.xml`, `build` + drift check,
194
218
 
195
219
  A GUI/TUI/CLI Java application published to GitHub Packages only - no Maven Central, no Docker, no CDK deploy hook.
196
220
 
221
+ Scaffold it with the `java_app` type:
222
+
223
+ ```bash
224
+ npx projen new --from @xpertss/projen-types java_app --name studio-cli --group-id org.xpertss --artifact-id studio-cli
225
+ ```
226
+
197
227
  ```typescript
198
228
  // .projenrc.ts
199
229
  import { JavaAppProject } from '@xpertss/projen-types';
@@ -214,6 +244,12 @@ You get everything from `JavaMavenProject`, plus `.github/workflows/publish-ghpa
214
244
 
215
245
  A reusable GitHub Action or Workflow. This example scaffolds an action that stages a folder and, only if it changed, commits and pushes it.
216
246
 
247
+ Scaffold it with the `git_hub_action` type:
248
+
249
+ ```bash
250
+ npx projen new --from @xpertss/projen-types git_hub_action --name auto-commit --sonar-host-url https://sonarcloud.io
251
+ ```
252
+
217
253
  ```typescript
218
254
  // .projenrc.ts
219
255
  import { GitHubActionProject } from '@xpertss/projen-types';
@@ -268,7 +304,7 @@ You get:
268
304
 
269
305
  - `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.
270
306
  - `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` alongside `sonar.yml`.
271
- - `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: .`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.
307
+ - `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: ./`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.
272
308
  - `.github/workflows/sonar.yml` - SonarCloud scan via the Scanner CLI (the quality gate blocks the PR), scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly.
273
309
  - `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.
274
310
  - `.github/workflows/projen-drift-check.yml` and `workflow-change-notice.yml` - drift detection and a change notice, always included.
@@ -329,7 +365,7 @@ Plain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.
329
365
  | `sonarHostUrl` | - (required) | URL of your SonarCloud instance (e.g. `https://sonarcloud.io`); must be reachable from github.com-hosted runners |
330
366
  | `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |
331
367
  | `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |
332
- | `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: .` |
368
+ | `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: ./` |
333
369
  | `license` | `MIT` | SPDX identifier for the generated `LICENSE` |
334
370
  | `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |
335
371
 
@@ -343,7 +379,7 @@ interface ActionDogfoodOptions {
343
379
 
344
380
  interface ActionDogfoodStep {
345
381
  readonly name: string; // labels this step-group's generated workflow steps
346
- readonly id?: string; // step id for the `uses: .` call; default: a slug of `name`
382
+ readonly id?: string; // step id for the `uses: ./` call; default: a slug of `name`
347
383
  readonly fixtureSteps?: string[]; // shell, before the invocation (default: none)
348
384
  readonly inputs?: Record<string, string>; // `with:` for this invocation (default: none)
349
385
  readonly assertions: string[]; // shell, after the invocation - required, job fails unless all exit 0
@@ -362,6 +398,29 @@ Most actions need exactly one `scenario` step. Actions with a re-run/no-op/idemp
362
398
  | `MAVEN_GPG_PRIVATE_KEY`, `MAVEN_GPG_PASSPHRASE`, `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD` | `JavaLibraryProject` without `mavenCentralOidc` | Not needed with OIDC trusted publishing |
363
399
  | (your Slack webhook secret) | CDK types with `slackWebhookSecret` | Deploy notifications |
364
400
 
401
+ ## Customizing `.gitignore`
402
+
403
+ Every project type already ignores JetBrains IDE state (`/.idea/*`). To ignore more, call the inherited `addGitIgnore()` method after constructing the project in your `.projenrc.ts`:
404
+
405
+ ```typescript
406
+ // .projenrc.ts
407
+ import { CdkInfraProject } from '@xpertss/projen-types';
408
+
409
+ const project = new CdkInfraProject({
410
+ name: 'my-infra',
411
+ });
412
+
413
+ project.addGitIgnore('*.log');
414
+ project.addGitIgnore('.env.*');
415
+ project.addGitIgnore('/build/');
416
+
417
+ project.synth();
418
+ ```
419
+
420
+ The same works for every type - just swap the class (e.g. `JavaServiceProject`, `GitHubActionProject`). Each call takes one standard gitignore glob pattern. There is no `gitignore` constructor option: the project types' option interfaces do not expose one, so patterns go through `addGitIgnore()` instead.
421
+
422
+ Re-run `npx projen` after editing - `.gitignore` is a generated file, so hand-editing it is caught by the drift check.
423
+
365
424
  ## Going further
366
425
 
367
426
  The project types are composed from smaller components you can also attach to your own projects:
@@ -20,7 +20,7 @@ const ACTIONLINT_SHA256 = '8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc
20
20
  * the release build job, so the lint commands exist in exactly one place.
21
21
  */
22
22
  class ActionBuildWorkflow extends projen_1.Component {
23
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionBuildWorkflow", version: "0.0.12" };
23
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionBuildWorkflow", version: "0.0.13" };
24
24
  task;
25
25
  workflow;
26
26
  constructor(scope) {
@@ -1,7 +1,7 @@
1
1
  import { Component, github } from 'projen';
2
2
  /**
3
3
  * One invocation of the action within the dogfood scenario: optional fixture
4
- * setup, the `uses: .` call with this step's inputs, then this step's
4
+ * setup, the `uses: ./` call with this step's inputs, then this step's
5
5
  * assertions. Most actions need exactly one; actions with a re-run/no-op
6
6
  * behavior to verify (e.g. F006's reuse-the-PR path, F007's no-op-commit
7
7
  * path) declare two.
@@ -10,7 +10,7 @@ export interface ActionDogfoodStep {
10
10
  /** Label used to name this step-group's generated workflow steps. */
11
11
  readonly name: string;
12
12
  /**
13
- * Step id for the `uses: .` invocation, so a later assertion can
13
+ * Step id for the `uses: ./` invocation, so a later assertion can
14
14
  * reference this step's outputs via `${{ steps.<id>.outputs.<name> }}`.
15
15
  * @default - a slug derived from `name`, disambiguated by position
16
16
  */
@@ -22,7 +22,7 @@ export interface ActionDogfoodStep {
22
22
  */
23
23
  readonly fixtureSteps?: string[];
24
24
  /**
25
- * `with:` inputs for this invocation's local `uses: .` call.
25
+ * `with:` inputs for this invocation's local `uses: ./` call.
26
26
  * @default {}
27
27
  */
28
28
  readonly inputs?: Record<string, string>;
@@ -37,7 +37,7 @@ export interface ActionDogfoodOptions {
37
37
  }
38
38
  /**
39
39
  * Per AD-001's dogfood test: the composite action is run **against this
40
- * repo**, end-to-end, via a local `uses: .` reference - no external harness.
40
+ * repo**, end-to-end, via a local `uses: ./` reference - no external harness.
41
41
  * Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps
42
42
  * (see `ActionDogfoodStep`) followed by a shared cleanup step.
43
43
  *
@@ -32,7 +32,7 @@ const UNCONFIGURED_STEPS = [
32
32
  ];
33
33
  /**
34
34
  * Per AD-001's dogfood test: the composite action is run **against this
35
- * repo**, end-to-end, via a local `uses: .` reference - no external harness.
35
+ * repo**, end-to-end, via a local `uses: ./` reference - no external harness.
36
36
  * Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps
37
37
  * (see `ActionDogfoodStep`) followed by a shared cleanup step.
38
38
  *
@@ -41,7 +41,7 @@ const UNCONFIGURED_STEPS = [
41
41
  * error: if you wrote a scenario by hand, you can write its cleanup too.
42
42
  */
43
43
  class ActionDogfoodWorkflow extends projen_1.Component {
44
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionDogfoodWorkflow", version: "0.0.12" };
44
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionDogfoodWorkflow", version: "0.0.13" };
45
45
  workflow;
46
46
  constructor(scope, options) {
47
47
  super(scope, 'ActionDogfoodWorkflow');
@@ -76,7 +76,7 @@ class ActionDogfoodWorkflow extends projen_1.Component {
76
76
  steps.push({
77
77
  id: step.id ?? slug(step.name, index),
78
78
  name: `${step.name}: run the action`,
79
- uses: '.',
79
+ uses: './',
80
80
  ...(hasInputs ? { with: step.inputs } : {}),
81
81
  });
82
82
  steps.push({
@@ -113,4 +113,4 @@ class ActionDogfoodWorkflow extends projen_1.Component {
113
113
  }
114
114
  }
115
115
  exports.ActionDogfoodWorkflow = ActionDogfoodWorkflow;
116
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWRvZ2Zvb2Qtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWN0aW9ucy9hY3Rpb24tZG9nZm9vZC13b3JrZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsbUNBQTJDO0FBQzNDLGlFQUFpRTtBQUVqRSx3RUFBd0U7QUFDeEUsMEVBQTBFO0FBQzFFLHFFQUFxRTtBQUNyRSxvREFBb0Q7QUFDcEQsTUFBTSx3QkFBd0IsR0FBRyxZQUFZLENBQUM7QUFxQzlDLHlFQUF5RTtBQUN6RSx1RUFBdUU7QUFDdkUsOENBQThDO0FBQzlDLFNBQVMsSUFBSSxDQUFDLElBQVksRUFBRSxLQUFhO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLElBQUk7U0FDZCxXQUFXLEVBQUU7U0FDYixPQUFPLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQztTQUMzQixPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzNCLE9BQU8sR0FBRyxJQUFJLElBQUksTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO0FBQ3RDLENBQUM7QUFVRCx5RUFBeUU7QUFDekUsb0VBQW9FO0FBQ3BFLDRFQUE0RTtBQUM1RSwwRUFBMEU7QUFDMUUsNEVBQTRFO0FBQzVFLHNEQUFzRDtBQUN0RCxNQUFNLGtCQUFrQixHQUFhO0lBQ25DLDBGQUEwRjtJQUMxRixvSUFBb0k7SUFDcEksUUFBUTtDQUNULENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFhLHFCQUFzQixTQUFRLGtCQUFTOztJQUNsQyxRQUFRLENBQXdCO0lBRWhELFlBQVksS0FBMkIsRUFBRSxPQUE4QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFFdEMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxDQUNwRSxDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNSLE1BQU0sSUFBSSxLQUFLLENBQ2IsaUVBQWlFLENBQ2xFLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQStCLE9BQU87WUFDL0MsQ0FBQyxDQUFDLENBQUMsZUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNuQyxDQUFDLENBQUM7Z0JBQ0E7b0JBQ0UsSUFBSSxFQUFFLGlDQUFpQztvQkFDdkMsR0FBRyxFQUFFLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7aUJBQ25DO2FBQ0YsQ0FBQztRQUVKLENBQUMsT0FBTyxFQUFFLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEQsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN0RCxLQUFLLENBQUMsSUFBSSxDQUFDO29CQUNULElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLFdBQVc7b0JBQzdCLEdBQUcsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7aUJBQ2xDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDckUsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDVCxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUM7Z0JBQ3JDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLGtCQUFrQjtnQkFDcEMsSUFBSSxFQUFFLEdBQUc7Z0JBQ1QsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDNUMsQ0FBQyxDQUFDO1lBRUgsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDVCxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxVQUFVO2dCQUM1QixHQUFHLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ2hDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsRUFBRSxFQUFFLFVBQVU7Z0JBQ2QsR0FBRyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzthQUNoQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGVBQU0sQ0FBQyxjQUFjLENBQUMsRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzlELElBQUEsc0NBQW1CLEVBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUNsQiwrREFBK0QsQ0FDaEUsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ2YsZ0JBQWdCLEVBQUUsRUFBRTtZQUNwQixXQUFXLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNuQyxzRUFBc0U7WUFDdEUsc0VBQXNFO1lBQ3RFLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsd0JBQXdCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUN2RSxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7WUFDOUIsTUFBTSxFQUFFLENBQUMsZUFBZSxDQUFDO1lBQ3pCLFdBQVcsRUFBRSxPQUFPO2dCQUNsQixDQUFDLENBQUM7b0JBQ0EsUUFBUSxFQUFFLGVBQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUs7b0JBQzlDLFlBQVksRUFBRSxlQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLO2lCQUNuRDtnQkFDRCxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsZUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFO1lBQ3JELEtBQUs7U0FDTixDQUFDLENBQUM7SUFDTCxDQUFDOztBQXJGSCxzREFzRkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGdpdGh1YiB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBub3RlV29ya2Zsb3dQdXJwb3NlIH0gZnJvbSAnLi4vY29tbW9uL3dvcmtmbG93LXB1cnBvc2UnO1xuXG4vLyBOaWdodGx5IGVudmlyb25tZW50LXJlZ3Jlc3Npb24gY2FuYXJ5IChBRC0wMDEvRjAwNik6IHJlLXJ1bnMgdGhlIHNhbWVcbi8vIHNjZW5hcmlvIGFnYWluc3Qgc2V0dGxlZCBgbWFpbmAgaW4gdG9kYXkncyBydW5uZXIgaW1hZ2UsIGluZGVwZW5kZW50IG9mXG4vLyB0aGUgcHVsbF9yZXF1ZXN0IGdhdGUuIFF1aWV0IFVUQyBob3VyOyBhIGNvbXBvbmVudCBjb25zdGFudCwgbm90IGFcbi8vIHByb2plY3Qgb3B0aW9uIC0gdXBncmFkaW5nIGl0IGlzIGEgcmV2aWV3ZWQgZGlmZi5cbmNvbnN0IE5JR0hUTFlfRE9HRk9PRF9TQ0hFRFVMRSA9ICcxNyAzICogKiAqJztcblxuLyoqXG4gKiBPbmUgaW52b2NhdGlvbiBvZiB0aGUgYWN0aW9uIHdpdGhpbiB0aGUgZG9nZm9vZCBzY2VuYXJpbzogb3B0aW9uYWwgZml4dHVyZVxuICogc2V0dXAsIHRoZSBgdXNlczogLmAgY2FsbCB3aXRoIHRoaXMgc3RlcCdzIGlucHV0cywgdGhlbiB0aGlzIHN0ZXAnc1xuICogYXNzZXJ0aW9ucy4gTW9zdCBhY3Rpb25zIG5lZWQgZXhhY3RseSBvbmU7IGFjdGlvbnMgd2l0aCBhIHJlLXJ1bi9uby1vcFxuICogYmVoYXZpb3IgdG8gdmVyaWZ5IChlLmcuIEYwMDYncyByZXVzZS10aGUtUFIgcGF0aCwgRjAwNydzIG5vLW9wLWNvbW1pdFxuICogcGF0aCkgZGVjbGFyZSB0d28uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRG9nZm9vZFN0ZXAge1xuICAvKiogTGFiZWwgdXNlZCB0byBuYW1lIHRoaXMgc3RlcC1ncm91cCdzIGdlbmVyYXRlZCB3b3JrZmxvdyBzdGVwcy4gKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdGVwIGlkIGZvciB0aGUgYHVzZXM6IC5gIGludm9jYXRpb24sIHNvIGEgbGF0ZXIgYXNzZXJ0aW9uIGNhblxuICAgKiByZWZlcmVuY2UgdGhpcyBzdGVwJ3Mgb3V0cHV0cyB2aWEgYCR7eyBzdGVwcy48aWQ+Lm91dHB1dHMuPG5hbWU+IH19YC5cbiAgICogQGRlZmF1bHQgLSBhIHNsdWcgZGVyaXZlZCBmcm9tIGBuYW1lYCwgZGlzYW1iaWd1YXRlZCBieSBwb3NpdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgaWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNoZWxsIHN0ZXBzIGV4ZWN1dGVkIGJlZm9yZSB0aGlzIGludm9jYXRpb24sIHRvIHByb2R1Y2Ugb3IgYWx0ZXJcbiAgICogZml4dHVyZSBzdGF0ZS5cbiAgICogQGRlZmF1bHQgW11cbiAgICovXG4gIHJlYWRvbmx5IGZpeHR1cmVTdGVwcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBgd2l0aDpgIGlucHV0cyBmb3IgdGhpcyBpbnZvY2F0aW9uJ3MgbG9jYWwgYHVzZXM6IC5gIGNhbGwuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqL1xuICByZWFkb25seSBpbnB1dHM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKiBTaGVsbCBhc3NlcnRpb25zIGFmdGVyIHRoaXMgaW52b2NhdGlvbiAtIHRoZSBqb2IgZmFpbHMgdW5sZXNzIGV2ZXJ5IG9uZSBleGl0cyAwLiAqL1xuICByZWFkb25seSBhc3NlcnRpb25zOiBzdHJpbmdbXTtcbn1cblxuLy8gTG93ZXJjYXNlLCBub24tYWxwaGFudW1lcmljcyBjb2xsYXBzZWQgdG8gYSBzaW5nbGUgYC1gLCB0cmltbWVkIC0gdGhlblxuLy8gZGlzYW1iaWd1YXRlZCBieSBwb3NpdGlvbiBzbyB0d28gc3RlcHMgc2hhcmluZyBhIG5hbWUgKG9yIGFuIHVubmFtZWRcbi8vIHNsdWcsIGUuZy4gcHVuY3R1YXRpb24tb25seSkgbmV2ZXIgY29sbGlkZS5cbmZ1bmN0aW9uIHNsdWcobmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgYmFzZSA9IG5hbWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csICctJylcbiAgICAucmVwbGFjZSgvXi0rfC0rJC9nLCAnJyk7XG4gIHJldHVybiBgJHtiYXNlIHx8ICdzdGVwJ30tJHtpbmRleH1gO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjdGlvbkRvZ2Zvb2RPcHRpb25zIHtcbiAgLyoqIE9uZSBvciBtb3JlIHNjZW5hcmlvIHN0ZXBzLCBydW4gaW4gb3JkZXIsIGluIHRoZSBkb2dmb29kIGpvYi4gKi9cbiAgcmVhZG9ubHkgc2NlbmFyaW86IEFjdGlvbkRvZ2Zvb2RTdGVwW107XG5cbiAgLyoqIFNoZWxsIGNsZWFudXAsIHJ1biBvbmNlIGF0IHRoZSBlbmQgd2l0aCBgaWY6IGFsd2F5cygpYCwgc28gcmVwZWF0ZWQgcnVucyBzdGFydCBjbGVhbi4gKi9cbiAgcmVhZG9ubHkgY2xlYW51cDogc3RyaW5nW107XG59XG5cbi8vIFRoZSBzdGFuZC1pbiBzY2VuYXJpbyB1c2VkIHdoZW4gYSBwcm9qZWN0IGRlY2xhcmVzIG5vIGBkb2dmb29kYCBhdCBhbGxcbi8vIChlLmcuIGEgcmVwbyBgcHJvamVuIG5ld2AganVzdCBzY2FmZm9sZGVkKS4gVGhlIHdvcmtmbG93IGlzIHN0aWxsXG4vLyBnZW5lcmF0ZWQgYW5kIHN0aWxsIHJ1bnMgb24gZXZlcnkgUFIgLSBpdCBqdXN0IGZhaWxzLCB0ZWxsaW5nIHlvdSB3aGF0IHRvXG4vLyB3cml0ZS4gQUQtMDAxJ3MgcnVsZSBpcyB0aGF0IGEgZG9nZm9vZCBtdXN0IG5ldmVyIGJlICpzaWxlbnRseSogYWJzZW50O1xuLy8gdGhyb3dpbmcgZHVyaW5nIHN5bnRoIGluc3RlYWQgd291bGQgbWFrZSB0aGUgcHJvamVjdCB0eXBlIHVuc2NhZmZvbGRhYmxlLFxuLy8gc2luY2UgYHByb2plbiBuZXdgIGhhcyBubyB3YXkgdG8gc3VwcGx5IGEgc2NlbmFyaW8uXG5jb25zdCBVTkNPTkZJR1VSRURfU1RFUFM6IHN0cmluZ1tdID0gW1xuICAnZWNobyBcIjo6ZXJyb3I6OnRoaXMgYWN0aW9uIGhhcyBubyBkb2dmb29kIHNjZW5hcmlvLCBzbyBub3RoaW5nIGV4ZXJjaXNlcyBpdCBlbmQtdG8tZW5kLlwiJyxcbiAgJ2VjaG8gXCJBZGQgZG9nZm9vZDogeyBzY2VuYXJpbzogWy4uLl0sIGNsZWFudXA6IFsuLi5dIH0gdG8gLnByb2plbnJjLnRzIGFuZCBydW4gbnB4IHByb2plbiAtIHNlZSB0aGUgQHhwZXJ0c3MvcHJvamVuLXR5cGVzIFJFQURNRS5cIicsXG4gICdleGl0IDEnLFxuXTtcblxuLyoqXG4gKiBQZXIgQUQtMDAxJ3MgZG9nZm9vZCB0ZXN0OiB0aGUgY29tcG9zaXRlIGFjdGlvbiBpcyBydW4gKiphZ2FpbnN0IHRoaXNcbiAqIHJlcG8qKiwgZW5kLXRvLWVuZCwgdmlhIGEgbG9jYWwgYHVzZXM6IC5gIHJlZmVyZW5jZSAtIG5vIGV4dGVybmFsIGhhcm5lc3MuXG4gKiBCdWlsZHMgYHRlc3QtZG9nZm9vZC55bWxgIGZyb20gYW4gb3JkZXJlZCBgc2NlbmFyaW9gIG9mIGludm9jYXRpb24gc3RlcHNcbiAqIChzZWUgYEFjdGlvbkRvZ2Zvb2RTdGVwYCkgZm9sbG93ZWQgYnkgYSBzaGFyZWQgY2xlYW51cCBzdGVwLlxuICpcbiAqIE9taXR0aW5nIGBvcHRpb25zYCBnZW5lcmF0ZXMgdGhlIHdvcmtmbG93IHdpdGggYSBzaW5nbGUgZmFpbGluZyBzdGVwIChzZWVcbiAqIGBVTkNPTkZJR1VSRURfU1RFUFNgKS4gQSAqcGFydGlhbGx5KiBkZWNsYXJlZCBkb2dmb29kIGlzIHN0aWxsIGEgc3ludGhcbiAqIGVycm9yOiBpZiB5b3Ugd3JvdGUgYSBzY2VuYXJpbyBieSBoYW5kLCB5b3UgY2FuIHdyaXRlIGl0cyBjbGVhbnVwIHRvby5cbiAqL1xuZXhwb3J0IGNsYXNzIEFjdGlvbkRvZ2Zvb2RXb3JrZmxvdyBleHRlbmRzIENvbXBvbmVudCB7XG4gIHB1YmxpYyByZWFkb25seSB3b3JrZmxvdzogZ2l0aHViLkdpdGh1YldvcmtmbG93O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBnaXRodWIuR2l0SHViUHJvamVjdCwgb3B0aW9ucz86IEFjdGlvbkRvZ2Zvb2RPcHRpb25zKSB7XG4gICAgc3VwZXIoc2NvcGUsICdBY3Rpb25Eb2dmb29kV29ya2Zsb3cnKTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMuc2NlbmFyaW8gfHwgb3B0aW9ucy5zY2VuYXJpby5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdBY3Rpb25Eb2dmb29kV29ya2Zsb3cgcmVxdWlyZXMgYXQgbGVhc3Qgb25lIGRvZ2Zvb2Quc2NlbmFyaW8gc3RlcCcsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIW9wdGlvbnMuY2xlYW51cCB8fCBvcHRpb25zLmNsZWFudXAubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uRG9nZm9vZFdvcmtmbG93IHJlcXVpcmVzIGRvZ2Zvb2QuY2xlYW51cCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGdoID0gc2NvcGUuZ2l0aHViO1xuICAgIGlmICghZ2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0FjdGlvbkRvZ2Zvb2RXb3JrZmxvdyByZXF1aXJlcyBHaXRIdWIgaW50ZWdyYXRpb24gdG8gYmUgZW5hYmxlZCcsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHN0ZXBzOiBnaXRodWIud29ya2Zsb3dzLkpvYlN0ZXBbXSA9IG9wdGlvbnNcbiAgICAgID8gW2dpdGh1Yi5Xb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KCldXG4gICAgICA6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdEb2dmb29kIHNjZW5hcmlvIG5vdCBjb25maWd1cmVkJyxcbiAgICAgICAgICBydW46IFVOQ09ORklHVVJFRF9TVEVQUy5qb2luKCdcXG4nKSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAob3B0aW9ucz8uc2NlbmFyaW8gPz8gW10pLmZvckVhY2goKHN0ZXAsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoc3RlcC5maXh0dXJlU3RlcHMgJiYgc3RlcC5maXh0dXJlU3RlcHMubGVuZ3RoID4gMCkge1xuICAgICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBgJHtzdGVwLm5hbWV9OiBmaXh0dXJlYCxcbiAgICAgICAgICBydW46IHN0ZXAuZml4dHVyZVN0ZXBzLmpvaW4oJ1xcbicpLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaGFzSW5wdXRzID0gc3RlcC5pbnB1dHMgJiYgT2JqZWN0LmtleXMoc3RlcC5pbnB1dHMpLmxlbmd0aCA+IDA7XG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgaWQ6IHN0ZXAuaWQgPz8gc2x1ZyhzdGVwLm5hbWUsIGluZGV4KSxcbiAgICAgICAgbmFtZTogYCR7c3RlcC5uYW1lfTogcnVuIHRoZSBhY3Rpb25gLFxuICAgICAgICB1c2VzOiAnLicsXG4gICAgICAgIC4uLihoYXNJbnB1dHMgPyB7IHdpdGg6IHN0ZXAuaW5wdXRzIH0gOiB7fSksXG4gICAgICB9KTtcblxuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIG5hbWU6IGAke3N0ZXAubmFtZX06IGFzc2VydGAsXG4gICAgICAgIHJ1bjogc3RlcC5hc3NlcnRpb25zLmpvaW4oJ1xcbicpLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIG5hbWU6ICdDbGVhbnVwJyxcbiAgICAgICAgaWY6ICdhbHdheXMoKScsXG4gICAgICAgIHJ1bjogb3B0aW9ucy5jbGVhbnVwLmpvaW4oJ1xcbicpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy53b3JrZmxvdyA9IG5ldyBnaXRodWIuR2l0aHViV29ya2Zsb3coZ2gsICd0ZXN0LWRvZ2Zvb2QnKTtcbiAgICBub3RlV29ya2Zsb3dQdXJwb3NlKFxuICAgICAgdGhpcy53b3JrZmxvdy5maWxlLFxuICAgICAgJ0VuZC10by1lbmQgZG9nZm9vZCB0ZXN0IHJ1bm5pbmcgdGhlIGFjdGlvbiBhZ2FpbnN0IHRoaXMgcmVwby4nLFxuICAgICk7XG4gICAgdGhpcy53b3JrZmxvdy5vbih7XG4gICAgICB3b3JrZmxvd0Rpc3BhdGNoOiB7fSxcbiAgICAgIHB1bGxSZXF1ZXN0OiB7IGJyYW5jaGVzOiBbJ21haW4nXSB9LFxuICAgICAgLy8gTm8gbmlnaHRseSBjYW5hcnkgd2hpbGUgdW5jb25maWd1cmVkOiB0aGUgUFIgcnVuIGlzIHRoZSBzaWduYWwsIGFuZFxuICAgICAgLy8gYSBjcm9uIHRoYXQgYWx3YXlzIGZhaWxzIGlzIGp1c3QgYSBkYWlseSBub3RpZmljYXRpb24gbm9ib2R5IHJlYWRzLlxuICAgICAgLi4uKG9wdGlvbnMgPyB7IHNjaGVkdWxlOiBbeyBjcm9uOiBOSUdIVExZX0RPR0ZPT0RfU0NIRURVTEUgfV0gfSA6IHt9KSxcbiAgICB9KTtcbiAgICB0aGlzLndvcmtmbG93LmFkZEpvYignZG9nZm9vZCcsIHtcbiAgICAgIHJ1bnNPbjogWyd1YnVudHUtbGF0ZXN0J10sXG4gICAgICBwZXJtaXNzaW9uczogb3B0aW9uc1xuICAgICAgICA/IHtcbiAgICAgICAgICBjb250ZW50czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICAgIHB1bGxSZXF1ZXN0czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICB9XG4gICAgICAgIDogeyBjb250ZW50czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLlJFQUQgfSxcbiAgICAgIHN0ZXBzLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWRvZ2Zvb2Qtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWN0aW9ucy9hY3Rpb24tZG9nZm9vZC13b3JrZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsbUNBQTJDO0FBQzNDLGlFQUFpRTtBQUVqRSx3RUFBd0U7QUFDeEUsMEVBQTBFO0FBQzFFLHFFQUFxRTtBQUNyRSxvREFBb0Q7QUFDcEQsTUFBTSx3QkFBd0IsR0FBRyxZQUFZLENBQUM7QUFxQzlDLHlFQUF5RTtBQUN6RSx1RUFBdUU7QUFDdkUsOENBQThDO0FBQzlDLFNBQVMsSUFBSSxDQUFDLElBQVksRUFBRSxLQUFhO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLElBQUk7U0FDZCxXQUFXLEVBQUU7U0FDYixPQUFPLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQztTQUMzQixPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzNCLE9BQU8sR0FBRyxJQUFJLElBQUksTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO0FBQ3RDLENBQUM7QUFVRCx5RUFBeUU7QUFDekUsb0VBQW9FO0FBQ3BFLDRFQUE0RTtBQUM1RSwwRUFBMEU7QUFDMUUsNEVBQTRFO0FBQzVFLHNEQUFzRDtBQUN0RCxNQUFNLGtCQUFrQixHQUFhO0lBQ25DLDBGQUEwRjtJQUMxRixvSUFBb0k7SUFDcEksUUFBUTtDQUNULENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFhLHFCQUFzQixTQUFRLGtCQUFTOztJQUNsQyxRQUFRLENBQXdCO0lBRWhELFlBQVksS0FBMkIsRUFBRSxPQUE4QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFFdEMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxD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QUMsRUFBRTtZQUNuQyxzRUFBc0U7WUFDdEUsc0VBQXNFO1lBQ3RFLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsd0JBQXdCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUN2RSxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7WUFDOUIsTUFBTSxFQUFFLENBQUMsZUFBZSxDQUFDO1lBQ3pCLFdBQVcsRUFBRSxPQUFPO2dCQUNsQixDQUFDLENBQUM7b0JBQ0EsUUFBUSxFQUFFLGVBQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUs7b0JBQzlDLFlBQVksRUFBRSxlQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLO2lCQUNuRDtnQkFDRCxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsZUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFO1lBQ3JELEtBQUs7U0FDTixDQUFDLENBQUM7SUFDTCxDQUFDOztBQXJGSCxzREFzRkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGdpdGh1YiB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBub3RlV29ya2Zsb3dQdXJwb3NlIH0gZnJvbSAnLi4vY29tbW9uL3dvcmtmbG93LXB1cnBvc2UnO1xuXG4vLyBOaWdodGx5IGVudmlyb25tZW50LXJlZ3Jlc3Npb24gY2FuYXJ5IChBRC0wMDEvRjAwNik6IHJlLXJ1bnMgdGhlIHNhbWVcbi8vIHNjZW5hcmlvIGFnYWluc3Qgc2V0dGxlZCBgbWFpbmAgaW4gdG9kYXkncyBydW5uZXIgaW1hZ2UsIGluZGVwZW5kZW50IG9mXG4vLyB0aGUgcHVsbF9yZXF1ZXN0IGdhdGUuIFF1aWV0IFVUQyBob3VyOyBhIGNvbXBvbmVudCBjb25zdGFudCwgbm90IGFcbi8vIHByb2plY3Qgb3B0aW9uIC0gdXBncmFkaW5nIGl0IGlzIGEgcmV2aWV3ZWQgZGlmZi5cbmNvbnN0IE5JR0hUTFlfRE9HRk9PRF9TQ0hFRFVMRSA9ICcxNyAzICogKiAqJztcblxuLyoqXG4gKiBPbmUgaW52b2NhdGlvbiBvZiB0aGUgYWN0aW9uIHdpdGhpbiB0aGUgZG9nZm9vZCBzY2VuYXJpbzogb3B0aW9uYWwgZml4dHVyZVxuICogc2V0dXAsIHRoZSBgdXNlczogLi9gIGNhbGwgd2l0aCB0aGlzIHN0ZXAncyBpbnB1dHMsIHRoZW4gdGhpcyBzdGVwJ3NcbiAqIGFzc2VydGlvbnMuIE1vc3QgYWN0aW9ucyBuZWVkIGV4YWN0bHkgb25lOyBhY3Rpb25zIHdpdGggYSByZS1ydW4vbm8tb3BcbiAqIGJlaGF2aW9yIHRvIHZlcmlmeSAoZS5nLiBGMDA2J3MgcmV1c2UtdGhlLVBSIHBhdGgsIEYwMDcncyBuby1vcC1jb21taXRcbiAqIHBhdGgpIGRlY2xhcmUgdHdvLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjdGlvbkRvZ2Zvb2RTdGVwIHtcbiAgLyoqIExhYmVsIHVzZWQgdG8gbmFtZSB0aGlzIHN0ZXAtZ3JvdXAncyBnZW5lcmF0ZWQgd29ya2Zsb3cgc3RlcHMuICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogU3RlcCBpZCBmb3IgdGhlIGB1c2VzOiAuL2AgaW52b2NhdGlvbiwgc28gYSBsYXRlciBhc3NlcnRpb24gY2FuXG4gICAqIHJlZmVyZW5jZSB0aGlzIHN0ZXAncyBvdXRwdXRzIHZpYSBgJHt7IHN0ZXBzLjxpZD4ub3V0cHV0cy48bmFtZT4gfX1gLlxuICAgKiBAZGVmYXVsdCAtIGEgc2x1ZyBkZXJpdmVkIGZyb20gYG5hbWVgLCBkaXNhbWJpZ3VhdGVkIGJ5IHBvc2l0aW9uXG4gICAqL1xuICByZWFkb25seSBpZD86IHN0cmluZztcblxuICAvKipcbiAgICogU2hlbGwgc3RlcHMgZXhlY3V0ZWQgYmVmb3JlIHRoaXMgaW52b2NhdGlvbiwgdG8gcHJvZHVjZSBvciBhbHRlclxuICAgKiBmaXh0dXJlIHN0YXRlLlxuICAgKiBAZGVmYXVsdCBbXVxuICAgKi9cbiAgcmVhZG9ubHkgZml4dHVyZVN0ZXBzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIGB3aXRoOmAgaW5wdXRzIGZvciB0aGlzIGludm9jYXRpb24ncyBsb2NhbCBgdXNlczogLi9gIGNhbGwuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqL1xuICByZWFkb25seSBpbnB1dHM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKiBTaGVsbCBhc3NlcnRpb25zIGFmdGVyIHRoaXMgaW52b2NhdGlvbiAtIHRoZSBqb2IgZmFpbHMgdW5sZXNzIGV2ZXJ5IG9uZSBleGl0cyAwLiAqL1xuICByZWFkb25seSBhc3NlcnRpb25zOiBzdHJpbmdbXTtcbn1cblxuLy8gTG93ZXJjYXNlLCBub24tYWxwaGFudW1lcmljcyBjb2xsYXBzZWQgdG8gYSBzaW5nbGUgYC1gLCB0cmltbWVkIC0gdGhlblxuLy8gZGlzYW1iaWd1YXRlZCBieSBwb3NpdGlvbiBzbyB0d28gc3RlcHMgc2hhcmluZyBhIG5hbWUgKG9yIGFuIHVubmFtZWRcbi8vIHNsdWcsIGUuZy4gcHVuY3R1YXRpb24tb25seSkgbmV2ZXIgY29sbGlkZS5cbmZ1bmN0aW9uIHNsdWcobmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgYmFzZSA9IG5hbWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csICctJylcbiAgICAucmVwbGFjZSgvXi0rfC0rJC9nLCAnJyk7XG4gIHJldHVybiBgJHtiYXNlIHx8ICdzdGVwJ30tJHtpbmRleH1gO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjdGlvbkRvZ2Zvb2RPcHRpb25zIHtcbiAgLyoqIE9uZSBvciBtb3JlIHNjZW5hcmlvIHN0ZXBzLCBydW4gaW4gb3JkZXIsIGluIHRoZSBkb2dmb29kIGpvYi4gKi9cbiAgcmVhZG9ubHkgc2NlbmFyaW86IEFjdGlvbkRvZ2Zvb2RTdGVwW107XG5cbiAgLyoqIFNoZWxsIGNsZWFudXAsIHJ1biBvbmNlIGF0IHRoZSBlbmQgd2l0aCBgaWY6IGFsd2F5cygpYCwgc28gcmVwZWF0ZWQgcnVucyBzdGFydCBjbGVhbi4gKi9cbiAgcmVhZG9ubHkgY2xlYW51cDogc3RyaW5nW107XG59XG5cbi8vIFRoZSBzdGFuZC1pbiBzY2VuYXJpbyB1c2VkIHdoZW4gYSBwcm9qZWN0IGRlY2xhcmVzIG5vIGBkb2dmb29kYCBhdCBhbGxcbi8vIChlLmcuIGEgcmVwbyBgcHJvamVuIG5ld2AganVzdCBzY2FmZm9sZGVkKS4gVGhlIHdvcmtmbG93IGlzIHN0aWxsXG4vLyBnZW5lcmF0ZWQgYW5kIHN0aWxsIHJ1bnMgb24gZXZlcnkgUFIgLSBpdCBqdXN0IGZhaWxzLCB0ZWxsaW5nIHlvdSB3aGF0IHRvXG4vLyB3cml0ZS4gQUQtMDAxJ3MgcnVsZSBpcyB0aGF0IGEgZG9nZm9vZCBtdXN0IG5ldmVyIGJlICpzaWxlbnRseSogYWJzZW50O1xuLy8gdGhyb3dpbmcgZHVyaW5nIHN5bnRoIGluc3RlYWQgd291bGQgbWFrZSB0aGUgcHJvamVjdCB0eXBlIHVuc2NhZmZvbGRhYmxlLFxuLy8gc2luY2UgYHByb2plbiBuZXdgIGhhcyBubyB3YXkgdG8gc3VwcGx5IGEgc2NlbmFyaW8uXG5jb25zdCBVTkNPTkZJR1VSRURfU1RFUFM6IHN0cmluZ1tdID0gW1xuICAnZWNobyBcIjo6ZXJyb3I6OnRoaXMgYWN0aW9uIGhhcyBubyBkb2dmb29kIHNjZW5hcmlvLCBzbyBub3RoaW5nIGV4ZXJjaXNlcyBpdCBlbmQtdG8tZW5kLlwiJyxcbiAgJ2VjaG8gXCJBZGQgZG9nZm9vZDogeyBzY2VuYXJpbzogWy4uLl0sIGNsZWFudXA6IFsuLi5dIH0gdG8gLnByb2plbnJjLnRzIGFuZCBydW4gbnB4IHByb2plbiAtIHNlZSB0aGUgQHhwZXJ0c3MvcHJvamVuLXR5cGVzIFJFQURNRS5cIicsXG4gICdleGl0IDEnLFxuXTtcblxuLyoqXG4gKiBQZXIgQUQtMDAxJ3MgZG9nZm9vZCB0ZXN0OiB0aGUgY29tcG9zaXRlIGFjdGlvbiBpcyBydW4gKiphZ2FpbnN0IHRoaXNcbiAqIHJlcG8qKiwgZW5kLXRvLWVuZCwgdmlhIGEgbG9jYWwgYHVzZXM6IC4vYCByZWZlcmVuY2UgLSBubyBleHRlcm5hbCBoYXJuZXNzLlxuICogQnVpbGRzIGB0ZXN0LWRvZ2Zvb2QueW1sYCBmcm9tIGFuIG9yZGVyZWQgYHNjZW5hcmlvYCBvZiBpbnZvY2F0aW9uIHN0ZXBzXG4gKiAoc2VlIGBBY3Rpb25Eb2dmb29kU3RlcGApIGZvbGxvd2VkIGJ5IGEgc2hhcmVkIGNsZWFudXAgc3RlcC5cbiAqXG4gKiBPbWl0dGluZyBgb3B0aW9uc2AgZ2VuZXJhdGVzIHRoZSB3b3JrZmxvdyB3aXRoIGEgc2luZ2xlIGZhaWxpbmcgc3RlcCAoc2VlXG4gKiBgVU5DT05GSUdVUkVEX1NURVBTYCkuIEEgKnBhcnRpYWxseSogZGVjbGFyZWQgZG9nZm9vZCBpcyBzdGlsbCBhIHN5bnRoXG4gKiBlcnJvcjogaWYgeW91IHdyb3RlIGEgc2NlbmFyaW8gYnkgaGFuZCwgeW91IGNhbiB3cml0ZSBpdHMgY2xlYW51cCB0b28uXG4gKi9cbmV4cG9ydCBjbGFzcyBBY3Rpb25Eb2dmb29kV29ya2Zsb3cgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c6IGdpdGh1Yi5HaXRodWJXb3JrZmxvdztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogZ2l0aHViLkdpdEh1YlByb2plY3QsIG9wdGlvbnM/OiBBY3Rpb25Eb2dmb29kT3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlLCAnQWN0aW9uRG9nZm9vZFdvcmtmbG93Jyk7XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zLnNjZW5hcmlvIHx8IG9wdGlvbnMuc2NlbmFyaW8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnQWN0aW9uRG9nZm9vZFdvcmtmbG93IHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBkb2dmb29kLnNjZW5hcmlvIHN0ZXAnLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRpb25zLmNsZWFudXAgfHwgb3B0aW9ucy5jbGVhbnVwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjdGlvbkRvZ2Zvb2RXb3JrZmxvdyByZXF1aXJlcyBkb2dmb29kLmNsZWFudXAnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBnaCA9IHNjb3BlLmdpdGh1YjtcbiAgICBpZiAoIWdoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdBY3Rpb25Eb2dmb29kV29ya2Zsb3cgcmVxdWlyZXMgR2l0SHViIGludGVncmF0aW9uIHRvIGJlIGVuYWJsZWQnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGVwczogZ2l0aHViLndvcmtmbG93cy5Kb2JTdGVwW10gPSBvcHRpb25zXG4gICAgICA/IFtnaXRodWIuV29ya2Zsb3dTdGVwcy5jaGVja291dCgpXVxuICAgICAgOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAnRG9nZm9vZCBzY2VuYXJpbyBub3QgY29uZmlndXJlZCcsXG4gICAgICAgICAgcnVuOiBVTkNPTkZJR1VSRURfU1RFUFMuam9pbignXFxuJyksXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgKG9wdGlvbnM/LnNjZW5hcmlvID8/IFtdKS5mb3JFYWNoKChzdGVwLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHN0ZXAuZml4dHVyZVN0ZXBzICYmIHN0ZXAuZml4dHVyZVN0ZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgICAgbmFtZTogYCR7c3RlcC5uYW1lfTogZml4dHVyZWAsXG4gICAgICAgICAgcnVuOiBzdGVwLmZpeHR1cmVTdGVwcy5qb2luKCdcXG4nKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0lucHV0cyA9IHN0ZXAuaW5wdXRzICYmIE9iamVjdC5rZXlzKHN0ZXAuaW5wdXRzKS5sZW5ndGggPiAwO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBzdGVwLmlkID8/IHNsdWcoc3RlcC5uYW1lLCBpbmRleCksXG4gICAgICAgIG5hbWU6IGAke3N0ZXAubmFtZX06IHJ1biB0aGUgYWN0aW9uYCxcbiAgICAgICAgdXNlczogJy4vJyxcbiAgICAgICAgLi4uKGhhc0lucHV0cyA/IHsgd2l0aDogc3RlcC5pbnB1dHMgfSA6IHt9KSxcbiAgICAgIH0pO1xuXG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgbmFtZTogYCR7c3RlcC5uYW1lfTogYXNzZXJ0YCxcbiAgICAgICAgcnVuOiBzdGVwLmFzc2VydGlvbnMuam9pbignXFxuJyksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBzdGVwcy5wdXNoKHtcbiAgICAgICAgbmFtZTogJ0NsZWFudXAnLFxuICAgICAgICBpZjogJ2Fsd2F5cygpJyxcbiAgICAgICAgcnVuOiBvcHRpb25zLmNsZWFudXAuam9pbignXFxuJyksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLndvcmtmbG93ID0gbmV3IGdpdGh1Yi5HaXRodWJXb3JrZmxvdyhnaCwgJ3Rlc3QtZG9nZm9vZCcpO1xuICAgIG5vdGVXb3JrZmxvd1B1cnBvc2UoXG4gICAgICB0aGlzLndvcmtmbG93LmZpbGUsXG4gICAgICAnRW5kLXRvLWVuZCBkb2dmb29kIHRlc3QgcnVubmluZyB0aGUgYWN0aW9uIGFnYWluc3QgdGhpcyByZXBvLicsXG4gICAgKTtcbiAgICB0aGlzLndvcmtmbG93Lm9uKHtcbiAgICAgIHdvcmtmbG93RGlzcGF0Y2g6IHt9LFxuICAgICAgcHVsbFJlcXVlc3Q6IHsgYnJhbmNoZXM6IFsnbWFpbiddIH0sXG4gICAgICAvLyBObyBuaWdodGx5IGNhbmFyeSB3aGlsZSB1bmNvbmZpZ3VyZWQ6IHRoZSBQUiBydW4gaXMgdGhlIHNpZ25hbCwgYW5kXG4gICAgICAvLyBhIGNyb24gdGhhdCBhbHdheXMgZmFpbHMgaXMganVzdCBhIGRhaWx5IG5vdGlmaWNhdGlvbiBub2JvZHkgcmVhZHMuXG4gICAgICAuLi4ob3B0aW9ucyA/IHsgc2NoZWR1bGU6IFt7IGNyb246IE5JR0hUTFlfRE9HRk9PRF9TQ0hFRFVMRSB9XSB9IDoge30pLFxuICAgIH0pO1xuICAgIHRoaXMud29ya2Zsb3cuYWRkSm9iKCdkb2dmb29kJywge1xuICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgIHBlcm1pc3Npb25zOiBvcHRpb25zXG4gICAgICAgID8ge1xuICAgICAgICAgIGNvbnRlbnRzOiBnaXRodWIud29ya2Zsb3dzLkpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgICAgcHVsbFJlcXVlc3RzOiBnaXRodWIud29ya2Zsb3dzLkpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgIH1cbiAgICAgICAgOiB7IGNvbnRlbnRzOiBnaXRodWIud29ya2Zsb3dzLkpvYlBlcm1pc3Npb24uUkVBRCB9LFxuICAgICAgc3RlcHMsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -15,7 +15,7 @@ const SONAR_SCANNER_SHA256 = 'bb8f709f9cb73352f8d1260a3b3c506c0f41146754bc630762
15
15
  * inclusions may skip `action.yml` outside `.github/`.
16
16
  */
17
17
  class ActionSonarWorkflow extends projen_1.Component {
18
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionSonarWorkflow", version: "0.0.12" };
18
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionSonarWorkflow", version: "0.0.13" };
19
19
  workflow;
20
20
  constructor(scope, options) {
21
21
  super(scope, 'ActionSonarWorkflow');
@@ -62,7 +62,7 @@ hand-committed.
62
62
  * per the action's own F### spec - this type only lints it.
63
63
  */
64
64
  class GitHubActionProject extends projen_1.github.GitHubProject {
65
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.GitHubActionProject", version: "0.0.12" };
65
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.GitHubActionProject", version: "0.0.13" };
66
66
  buildWorkflow;
67
67
  dogfoodWorkflow;
68
68
  sonarWorkflow;
@@ -8,7 +8,7 @@ const projen_1 = require("projen");
8
8
  * layered on top of `CdkTypescriptProject`'s pure-infra scaffold.
9
9
  */
10
10
  class AppRuntimeScaffold extends projen_1.Component {
11
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.AppRuntimeScaffold", version: "0.0.12" };
11
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.AppRuntimeScaffold", version: "0.0.13" };
12
12
  constructor(project, appEntryPoint = 'src/app.ts') {
13
13
  super(project, 'AppRuntimeScaffold');
14
14
  const app = new projen_1.SourceCode(project, appEntryPoint);
@@ -13,7 +13,7 @@ const workflow_purpose_1 = require("../common/workflow-purpose");
13
13
  * application source, a database, and an app-level build/test workflow.
14
14
  */
15
15
  class CdkAppProject extends cdk_infra_project_1.CdkInfraProject {
16
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkAppProject", version: "0.0.12" };
16
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkAppProject", version: "0.0.13" };
17
17
  constructor(options) {
18
18
  super(options);
19
19
  new app_runtime_scaffold_1.AppRuntimeScaffold(this, options.appEntryPoint ?? 'src/app.ts');
@@ -11,7 +11,7 @@ const edge_networking_constructs_1 = require("./components/edge-networking-const
11
11
  * externally-built images). Reference example: SimulcastAVDelivery.
12
12
  */
13
13
  class CdkInfraProject extends cdk_typescript_base_1.CdkTypescriptProject {
14
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkInfraProject", version: "0.0.12" };
14
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkInfraProject", version: "0.0.13" };
15
15
  constructor(options) {
16
16
  super(options);
17
17
  if (options.ecrEcs?.enabled) {
@@ -22,7 +22,7 @@ const PROJEN_TYPES_VERSION = require('../../package.json').version;
22
22
  * `ManualDeployWorkflow` when `environments` is provided.
23
23
  */
24
24
  class CdkTypescriptProject extends projen_1.awscdk.AwsCdkTypeScriptApp {
25
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkTypescriptProject", version: "0.0.12" };
25
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkTypescriptProject", version: "0.0.13" };
26
26
  constructor(options) {
27
27
  super({
28
28
  // Spread first, overrides after: forwarding the caller's options is
@@ -10,7 +10,7 @@ const projen_1 = require("projen");
10
10
  * built from this project's own source (app projects).
11
11
  */
12
12
  class EcrEcsConstructs extends projen_1.Component {
13
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.EcrEcsConstructs", version: "0.0.12" };
13
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.EcrEcsConstructs", version: "0.0.13" };
14
14
  constructor(project, options = {}) {
15
15
  super(project, 'EcrEcsConstructs');
16
16
  const externalImageSource = options.externalImageSource ?? true;
@@ -42,7 +42,7 @@ const HELPERS = {
42
42
  * to whichever `edgeResources` the consuming project type opts into.
43
43
  */
44
44
  class EdgeNetworkingConstructs extends projen_1.Component {
45
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.EdgeNetworkingConstructs", version: "0.0.12" };
45
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.EdgeNetworkingConstructs", version: "0.0.13" };
46
46
  constructor(project, resources) {
47
47
  super(project, 'EdgeNetworkingConstructs');
48
48
  if (resources.length === 0) {
@@ -10,7 +10,7 @@ const projen_1 = require("projen");
10
10
  * the consuming team to wire up; no opinionated default is imposed.
11
11
  */
12
12
  class DatabaseComponent extends projen_1.Component {
13
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.DatabaseComponent", version: "0.0.12" };
13
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.DatabaseComponent", version: "0.0.13" };
14
14
  constructor(project, options = {}) {
15
15
  super(project, 'DatabaseComponent');
16
16
  const engine = options.engine ?? 'postgres';
@@ -5,7 +5,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const projen_1 = require("projen");
6
6
  const workflow_purpose_1 = require("./workflow-purpose");
7
7
  class ProjenDriftCheckWorkflow extends projen_1.Component {
8
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ProjenDriftCheckWorkflow", version: "0.0.12" };
8
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ProjenDriftCheckWorkflow", version: "0.0.13" };
9
9
  workflow;
10
10
  constructor(scope, options = {}) {
11
11
  super(scope, 'ProjenDriftCheckWorkflow');
@@ -5,7 +5,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const projen_1 = require("projen");
6
6
  const workflow_purpose_1 = require("./workflow-purpose");
7
7
  class WorkflowChangeNoticeWorkflow extends projen_1.Component {
8
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.WorkflowChangeNoticeWorkflow", version: "0.0.12" };
8
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.WorkflowChangeNoticeWorkflow", version: "0.0.13" };
9
9
  workflow;
10
10
  constructor(scope, options = {}) {
11
11
  super(scope, 'WorkflowChangeNoticeWorkflow');
@@ -18,7 +18,7 @@ const manual_deploy_workflow_1 = require("../../common/manual-deploy-workflow");
18
18
  * which is exactly when "this repo has no deploy target" needs saying.
19
19
  */
20
20
  class CdkDeployHook extends projen_1.Component {
21
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkDeployHook", version: "0.0.12" };
21
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CdkDeployHook", version: "0.0.13" };
22
22
  constructor(project, environments, options = {}) {
23
23
  super(project, 'CdkDeployHook');
24
24
  const targetRepo = options.targetRepo;
@@ -6,7 +6,7 @@ const projen_1 = require("projen");
6
6
  const workflow_purpose_1 = require("../../common/workflow-purpose");
7
7
  /** Generates a code index and publishes it to `.cai/` on checkin. */
8
8
  class CodeIndexWorkflow extends projen_1.Component {
9
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CodeIndexWorkflow", version: "0.0.12" };
9
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.CodeIndexWorkflow", version: "0.0.13" };
10
10
  constructor(project) {
11
11
  super(project, 'CodeIndexWorkflow');
12
12
  const gh = project.github;
@@ -6,7 +6,7 @@ const projen_1 = require("projen");
6
6
  const workflow_purpose_1 = require("../../common/workflow-purpose");
7
7
  /** On-demand build+push of a Docker image, defaulting to Docker Hub. */
8
8
  class DockerPublish extends projen_1.Component {
9
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.DockerPublish", version: "0.0.12" };
9
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.DockerPublish", version: "0.0.13" };
10
10
  constructor(project, options = {}) {
11
11
  super(project, 'DockerPublish');
12
12
  const gh = project.github;
@@ -5,7 +5,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const projen_1 = require("projen");
6
6
  /** Adds Flyway config/dependencies + a migrations directory for DB migrations. */
7
7
  class FlywayMigration extends projen_1.Component {
8
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.FlywayMigration", version: "0.0.12" };
8
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.FlywayMigration", version: "0.0.13" };
9
9
  constructor(project) {
10
10
  super(project, 'FlywayMigration');
11
11
  project.pom.addPlugin('org.flywaydb/flyway-maven-plugin@^10');
@@ -6,7 +6,7 @@ const projen_1 = require("projen");
6
6
  const workflow_purpose_1 = require("../../common/workflow-purpose");
7
7
  /** On-demand publish to GitHub Packages. */
8
8
  class GitHubPackagesPublish extends projen_1.Component {
9
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.GitHubPackagesPublish", version: "0.0.12" };
9
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.GitHubPackagesPublish", version: "0.0.13" };
10
10
  constructor(project, options = {}) {
11
11
  super(project, 'GitHubPackagesPublish');
12
12
  const gh = project.github;
@@ -9,7 +9,7 @@ const workflow_purpose_1 = require("../../common/workflow-purpose");
9
9
  * or OIDC trusted publishing.
10
10
  */
11
11
  class MavenCentralPublish extends projen_1.Component {
12
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.MavenCentralPublish", version: "0.0.12" };
12
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.MavenCentralPublish", version: "0.0.13" };
13
13
  constructor(project, options = {}) {
14
14
  super(project, 'MavenCentralPublish');
15
15
  const gh = project.github;
@@ -9,7 +9,7 @@ const java_maven_base_1 = require("./java-maven-base");
9
9
  * explicitly excludes Maven Central, Docker, and CDK deploy hooks.
10
10
  */
11
11
  class JavaAppProject extends java_maven_base_1.JavaMavenProject {
12
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaAppProject", version: "0.0.12" };
12
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaAppProject", version: "0.0.13" };
13
13
  constructor(options) {
14
14
  super(options);
15
15
  new github_packages_publish_1.GitHubPackagesPublish(this, {
@@ -7,7 +7,7 @@ const maven_central_publish_1 = require("./components/maven-central-publish");
7
7
  const java_maven_base_1 = require("./java-maven-base");
8
8
  /** Reusable Java library, published to Maven Central. */
9
9
  class JavaLibraryProject extends java_maven_base_1.JavaMavenProject {
10
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaLibraryProject", version: "0.0.12" };
10
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaLibraryProject", version: "0.0.13" };
11
11
  constructor(options) {
12
12
  super(options);
13
13
  new maven_central_publish_1.MavenCentralPublish(this, { mavenCentralOidc: options.mavenCentralOidc });
@@ -17,7 +17,7 @@ const workflow_purpose_1 = require("../common/workflow-purpose");
17
17
  * nightly dependency-upgrade workflow.
18
18
  */
19
19
  class JavaMavenProject extends projen_1.java.JavaProject {
20
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaMavenProject", version: "0.0.12" };
20
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaMavenProject", version: "0.0.13" };
21
21
  upgradeTask;
22
22
  buildVerifyWorkflow;
23
23
  constructor(options) {
@@ -11,7 +11,7 @@ const java_maven_base_1 = require("./java-maven-base");
11
11
  * Central); publish and deploy are both manual-dispatch, not on every merge.
12
12
  */
13
13
  class JavaServiceProject extends java_maven_base_1.JavaMavenProject {
14
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaServiceProject", version: "0.0.12" };
14
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.JavaServiceProject", version: "0.0.13" };
15
15
  constructor(options) {
16
16
  super(options);
17
17
  this.pom.addDependency('org.springframework.boot/spring-boot-starter-web@^3');
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "publishConfig": {
83
83
  "access": "public"
84
84
  },
85
- "version": "0.0.12",
85
+ "version": "0.0.13",
86
86
  "jest": {
87
87
  "coverageProvider": "v8",
88
88
  "testMatch": [