From 109a1ed87f7a2e9fbe352695c982e1d761b57222 Mon Sep 17 00:00:00 2001 From: galargh Date: Mon, 8 Dec 2025 22:13:19 +0000 Subject: [PATCH] upgrade@20044535066 --- .github/workflows/apply.yml | 17 +- .github/workflows/clean.yml | 6 +- .github/workflows/cleanup.yml | 13 +- .github/workflows/fix.yml | 29 +- .github/workflows/labels.yml | 13 +- .github/workflows/plan.yml | 14 +- .github/workflows/sync.yml | 33 +- .github/workflows/update.yml | 13 +- CHANGELOG.md | 4 + docs/ABOUT.md | 2 +- docs/EXAMPLE.yml | 1 - github/.schema.json | 42 +- .../terraform/locals_override.tf | 2 +- .../__resources__/terraform/resources.tf | 2 +- .../__resources__/terraform/terraform.tfstate | 64 +- scripts/__tests__/sync.test.ts | 25 +- scripts/__tests__/terraform/state.test.ts | 19 +- scripts/package.json | 45 +- scripts/pnpm-lock.yaml | 2175 +++++++++++++++++ scripts/pnpm-workspace.yaml | 4 + scripts/src/actions/find-sha-for-plan.ts | 12 +- .../repository-branch-protection-rule.ts | 13 +- scripts/src/resources/repository-label.ts | 21 +- scripts/src/resources/repository.ts | 3 + scripts/src/terraform/schema.ts | 8 +- scripts/src/terraform/state.ts | 40 +- terraform/bootstrap/aws.tf | 2 +- terraform/locals.tf | 48 +- terraform/resources.tf | 71 +- terraform/terraform.tf | 4 +- terraform/variables.tf | 16 + 31 files changed, 2552 insertions(+), 209 deletions(-) create mode 100644 scripts/pnpm-lock.yaml create mode 100644 scripts/pnpm-workspace.yaml diff --git a/.github/workflows/apply.yml b/.github/workflows/apply.yml index 8de5da2..624bb18 100644 --- a/.github/workflows/apply.yml +++ b/.github/workflows/apply.yml @@ -23,11 +23,20 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Discover workspaces id: workspaces run: echo "this=$(ls github | jq --raw-input '[.[0:-4]]' | jq -sc add)" >> $GITHUB_OUTPUT - - run: npm ci && npm run build + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' + - run: pnpm install --frozen-lockfile && pnpm run build working-directory: scripts - name: Find sha for plan id: sha @@ -65,11 +74,11 @@ jobs: working-directory: terraform steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init diff --git a/.github/workflows/clean.yml b/.github/workflows/clean.yml index 00bd852..556adb5 100644 --- a/.github/workflows/clean.yml +++ b/.github/workflows/clean.yml @@ -30,7 +30,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Discover workspaces id: workspaces env: @@ -69,11 +69,11 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init -upgrade diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index 88e0e75..87f35ca 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -37,9 +37,18 @@ jobs: TF_WORKSPACE: ${{ github.repository_owner }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' - name: Initialize scripts - run: npm install && npm run build + run: pnpm install --frozen-lockfile && pnpm run build working-directory: scripts - name: Remove inactive members run: node lib/actions/remove-inactive-members.js diff --git a/.github/workflows/fix.yml b/.github/workflows/fix.yml index dd414c8..38607ed 100644 --- a/.github/workflows/fix.yml +++ b/.github/workflows/fix.yml @@ -35,7 +35,7 @@ jobs: skip-fix: ${{ steps.skip-fix.outputs.this }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - if: github.event_name == 'pull_request_target' env: NUMBER: ${{ github.event.pull_request.number }} @@ -82,7 +82,7 @@ jobs: TF_VAR_write_delay_ms: 300 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - if: github.event_name == 'pull_request_target' env: NUMBER: ${{ github.event.pull_request.number }} @@ -95,13 +95,22 @@ jobs: - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init working-directory: terraform + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' - name: Initialize scripts - run: npm ci && npm run build + run: pnpm install --frozen-lockfile && pnpm run build working-directory: scripts - name: Fix id: fix @@ -117,7 +126,7 @@ jobs: # NOTE(galargh, 2024-02-15): This will only work if GitHub as Code is used for a single organization - name: Comment on pull request if: github.event_name == 'pull_request_target' && steps.fix.outputs.comment - uses: marocchino/sticky-pull-request-comment@67d0dec7b07ed060a405f9b2a64b8ab319fdd7db # v2.9.2 + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 with: header: fix number: ${{ github.event.pull_request.number }} @@ -142,22 +151,24 @@ jobs: installation_retrieval_payload: ${{ secrets[format('RW_GITHUB_APP_INSTALLATION_ID_{0}', github.repository_owner)] || secrets.RW_GITHUB_APP_INSTALLATION_ID }} private_key: ${{ secrets.RW_GITHUB_APP_PEM_FILE }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} ref: ${{ github.event.pull_request.head.sha || github.sha }} token: ${{ steps.token.outputs.token }} path: head - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: path: base - name: Download YAML configs - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: artifacts - name: Copy YAML configs - run: cp artifacts/**/*.yml head/github + run: | + shopt -s globstar + cp artifacts/**/*.yml head/github - name: Check if github was modified id: github-modified run: | diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index eb17c7e..130d3cb 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -35,9 +35,18 @@ jobs: TF_WORKSPACE: ${{ github.repository_owner }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' - name: Initialize scripts - run: npm install && npm run build + run: pnpm install --frozen-lockfile && pnpm run build working-directory: scripts - name: Sync run: node lib/actions/sync-labels.js diff --git a/.github/workflows/plan.yml b/.github/workflows/plan.yml index 1442cb8..9ab88e0 100644 --- a/.github/workflows/plan.yml +++ b/.github/workflows/plan.yml @@ -25,7 +25,7 @@ jobs: workspaces: ${{ steps.workspaces.outputs.this }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - if: github.event_name == 'pull_request_target' env: NUMBER: ${{ github.event.pull_request.number }} @@ -70,7 +70,7 @@ jobs: TF_VAR_write_delay_ms: 300 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - if: github.event_name == 'pull_request_target' env: NUMBER: ${{ github.event.pull_request.number }} @@ -82,7 +82,7 @@ jobs: - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init @@ -112,7 +112,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.RO_AWS_SECRET_ACCESS_KEY }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - if: github.event_name == 'pull_request_target' env: NUMBER: ${{ github.event.pull_request.number }} @@ -124,13 +124,13 @@ jobs: - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init working-directory: terraform - name: Download terraform plans - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: path: terraform - name: Show terraform plans @@ -157,7 +157,7 @@ jobs: echo 'EOF' >> $GITHUB_ENV working-directory: terraform - name: Comment on pull request - uses: marocchino/sticky-pull-request-comment@67d0dec7b07ed060a405f9b2a64b8ab319fdd7db # v2.9.2 + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 with: header: plan number: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index ca0af0f..544fd1f 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -12,6 +12,10 @@ on: description: Whether to acquire terraform state lock during sync required: false default: "true" + refresh: + description: Refresh terraform state before sync + required: false + default: "false" jobs: prepare: @@ -24,7 +28,7 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Discover workspaces id: workspaces env: @@ -63,11 +67,11 @@ jobs: shell: bash steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup terraform uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 with: - terraform_version: 1.2.9 + terraform_version: 1.12.0 terraform_wrapper: false - name: Initialize terraform run: terraform init -upgrade @@ -77,15 +81,30 @@ jobs: terraform workspace select "${TF_WORKSPACE_OPT}" || terraform workspace new "${TF_WORKSPACE_OPT}" echo "TF_WORKSPACE=${TF_WORKSPACE_OPT}" >> $GITHUB_ENV working-directory: terraform + - name: Refresh terraform state + if: ${{ github.event.inputs.refresh == 'true' }} + run: | + echo "{}" > $TF_WORKSPACE.tfstate.json + terraform apply -refresh-only -auto-approve -lock=$TF_LOCK + working-directory: terraform - name: Pull terraform state run: | terraform show -json > $TF_WORKSPACE.tfstate.json working-directory: terraform + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' - name: Sync run: | - npm ci - npm run build - npm run main + pnpm install --frozen-lockfile + pnpm run build + pnpm run main working-directory: scripts - uses: ./.github/actions/git-config-user - env: @@ -114,7 +133,7 @@ jobs: installation_retrieval_payload: ${{ secrets[format('RW_GITHUB_APP_INSTALLATION_ID_{0}', github.repository_owner)] || secrets.RW_GITHUB_APP_INSTALLATION_ID }} private_key: ${{ secrets.RW_GITHUB_APP_PEM_FILE }} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: token: ${{ steps.token.outputs.token }} - uses: ./.github/actions/git-config-user diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 9ff4cd7..e621491 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -20,8 +20,17 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 - - run: npm ci && npm run build + - uses: actions/checkout@v5 + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + - name: Use Node.js lts/* + uses: actions/setup-node@v6 + with: + node-version: lts/* + cache: '' + - run: pnpm install --frozen-lockfile && pnpm run build working-directory: scripts - name: Update PRs env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad4692..d27cd10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - new args for repositories and branch protection rules ### Changed +- **BREAKING**: added support for efficient labels handling via the `github_issue_labels` resource (please clean `github_issue_label.this.*` from the terraform state and update `locals_override.tf` and `resources_override.tf` before syncing) +- **BREAKING**: upgraded to terraform 1.12.0 and github provider 6.6.0 (please clean `github_branch_protection.this.*` from the terraform state and update `resources_override.tf` before syncing the upgrade) - **BREAKING**: turned scripts into an ESM project (please ensure you remove the following files during the upgrade: `scripts/.eslintignore`, `scripts/.eslintrc.json`, `scripts/jest.config.js`, `jest.d.ts`, `jest.setup.ts`; please update your imports in the `scripts/src/actions/fix-yaml-config.ts` file to include the `.js` extension) - **BREAKING**: Updated the signatures of all the shared actions; now the runAction function will persist the changes to disk while action functions will operate on the in-memory state (please update your imports in the `scripts/src/actions/fix-yaml-config.ts` file accordingly) - Synchronization script: to use GitHub API directly instead of relying on TF GH Provider's Data Sources @@ -47,8 +49,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - tf: to prevent destroy of membership and repository resources - apply: find sha for plan using proper credentials - updated upload and download artifacts actions to v4 +- switched from npm to pnpm ### Fixed +- include labels in the config resources only if they are explicitly defined in the config - always assert state type when creating resources from state - do not break long file content lines - source TF_WORKING_DIR from env helper instead of process.env in locals helper diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 0b41101..98d8d42 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -47,7 +47,7 @@ Running the `Sync` GitHub Action workflows refreshes the underlying terraform st - [github_team_repository](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository) - [github_team_membership](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_membership) - [github_repository_file](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) -- [github_issue_label](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/issue_label) +- [github_issue_labels](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/issue_labels) # Config Fix Rules diff --git a/docs/EXAMPLE.yml b/docs/EXAMPLE.yml index 28c3a7c..a035b60 100644 --- a/docs/EXAMPLE.yml +++ b/docs/EXAMPLE.yml @@ -32,7 +32,6 @@ repositories: # This group defines repositories (https://registry.terraform.io/p require_conversation_resolution: false require_signed_commits: false required_linear_history: false - push_restrictions: [] # This field accepts node IDs (TODO: make this field accept human friendly names too) required_pull_request_reviews: dismiss_stale_reviews: false dismissal_restrictions: [] # This field accepts node IDs (TODO: make this field accept human friendly names too) diff --git a/github/.schema.json b/github/.schema.json index 624afd3..d48c256 100644 --- a/github/.schema.json +++ b/github/.schema.json @@ -156,6 +156,13 @@ "pages": { "additionalProperties": false, "properties": { + "build_type": { + "enum": [ + "legacy", + "workflow" + ], + "type": "string" + }, "cname": { "type": "string" }, @@ -225,6 +232,9 @@ "template": { "additionalProperties": false, "properties": { + "include_all_branches": { + "type": "boolean" + }, "owner": { "type": "string" }, @@ -245,6 +255,9 @@ }, "vulnerability_alerts": { "type": "boolean" + }, + "web_commit_signoff_required": { + "type": "boolean" } }, "type": "object" @@ -309,21 +322,18 @@ "allows_force_pushes": { "type": "boolean" }, - "blocks_creations": { - "type": "boolean" - }, "enforce_admins": { "type": "boolean" }, - "lock_branch": { - "type": "boolean" - }, - "push_restrictions": { + "force_push_bypassers": { "items": { "type": "string" }, "type": "array" }, + "lock_branch": { + "type": "boolean" + }, "require_conversation_resolution": { "type": "boolean" }, @@ -354,6 +364,9 @@ "require_code_owner_reviews": { "type": "boolean" }, + "require_last_push_approval": { + "type": "boolean" + }, "required_approving_review_count": { "type": "number" }, @@ -377,6 +390,21 @@ } }, "type": "object" + }, + "restrict_pushes": { + "additionalProperties": false, + "properties": { + "blocks_creations": { + "type": "boolean" + }, + "push_allowances": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" } }, "type": "object" diff --git a/scripts/__tests__/__resources__/terraform/locals_override.tf b/scripts/__tests__/__resources__/terraform/locals_override.tf index 516cea5..b75b367 100644 --- a/scripts/__tests__/__resources__/terraform/locals_override.tf +++ b/scripts/__tests__/__resources__/terraform/locals_override.tf @@ -8,7 +8,7 @@ locals { "github_team", "github_branch_protection", "github_repository_file", - "github_issue_label" + "github_issue_labels" ] ignore = { "repositories" = ["ignored"] diff --git a/scripts/__tests__/__resources__/terraform/resources.tf b/scripts/__tests__/__resources__/terraform/resources.tf index 5d7256c..8b48094 100644 --- a/scripts/__tests__/__resources__/terraform/resources.tf +++ b/scripts/__tests__/__resources__/terraform/resources.tf @@ -38,7 +38,7 @@ resource "github_repository_file" "this" { ignore_changes = [] } } -resource "github_issue_label" "this" { +resource "github_issue_labels" "this" { lifecycle { ignore_changes = [] } diff --git a/scripts/__tests__/__resources__/terraform/terraform.tfstate b/scripts/__tests__/__resources__/terraform/terraform.tfstate index 7eef4d6..dc1ef1b 100644 --- a/scripts/__tests__/__resources__/terraform/terraform.tfstate +++ b/scripts/__tests__/__resources__/terraform/terraform.tfstate @@ -1230,7 +1230,6 @@ "enforce_admins": false, "id": "BPR_kwDOHGSVzc4BfS9s", "pattern": "master", - "push_restrictions": [], "repository_id": "R_kgDOHGSVzQ", "require_conversation_resolution": false, "require_signed_commits": false, @@ -1255,7 +1254,6 @@ ] }, "sensitive_values": { - "push_restrictions": [], "required_pull_request_reviews": [ { "dismissal_restrictions": [], @@ -2055,39 +2053,29 @@ ] }, { - "address": "github_issue_label.this[\"github-action-releaser:topic/ci\"]", + "address": "github_issue_labels.this[\"github-action-releaser\"]", "mode": "managed", - "type": "github_issue_label", + "type": "github_issue_labels", "name": "this", - "index": "github-action-releaser:topic/ci", - "provider_name": "registry.terraform.io/integrations/github", - "schema_version": 0, - "values": { - "repository": "github-action-releaser", - "name": "topic/ci", - "color": "#57cc2c", - "description": "Topic CI", - "url": "https://github.com/pl-strflt/github-action-releaser/labels/topic%2Fci" - }, - "sensitive_values": {}, - "depends_on": [ - "github_repository.this" - ] - }, - { - "address": "github_issue_label.this[\"github-action-releaser:topic dx\"]", - "mode": "managed", - "type": "github_issue_label", - "name": "this", - "index": "github-action-releaser:topic dx", + "index": "github-action-releaser", "provider_name": "registry.terraform.io/integrations/github", "schema_version": 0, "values": { "repository": "github-action-releaser", - "name": "topic dx", - "color": "#57cc2c", - "description": "Topic DX", - "url": "https://github.com/pl-strflt/github-action-releaser/labels/topic%20dx" + "label": [ + { + "name": "topic/ci", + "color": "#57cc2c", + "description": "Topic CI", + "url": "https://github.com/pl-strflt/github-action-releaser/labels/topic%2Fci" + }, + { + "name": "topic dx", + "color": "#57cc2c", + "description": "Topic DX", + "url": "https://github.com/pl-strflt/github-action-releaser/labels/topic%20dx" + } + ] }, "sensitive_values": {}, "depends_on": [ @@ -2095,19 +2083,23 @@ ] }, { - "address": "github_issue_label.this[\"projects-status-history:stale\"]", + "address": "github_issue_labels.this[\"projects-status-history\"]", "mode": "managed", - "type": "github_issue_label", + "type": "github_issue_labels", "name": "this", - "index": "projects-status-history:stale", + "index": "projects-status-history", "provider_name": "registry.terraform.io/integrations/github", "schema_version": 0, "values": { "repository": "projects-status-history", - "name": "stale", - "color": "#57cc2c", - "description": "Stale", - "url": "https://github.com/pl-strflt/projects-status-history/labels/stale" + "label": [ + { + "name": "stale", + "color": "#57cc2c", + "description": "Stale", + "url": "https://github.com/pl-strflt/projects-status-history/labels/stale" + } + ] }, "sensitive_values": {}, "depends_on": [ diff --git a/scripts/__tests__/sync.test.ts b/scripts/__tests__/sync.test.ts index 5a3679f..a8b54f1 100644 --- a/scripts/__tests__/sync.test.ts +++ b/scripts/__tests__/sync.test.ts @@ -5,7 +5,6 @@ import * as YAML from 'yaml' import {Config} from '../src/yaml/config.js' import {State} from '../src/terraform/state.js' import {sync} from '../src/sync.js' -import {Resource} from '../src/resources/resource.js' import {RepositoryFile} from '../src/resources/repository-file.js' import {StateSchema} from '../src/terraform/schema.js' import {toggleArchivedRepos} from '../src/actions/shared/toggle-archived-repos.js' @@ -61,19 +60,25 @@ describe('sync', () => { } }) - tfConfig.addResource = async (id: string, resource: Resource) => { - tfSource?.values?.root_module?.resources?.push({ + const resources = [ + { mode: 'managed', - index: id, - address: resource.getStateAddress(), + index: 'blog:README.md', + address: 'github_repository_file.this["blog/readme.md"]', type: RepositoryFile.StateType, values: { - repository: (resource as RepositoryFile).repository, - file: (resource as RepositoryFile).file, - content: (resource as RepositoryFile).content ?? '', - ...resource + repository: 'blog', + file: 'README.md', + content: 'Hello, world!' } - }) + } + ] + + tfConfig.addResourceAt = async (_id: string, address: string) => { + const resource = resources.find(r => r.address === address) + if (resource !== undefined) { + tfSource?.values?.root_module?.resources?.push(resource) + } } const expectedYamlConfig = new Config(YAML.stringify(yamlSource)) diff --git a/scripts/__tests__/terraform/state.test.ts b/scripts/__tests__/terraform/state.test.ts index ffa287e..60181f3 100644 --- a/scripts/__tests__/terraform/state.test.ts +++ b/scripts/__tests__/terraform/state.test.ts @@ -63,10 +63,10 @@ describe('state', () => { it('can add and remove resources through sync', async () => { const config = await State.New() - const addResourceMock = mock.fn(config.addResource.bind(config)) + const addResourceAtMock = mock.fn(config.addResourceAt.bind(config)) const removeResourceAtMock = mock.fn(config.removeResourceAt.bind(config)) - config.addResource = addResourceMock + config.addResourceAt = addResourceAtMock config.removeResourceAt = removeResourceAtMock const desiredResources: [Id, Resource][] = [] @@ -74,10 +74,13 @@ describe('state', () => { await config.sync(desiredResources) - assert.equal(addResourceMock.mock.calls.length, 0) - assert.equal(removeResourceAtMock.mock.calls.length, resources.length) + assert.equal(addResourceAtMock.mock.calls.length, 0) + assert.equal( + removeResourceAtMock.mock.calls.length, + new Set(resources.map(r => r.getStateAddress().toLowerCase())).size + ) - addResourceMock.mock.resetCalls() + addResourceAtMock.mock.resetCalls() removeResourceAtMock.mock.resetCalls() for (const resource of resources) { @@ -85,10 +88,10 @@ describe('state', () => { } await config.sync(desiredResources) - assert.equal(addResourceMock.mock.calls.length, 1) // adding github-mgmt/readme.md + assert.equal(addResourceAtMock.mock.calls.length, 1) // adding github-mgmt/readme.md assert.equal(removeResourceAtMock.mock.calls.length, 1) // removing github-mgmt/README.md - addResourceMock.mock.resetCalls() + addResourceAtMock.mock.resetCalls() removeResourceAtMock.mock.resetCalls() desiredResources.push(['id', new Repository('test')]) @@ -99,7 +102,7 @@ describe('state', () => { await config.sync(desiredResources) assert.equal( - addResourceMock.mock.calls.length, + addResourceAtMock.mock.calls.length, 1 + desiredResources.length - resources.length ) assert.equal(removeResourceAtMock.mock.calls.length, 1) diff --git a/scripts/package.json b/scripts/package.json index 996b777..7999be1 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -12,38 +12,45 @@ "lint:fix": "eslint --fix \"src/**/*.ts\" \"__tests__/**/*.ts\"", "test": "TF_EXEC=false TF_LOCK=false TF_WORKING_DIR=__tests__/__resources__/terraform GITHUB_DIR=__tests__/__resources__/github FILES_DIR=__tests__/__resources__/files GITHUB_ORG=default node --import tsx/esm --test --experimental-test-module-mocks \"__tests__/**/*.test.ts\"", "test:only": "TF_EXEC=false TF_LOCK=false TF_WORKING_DIR=__tests__/__resources__/terraform GITHUB_DIR=__tests__/__resources__/github FILES_DIR=__tests__/__resources__/files GITHUB_ORG=default node --import tsx/esm --test --test-only --experimental-test-module-mocks \"__tests__/**/*.test.ts\"", - "all": "npm run build && npm run format && npm run lint && npm test", + "all": "pnpm run build && pnpm run format && pnpm run lint && pnpm test", "schema": "ts-json-schema-generator --tsconfig tsconfig.json --path src/yaml/schema.ts --type ConfigSchema --out ../github/.schema.json", "main": "node lib/main.js" }, "dependencies": { "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", - "@actions/github": "^6.0.0", - "@octokit/auth-app": "^7.2.0", - "@octokit/graphql": "^8.2.2", - "@octokit/plugin-paginate-rest": "^11.6.0", - "@octokit/plugin-retry": "^7.2.1", - "@octokit/plugin-throttling": "^9.6.1", - "@octokit/rest": "^21.1.1", + "@actions/github": "^6.0.1", + "@octokit/auth-app": "^8.1.2", + "@octokit/core": "^7.0.6", + "@octokit/graphql": "^9.0.3", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-retry": "^8.0.3", + "@octokit/plugin-throttling": "^11.0.3", + "@octokit/rest": "^22.0.1", "class-transformer": "^0.5.1", "deep-diff": "^1.0.2", "hcl2-parser": "^1.0.3", "reflect-metadata": "^0.2.2", - "yaml": "^2.7.1" + "yaml": "^2.8.1" }, "devDependencies": { - "@eslint/js": "^9.24.0", - "@octokit/types": "^14.0.0", + "@eslint/js": "^9.39.1", + "@octokit/types": "^16.0.0", "@types/deep-diff": "^1.0.5", - "@types/node": "^22.14.1", - "eslint": "^9.25.0", - "eslint-config-prettier": "^10.1.2", - "eslint-plugin-prettier": "^5.2.6", - "prettier": "^3.5.3", + "@types/node": "^24.10.0", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.4", + "prettier": "^3.6.2", "ts-json-schema-generator": "^2.4.0", - "tsx": "^4.19.3", - "typescript": "^5.8.3", - "typescript-eslint": "^8.29.1" + "tsx": "^4.20.6", + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.4" + }, + "pnpm": { + "overrides": { + "glob": "^11.1.0", + "js-yaml": "^4.1.1" + } } } diff --git a/scripts/pnpm-lock.yaml b/scripts/pnpm-lock.yaml new file mode 100644 index 0000000..07cc064 --- /dev/null +++ b/scripts/pnpm-lock.yaml @@ -0,0 +1,2175 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + glob: ^11.1.0 + js-yaml: ^4.1.1 + +importers: + + .: + dependencies: + '@actions/core': + specifier: ^1.11.1 + version: 1.11.1 + '@actions/exec': + specifier: ^1.1.1 + version: 1.1.1 + '@actions/github': + specifier: ^6.0.1 + version: 6.0.1 + '@octokit/auth-app': + specifier: ^8.1.2 + version: 8.1.2 + '@octokit/core': + specifier: ^7.0.6 + version: 7.0.6 + '@octokit/graphql': + specifier: ^9.0.3 + version: 9.0.3 + '@octokit/plugin-paginate-rest': + specifier: ^14.0.0 + version: 14.0.0(@octokit/core@7.0.6) + '@octokit/plugin-retry': + specifier: ^8.0.3 + version: 8.0.3(@octokit/core@7.0.6) + '@octokit/plugin-throttling': + specifier: ^11.0.3 + version: 11.0.3(@octokit/core@7.0.6) + '@octokit/rest': + specifier: ^22.0.1 + version: 22.0.1 + class-transformer: + specifier: ^0.5.1 + version: 0.5.1 + deep-diff: + specifier: ^1.0.2 + version: 1.0.2 + hcl2-parser: + specifier: ^1.0.3 + version: 1.0.3 + reflect-metadata: + specifier: ^0.2.2 + version: 0.2.2 + yaml: + specifier: ^2.8.1 + version: 2.8.1 + devDependencies: + '@eslint/js': + specifier: ^9.39.1 + version: 9.39.1 + '@octokit/types': + specifier: ^16.0.0 + version: 16.0.0 + '@types/deep-diff': + specifier: ^1.0.5 + version: 1.0.5 + '@types/node': + specifier: ^24.10.0 + version: 24.10.0 + eslint: + specifier: ^9.39.1 + version: 9.39.1 + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.1) + eslint-plugin-prettier: + specifier: ^5.5.4 + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2) + prettier: + specifier: ^3.6.2 + version: 3.6.2 + ts-json-schema-generator: + specifier: ^2.4.0 + version: 2.4.0 + tsx: + specifier: ^4.20.6 + version: 4.20.6 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.46.4 + version: 8.46.4(eslint@9.39.1)(typescript@5.9.3) + +packages: + + '@actions/core@1.11.1': + resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} + + '@actions/exec@1.1.1': + resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} + + '@actions/github@6.0.1': + resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==} + + '@actions/http-client@2.2.3': + resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + + '@actions/io@1.1.3': + resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.1': + resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@octokit/auth-app@8.1.2': + resolution: {integrity: sha512-db8VO0PqXxfzI6GdjtgEFHY9tzqUql5xMFXYA12juq8TeTgPAuiiP3zid4h50lwlIP457p5+56PnJOgd2GGBuw==} + engines: {node: '>= 20'} + + '@octokit/auth-oauth-app@9.0.3': + resolution: {integrity: sha512-+yoFQquaF8OxJSxTb7rnytBIC2ZLbLqA/yb71I4ZXT9+Slw4TziV9j/kyGhUFRRTF2+7WlnIWsePZCWHs+OGjg==} + engines: {node: '>= 20'} + + '@octokit/auth-oauth-device@8.0.3': + resolution: {integrity: sha512-zh2W0mKKMh/VWZhSqlaCzY7qFyrgd9oTWmTmHaXnHNeQRCZr/CXy2jCgHo4e4dJVTiuxP5dLa0YM5p5QVhJHbw==} + engines: {node: '>= 20'} + + '@octokit/auth-oauth-user@6.0.2': + resolution: {integrity: sha512-qLoPPc6E6GJoz3XeDG/pnDhJpTkODTGG4kY0/Py154i/I003O9NazkrwJwRuzgCalhzyIeWQ+6MDvkUmKXjg/A==} + engines: {node: '>= 20'} + + '@octokit/auth-token@4.0.0': + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} + + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} + + '@octokit/core@5.2.2': + resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==} + engines: {node: '>= 18'} + + '@octokit/core@7.0.6': + resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} + engines: {node: '>= 20'} + + '@octokit/endpoint@11.0.2': + resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} + engines: {node: '>= 20'} + + '@octokit/endpoint@9.0.6': + resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==} + engines: {node: '>= 18'} + + '@octokit/graphql@7.1.1': + resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==} + engines: {node: '>= 18'} + + '@octokit/graphql@9.0.3': + resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} + engines: {node: '>= 20'} + + '@octokit/oauth-authorization-url@8.0.0': + resolution: {integrity: sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==} + engines: {node: '>= 20'} + + '@octokit/oauth-methods@6.0.2': + resolution: {integrity: sha512-HiNOO3MqLxlt5Da5bZbLV8Zarnphi4y9XehrbaFMkcoJ+FL7sMxH/UlUsCVxpddVu4qvNDrBdaTVE2o4ITK8ng==} + engines: {node: '>= 20'} + + '@octokit/openapi-types@20.0.0': + resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} + + '@octokit/openapi-types@24.2.0': + resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} + + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} + + '@octokit/plugin-paginate-rest@14.0.0': + resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-paginate-rest@9.2.2': + resolution: {integrity: sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-request-log@6.0.0': + resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-rest-endpoint-methods@10.4.1': + resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-rest-endpoint-methods@17.0.0': + resolution: {integrity: sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-retry@8.0.3': + resolution: {integrity: sha512-vKGx1i3MC0za53IzYBSBXcrhmd+daQDzuZfYDd52X5S0M2otf3kVZTVP8bLA3EkU0lTvd1WEC2OlNNa4G+dohA==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=7' + + '@octokit/plugin-throttling@11.0.3': + resolution: {integrity: sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': ^7.0.0 + + '@octokit/request-error@5.1.1': + resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==} + engines: {node: '>= 18'} + + '@octokit/request-error@7.0.2': + resolution: {integrity: sha512-U8piOROoQQUyExw5c6dTkU3GKxts5/ERRThIauNL7yaRoeXW0q/5bgHWT7JfWBw1UyrbK8ERId2wVkcB32n0uQ==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.6': + resolution: {integrity: sha512-FO+UgZCUu+pPnZAR+iKdUt64kPE7QW7ciqpldaMXaNzixz5Jld8dJ31LAUewk0cfSRkNSRKyqG438ba9c/qDlQ==} + engines: {node: '>= 20'} + + '@octokit/request@8.4.1': + resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} + engines: {node: '>= 18'} + + '@octokit/rest@22.0.1': + resolution: {integrity: sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==} + engines: {node: '>= 20'} + + '@octokit/types@12.6.0': + resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} + + '@octokit/types@13.10.0': + resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} + + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@types/deep-diff@1.0.5': + resolution: {integrity: sha512-PQyNSy1YMZU1hgZA5tTYfHPpUAo9Dorn1PZho2/budQLfqLu3JIP37JAavnwYpR1S2yFZTXa3hxaE4ifGW5jaA==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@24.10.0': + resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} + + '@typescript-eslint/eslint-plugin@8.46.4': + resolution: {integrity: sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.46.4 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.46.4': + resolution: {integrity: sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.46.4': + resolution: {integrity: sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.46.4': + resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.46.4': + resolution: {integrity: sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.46.4': + resolution: {integrity: sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.46.4': + resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.46.4': + resolution: {integrity: sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.46.4': + resolution: {integrity: sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.46.4': + resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-diff@1.0.2: + resolution: {integrity: sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-prettier@5.5.4: + resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.39.1: + resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-content-type-parse@3.0.0: + resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@11.1.0: + resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} + engines: {node: 20 || >=22} + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hcl2-parser@1.0.3: + resolution: {integrity: sha512-NQUm/BFF+2nrBfeqDhhsy4DxxiLHgkeE3FywtjFiXnjSUaio3w4Tz1MQ3vGJBUhyArzOXJ24pO7JwE5LAn7Ncg==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lru-cache@11.2.2: + resolution: {integrity: sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==} + engines: {node: 20 || >=22} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-json-schema-generator@2.4.0: + resolution: {integrity: sha512-HbmNsgs58CfdJq0gpteRTxPXG26zumezOs+SB9tgky6MpqiFgQwieCn2MW70+sxpHouZ/w9LW0V6L4ZQO4y1Ug==} + engines: {node: '>=18.0.0'} + hasBin: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.46.4: + resolution: {integrity: sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + engines: {node: '>=14.0'} + + universal-github-app-jwt@2.2.2: + resolution: {integrity: sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + + universal-user-agent@7.0.3: + resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@actions/core@1.11.1': + dependencies: + '@actions/exec': 1.1.1 + '@actions/http-client': 2.2.3 + + '@actions/exec@1.1.1': + dependencies: + '@actions/io': 1.1.3 + + '@actions/github@6.0.1': + dependencies: + '@actions/http-client': 2.2.3 + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.2) + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + undici: 5.29.0 + + '@actions/http-client@2.2.3': + dependencies: + tunnel: 0.0.6 + undici: 5.29.0 + + '@actions/io@1.1.3': {} + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1)': + dependencies: + eslint: 9.39.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.1': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@fastify/busboy@2.1.1': {} + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@octokit/auth-app@8.1.2': + dependencies: + '@octokit/auth-oauth-app': 9.0.3 + '@octokit/auth-oauth-user': 6.0.2 + '@octokit/request': 10.0.6 + '@octokit/request-error': 7.0.2 + '@octokit/types': 16.0.0 + toad-cache: 3.7.0 + universal-github-app-jwt: 2.2.2 + universal-user-agent: 7.0.3 + + '@octokit/auth-oauth-app@9.0.3': + dependencies: + '@octokit/auth-oauth-device': 8.0.3 + '@octokit/auth-oauth-user': 6.0.2 + '@octokit/request': 10.0.6 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/auth-oauth-device@8.0.3': + dependencies: + '@octokit/oauth-methods': 6.0.2 + '@octokit/request': 10.0.6 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/auth-oauth-user@6.0.2': + dependencies: + '@octokit/auth-oauth-device': 8.0.3 + '@octokit/oauth-methods': 6.0.2 + '@octokit/request': 10.0.6 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/auth-token@4.0.0': {} + + '@octokit/auth-token@6.0.0': {} + + '@octokit/core@5.2.2': + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.1 + '@octokit/request': 8.4.1 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + + '@octokit/core@7.0.6': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.3 + '@octokit/request': 10.0.6 + '@octokit/request-error': 7.0.2 + '@octokit/types': 16.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@11.0.2': + dependencies: + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@9.0.6': + dependencies: + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@7.1.1': + dependencies: + '@octokit/request': 8.4.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@9.0.3': + dependencies: + '@octokit/request': 10.0.6 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/oauth-authorization-url@8.0.0': {} + + '@octokit/oauth-methods@6.0.2': + dependencies: + '@octokit/oauth-authorization-url': 8.0.0 + '@octokit/request': 10.0.6 + '@octokit/request-error': 7.0.2 + '@octokit/types': 16.0.0 + + '@octokit/openapi-types@20.0.0': {} + + '@octokit/openapi-types@24.2.0': {} + + '@octokit/openapi-types@27.0.0': {} + + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + + '@octokit/plugin-paginate-rest@9.2.2(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 12.6.0 + + '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + + '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 12.6.0 + + '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + + '@octokit/plugin-retry@8.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/request-error': 7.0.2 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/plugin-throttling@11.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/request-error@5.1.1': + dependencies: + '@octokit/types': 13.10.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request-error@7.0.2': + dependencies: + '@octokit/types': 16.0.0 + + '@octokit/request@10.0.6': + dependencies: + '@octokit/endpoint': 11.0.2 + '@octokit/request-error': 7.0.2 + '@octokit/types': 16.0.0 + fast-content-type-parse: 3.0.0 + universal-user-agent: 7.0.3 + + '@octokit/request@8.4.1': + dependencies: + '@octokit/endpoint': 9.0.6 + '@octokit/request-error': 5.1.1 + '@octokit/types': 13.10.0 + universal-user-agent: 6.0.1 + + '@octokit/rest@22.0.1': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) + '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.6) + '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) + + '@octokit/types@12.6.0': + dependencies: + '@octokit/openapi-types': 20.0.0 + + '@octokit/types@13.10.0': + dependencies: + '@octokit/openapi-types': 24.2.0 + + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + + '@pkgr/core@0.2.9': {} + + '@types/deep-diff@1.0.5': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@24.10.0': + dependencies: + undici-types: 7.16.0 + + '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/type-utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + eslint: 9.39.1 + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.3 + eslint: 9.39.1 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.46.4': + dependencies: + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 + + '@typescript-eslint/tsconfig-utils@8.46.4(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.1 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.46.4': {} + + '@typescript-eslint/typescript-estree@8.46.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.46.4(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + eslint: 9.39.1 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.46.4': + dependencies: + '@typescript-eslint/types': 8.46.4 + eslint-visitor-keys: 4.2.1 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + before-after-hook@2.2.3: {} + + before-after-hook@4.0.0: {} + + bottleneck@2.19.5: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + class-transformer@0.5.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@13.1.0: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-diff@1.0.2: {} + + deep-is@0.1.4: {} + + deprecation@2.3.1: {} + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.1): + dependencies: + eslint: 9.39.1 + + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2): + dependencies: + eslint: 9.39.1 + prettier: 3.6.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.11 + optionalDependencies: + eslint-config-prettier: 10.1.8(eslint@9.39.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.39.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.39.1 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-content-type-parse@3.0.0: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@11.1.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.1.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.1 + + globals@14.0.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + hcl2-parser@1.0.3: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lru-cache@11.2.2: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minipass@7.1.2: {} + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + normalize-path@3.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.2 + minipass: 7.1.2 + + picomatch@2.3.1: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.6.2: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + reflect-metadata@0.2.2: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-stable-stringify@2.5.0: {} + + semver@7.7.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toad-cache@3.7.0: {} + + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-json-schema-generator@2.4.0: + dependencies: + '@types/json-schema': 7.0.15 + commander: 13.1.0 + glob: 11.1.0 + json5: 2.2.3 + normalize-path: 3.0.0 + safe-stable-stringify: 2.5.0 + tslib: 2.8.1 + typescript: 5.9.3 + + tslib@2.8.1: {} + + tsx@4.20.6: + dependencies: + esbuild: 0.25.12 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + tunnel@0.0.6: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.46.4(eslint@9.39.1)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3) + eslint: 9.39.1 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici-types@7.16.0: {} + + undici@5.29.0: + dependencies: + '@fastify/busboy': 2.1.1 + + universal-github-app-jwt@2.2.2: {} + + universal-user-agent@6.0.1: {} + + universal-user-agent@7.0.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + yaml@2.8.1: {} + + yocto-queue@0.1.0: {} diff --git a/scripts/pnpm-workspace.yaml b/scripts/pnpm-workspace.yaml new file mode 100644 index 0000000..36b9913 --- /dev/null +++ b/scripts/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +minimumReleaseAge: 40320 +minimumReleaseAgeExclude: + - glob + - js-yaml diff --git a/scripts/src/actions/find-sha-for-plan.ts b/scripts/src/actions/find-sha-for-plan.ts index 5049359..9184425 100644 --- a/scripts/src/actions/find-sha-for-plan.ts +++ b/scripts/src/actions/find-sha-for-plan.ts @@ -6,22 +6,29 @@ async function findShaForPlan(): Promise { const github = await GitHub.getGitHub() if (context.eventName !== 'push') { + console.log( + `This is not a push event ("${context.eventName}"); returning "${context.sha}"` + ) return context.sha } + const q = `repo:${context.repo.owner}/${context.repo.repo} ${context.sha} type:pr is:merged` + console.log(`Running advanced query: ${q}`) const pulls = await github.client.paginate( github.client.search.issuesAndPullRequests, { - q: `repository:${context.repo.owner}/${context.repo.repo} ${context.sha} type:pr is:merged`, + q, advanced_search: 'true' } ) if (pulls.length === 0) { + console.log('Got 0 pull request, returning empty string') return '' } const pull = pulls[0] + console.log(`Processing pull request number ${pull.number}`) const commits = await github.client.paginate( github.client.pulls.listCommits, { @@ -31,9 +38,12 @@ async function findShaForPlan(): Promise { ) if (commits.length === 0) { + console.log('Found 0 commits, returning empty string') return '' } + const commit = commits[commits.length - 1] + console.log(`Returning commit ${commit.sha}`) return commits[commits.length - 1].sha } diff --git a/scripts/src/resources/repository-branch-protection-rule.ts b/scripts/src/resources/repository-branch-protection-rule.ts index d2472e7..b5cf75d 100644 --- a/scripts/src/resources/repository-branch-protection-rule.ts +++ b/scripts/src/resources/repository-branch-protection-rule.ts @@ -11,6 +11,7 @@ class RequiredPullRequestReviews { @Expose() dismissal_restrictions?: string[] @Expose() pull_request_bypassers?: string[] @Expose() require_code_owner_reviews?: boolean + @Expose() require_last_push_approval?: boolean @Expose() required_approving_review_count?: number @Expose() restrict_dismissals?: boolean } @@ -21,6 +22,12 @@ class RequiredStatusChecks { @Expose() strict?: boolean } +@Exclude() +class RestrictPushes { + @Expose() blocks_creations?: boolean + @Expose() push_allowances?: string[] +} + @Exclude() export class RepositoryBranchProtectionRule implements Resource { static StateType = 'github_branch_protection' as const @@ -120,10 +127,9 @@ export class RepositoryBranchProtectionRule implements Resource { @Expose() allows_deletions?: boolean @Expose() allows_force_pushes?: boolean - @Expose() blocks_creations?: boolean @Expose() enforce_admins?: boolean + @Expose() force_push_bypassers?: string[] @Expose() lock_branch?: boolean - @Expose() push_restrictions?: string[] @Expose() require_conversation_resolution?: boolean @Expose() require_signed_commits?: boolean @Expose() required_linear_history?: boolean @@ -133,6 +139,9 @@ export class RepositoryBranchProtectionRule implements Resource { @Expose() @Type(() => RequiredStatusChecks) required_status_checks?: RequiredStatusChecks + @Expose() + @Type(() => RestrictPushes) + restrict_pushes?: RestrictPushes getSchemaPath(_schema: ConfigSchema): Path { return ['repositories', this.repository, 'branch_protection', this.pattern] diff --git a/scripts/src/resources/repository-label.ts b/scripts/src/resources/repository-label.ts index 8e53023..9537cce 100644 --- a/scripts/src/resources/repository-label.ts +++ b/scripts/src/resources/repository-label.ts @@ -6,7 +6,7 @@ import {Id, StateSchema} from '../terraform/schema.js' @Exclude() export class RepositoryLabel implements Resource { - static StateType = 'github_issue_label' as const + static StateType = 'github_issue_labels' as const static async FromGitHub( _labels: RepositoryLabel[] ): Promise<[Id, RepositoryLabel][]> { @@ -15,7 +15,7 @@ export class RepositoryLabel implements Resource { const result: [Id, RepositoryLabel][] = [] for (const label of labels) { result.push([ - `${label.repository.name}:${label.label.name}`, + label.repository.name, new RepositoryLabel(label.repository.name, label.label.name) ]) } @@ -29,15 +29,14 @@ export class RepositoryLabel implements Resource { resource.type === RepositoryLabel.StateType && resource.mode === 'managed' ) { - labels.push( - plainToClassFromExist( - new RepositoryLabel( - resource.values.repository, - resource.values.name - ), - resource.values + for (const label of resource.values.label ?? []) { + labels.push( + plainToClassFromExist( + new RepositoryLabel(resource.values.repository, label.name), + label + ) ) - ) + } } } } @@ -85,6 +84,6 @@ export class RepositoryLabel implements Resource { } getStateAddress(): string { - return `${RepositoryLabel.StateType}.this["${this.repository}:${this.name}"]` + return `${RepositoryLabel.StateType}.this["${this.repository}"]` } } diff --git a/scripts/src/resources/repository.ts b/scripts/src/resources/repository.ts index 87e020d..d9eed32 100644 --- a/scripts/src/resources/repository.ts +++ b/scripts/src/resources/repository.ts @@ -13,6 +13,7 @@ class PageSource { @Exclude() class Pages { @Expose() source?: PageSource + @Expose() build_type?: 'legacy' | 'workflow' @Expose() cname?: string } @@ -20,6 +21,7 @@ class Pages { class Template { @Expose() owner?: string @Expose() repository?: string + @Expose() include_all_branches?: boolean } export enum Visibility { @@ -138,6 +140,7 @@ export class Repository implements Resource { @Expose() topics?: string[] @Expose() visibility?: Visibility @Expose() vulnerability_alerts?: boolean + @Expose() web_commit_signoff_required?: boolean getSchemaPath(_schema: ConfigSchema): Path { return ['repositories', this.name] diff --git a/scripts/src/terraform/schema.ts b/scripts/src/terraform/schema.ts index 0c11bc8..fded2c2 100644 --- a/scripts/src/terraform/schema.ts +++ b/scripts/src/terraform/schema.ts @@ -32,10 +32,14 @@ type ResourceSchema = { } } | { - type: 'github_issue_label' + type: 'github_issue_labels' values: { - name: string repository: string + label?: { + name: string + color: string + description: string + }[] } } | { diff --git a/scripts/src/terraform/state.ts b/scripts/src/terraform/state.ts index 57ac365..a2d2ced 100644 --- a/scripts/src/terraform/state.ts +++ b/scripts/src/terraform/state.ts @@ -162,27 +162,23 @@ export class State { return !Locals.getLocals().resource_types.includes(resourceClass.StateType) } - async addResource(id: Id, resource: Resource): Promise { - await this.addResourceAt(id, resource.getStateAddress().toLowerCase()) - } - async addResourceAt(id: Id, address: string): Promise { if (env.TF_EXEC === 'true') { + const [, key, value] = address.match(/^([^.]+)\.this\["([^"]+)"\]$/)! + const resources = JSON.stringify({ + [key]: { + [value]: {} + } + }).replaceAll('"', '\\"') + const addr = address.replaceAll('"', '\\"') await cli.exec( - `terraform import -lock=${env.TF_LOCK} "${address.replaceAll( - '"', - '\\"' - )}" "${id}"`, + `terraform import -lock=${env.TF_LOCK} -var "resources=${resources}" "${addr}" "${id}"`, undefined, {cwd: env.TF_WORKING_DIR} ) } } - async removeResource(resource: Resource): Promise { - await this.removeResourceAt(resource.getStateAddress().toLowerCase()) - } - async removeResourceAt(address: string): Promise { if (env.TF_EXEC === 'true') { await cli.exec( @@ -197,21 +193,19 @@ export class State { } async sync(resources: [Id, Resource][]): Promise { - const addresses = this.getAllAddresses() + const addresses = new Set(this.getAllAddresses()) + const addressToId = new Map() + for (const [id, resource] of resources) { + addressToId.set(resource.getStateAddress().toLowerCase(), id) + } for (const address of addresses) { - if ( - !resources.some( - ([_, r]) => r.getStateAddress().toLowerCase() === address - ) - ) { + if (!addressToId.has(address)) { await this.removeResourceAt(address) } } - for (const [id, resource] of resources) { - if ( - !addresses.some(a => a === resource.getStateAddress().toLowerCase()) - ) { - await this.addResource(id, resource) + for (const [address, id] of addressToId) { + if (!addresses.has(address)) { + await this.addResourceAt(id, address) } } } diff --git a/terraform/bootstrap/aws.tf b/terraform/bootstrap/aws.tf index 19cc9a4..bdaf058 100644 --- a/terraform/bootstrap/aws.tf +++ b/terraform/bootstrap/aws.tf @@ -12,7 +12,7 @@ terraform { } } - required_version = "~> 1.2.9" + required_version = "~> 1.12.0" } provider "aws" {} diff --git a/terraform/locals.tf b/terraform/locals.tf index b00ac8d..fbf0079 100644 --- a/terraform/locals.tf +++ b/terraform/locals.tf @@ -6,8 +6,8 @@ locals { state = jsondecode(file("${path.module}/${local.organization}.tfstate.json")) ignore = { "repositories" = [] - "teams" = [] - "users" = [] + "teams" = [] + "users" = [] } sources = { "config" = { @@ -128,23 +128,25 @@ locals { ]) : lower("${item.repository}/${item.file}") => item } } - "github_issue_label" = { + "github_issue_labels" = { "this" = { - for item in flatten([ - for repository, config in lookup(local.config, "repositories", {}) : [ - for name, config in lookup(config, "labels", {}) : merge(config, { - repository = repository - name = name - }) - ] - ]) : lower("${item.repository}:${item.name}") => item + for item in [ + for repository, config in lookup(local.config, "repositories", {}) : { + repository = repository + label = [ + for name, config in lookup(config, "labels", {}) : merge(config, { + name = name + }) + ] + } if contains(keys(config), "labels") + ] : lower("${item.repository}") => item } } } "state" = lookup({ for mode, item in { for item in try(local.state.values.root_module.resources, []) : item.mode => item... - } : mode => { + } : mode => { for type, item in { for item in item : item.type => item... } : type => { @@ -171,13 +173,13 @@ locals { "github_repository" = { for item in [ for repository, config in local.sources.config.github_repository.this : - try(config.archived, false) ? { - source = "state" - index = repository + try(config.archived, false) && try(contains(keys(local.sources.state.github_repository.this), repository), false) ? { + source = "state" + index = repository archived = config.archived } : { - source = "config" - index = repository + source = "config" + index = repository archived = try(config.archived, false) } ] : item.index => merge(local.sources[item.source].github_repository.this[item.index], { archived = item.archived }) @@ -266,22 +268,22 @@ locals { ]) ]) : item.index => local.sources[item.source].github_repository_file.this[item.index] } - "github_issue_label" = { + "github_issue_labels" = { for item in flatten([ for repository, config in local.sources.config.github_repository.this : flatten([ try(config.archived, false) ? [ - for label, config in try(local.sources.state.github_issue_label.this, {}) : { + for labelsRepository, config in try(local.sources.state.github_issue_labels.this, {}) : { source = "state" - index = label + index = labelsRepository } if lower(config.repository) == repository ] : [ - for label, config in local.sources.config.github_issue_label.this : { + for labelsRepository, config in local.sources.config.github_issue_labels.this : { source = "config" - index = label + index = labelsRepository } if lower(config.repository) == repository ] ]) - ]) : item.index => local.sources[item.source].github_issue_label.this[item.index] + ]) : item.index => local.sources[item.source].github_issue_labels.this[item.index] } } } diff --git a/terraform/resources.tf b/terraform/resources.tf index 755f261..8ba0fde 100644 --- a/terraform/resources.tf +++ b/terraform/resources.tf @@ -1,8 +1,9 @@ resource "github_membership" "this" { - for_each = local.resources.github_membership + for_each = try(var.resources.github_membership, local.resources.github_membership) username = each.value.username role = each.value.role + # downgrade_on_destroy = try(each.value.downgrade_on_destroy, null) lifecycle { ignore_changes = [] @@ -11,7 +12,7 @@ resource "github_membership" "this" { } resource "github_repository" "this" { - for_each = local.resources.github_repository + for_each = try(var.resources.github_repository, local.resources.github_repository) name = each.value.name allow_auto_merge = try(each.value.allow_auto_merge, null) @@ -37,11 +38,13 @@ resource "github_repository" "this" { license_template = try(each.value.license_template, null) merge_commit_message = try(each.value.merge_commit_message, null) merge_commit_title = try(each.value.merge_commit_title, null) - squash_merge_commit_message = try(each.value.squash_merge_commit_message, null) - squash_merge_commit_title = try(each.value.squash_merge_commit_title, null) - topics = try(each.value.topics, null) - visibility = try(each.value.visibility, null) - vulnerability_alerts = try(each.value.vulnerability_alerts, null) + # private = try(each.value.private, null) + squash_merge_commit_message = try(each.value.squash_merge_commit_message, null) + squash_merge_commit_title = try(each.value.squash_merge_commit_title, null) + topics = try(each.value.topics, null) + visibility = try(each.value.visibility, null) + vulnerability_alerts = try(each.value.vulnerability_alerts, null) + web_commit_signoff_required = try(each.value.web_commit_signoff_required, null) dynamic "security_and_analysis" { for_each = try(each.value.security_and_analysis, []) @@ -71,7 +74,8 @@ resource "github_repository" "this" { dynamic "pages" { for_each = try(each.value.pages, []) content { - cname = try(pages.value["cname"], null) + build_type = try(pages.value["build_type"], null) + cname = try(pages.value["cname"], null) dynamic "source" { for_each = pages.value["source"] content { @@ -84,8 +88,9 @@ resource "github_repository" "this" { dynamic "template" { for_each = try(each.value.template, []) content { - owner = template.value["owner"] - repository = template.value["repository"] + owner = template.value["owner"] + repository = template.value["repository"] + include_all_branches = try(template.value["include_all_branches"], null) } } @@ -96,13 +101,14 @@ resource "github_repository" "this" { } resource "github_repository_collaborator" "this" { - for_each = local.resources.github_repository_collaborator + for_each = try(var.resources.github_repository_collaborator, local.resources.github_repository_collaborator) depends_on = [github_repository.this] repository = each.value.repository username = each.value.username permission = each.value.permission + # permission_diff_suppression = try(each.value.permission_diff_suppression, null) lifecycle { ignore_changes = [] @@ -110,7 +116,7 @@ resource "github_repository_collaborator" "this" { } resource "github_branch_protection" "this" { - for_each = local.resources.github_branch_protection + for_each = try(var.resources.github_branch_protection, local.resources.github_branch_protection) pattern = each.value.pattern @@ -118,10 +124,9 @@ resource "github_branch_protection" "this" { allows_deletions = try(each.value.allows_deletions, null) allows_force_pushes = try(each.value.allows_force_pushes, null) - blocks_creations = try(each.value.blocks_creations, null) enforce_admins = try(each.value.enforce_admins, null) + force_push_bypassers = try(each.value.force_push_bypassers, null) lock_branch = try(each.value.lock_branch, null) - push_restrictions = try(each.value.push_restrictions, null) require_conversation_resolution = try(each.value.require_conversation_resolution, null) require_signed_commits = try(each.value.require_signed_commits, null) required_linear_history = try(each.value.required_linear_history, null) @@ -133,6 +138,7 @@ resource "github_branch_protection" "this" { dismissal_restrictions = try(required_pull_request_reviews.value["dismissal_restrictions"], null) pull_request_bypassers = try(required_pull_request_reviews.value["pull_request_bypassers"], null) require_code_owner_reviews = try(required_pull_request_reviews.value["require_code_owner_reviews"], null) + require_last_push_approval = try(required_pull_request_reviews.value["require_last_push_approval"], null) required_approving_review_count = try(required_pull_request_reviews.value["required_approving_review_count"], null) restrict_dismissals = try(required_pull_request_reviews.value["restrict_dismissals"], null) } @@ -144,17 +150,26 @@ resource "github_branch_protection" "this" { strict = try(required_status_checks.value["strict"], null) } } + dynamic "restrict_pushes" { + for_each = try(each.value.restrict_pushes, []) + content { + blocks_creations = try(restrict_pushes.value["blocks_creations"], null) + push_allowances = try(restrict_pushes.value["push_allowances"], null) + } + } } resource "github_team" "this" { - for_each = local.resources.github_team + for_each = try(var.resources.github_team, local.resources.github_team) name = each.value.name parent_team_id = try(try(element(data.github_organization_teams.this[0].teams, index(data.github_organization_teams.this[0].teams.*.name, each.value.parent_team_id)).id, each.value.parent_team_id), null) + # create_default_maintainer = try(each.value.create_default_maintainer, null) description = try(each.value.description, null) - privacy = try(each.value.privacy, null) + # ldap_dn = try(each.value.ldap_dn, null) + privacy = try(each.value.privacy, null) lifecycle { ignore_changes = [] @@ -162,7 +177,7 @@ resource "github_team" "this" { } resource "github_team_repository" "this" { - for_each = local.resources.github_team_repository + for_each = try(var.resources.github_team_repository, local.resources.github_team_repository) depends_on = [github_repository.this] @@ -177,7 +192,7 @@ resource "github_team_repository" "this" { } resource "github_team_membership" "this" { - for_each = local.resources.github_team_membership + for_each = try(var.resources.github_team_membership, local.resources.github_team_membership) username = each.value.username role = each.value.role @@ -190,11 +205,14 @@ resource "github_team_membership" "this" { } resource "github_repository_file" "this" { - for_each = local.resources.github_repository_file + for_each = try(var.resources.github_repository_file, local.resources.github_repository_file) repository = each.value.repository file = each.value.file content = each.value.content + # autocreate_branch = try(each.value.autocreate_branch, null) + # autocreate_branch_source_branch = try(each.value.autocreate_branch_source_branch, null) + # autocreate_branch_source_sha = try(each.value.autocreate_branch_source_sha, null) # Since 5.25.0 the branch attribute defaults to the default branch of the repository # branch = try(each.value.branch, null) branch = lookup(each.value, "branch", lookup(lookup(github_repository.this, each.value.repository, {}), "default_branch", null)) @@ -209,16 +227,21 @@ resource "github_repository_file" "this" { } } -resource "github_issue_label" "this" { - for_each = local.resources.github_issue_label +resource "github_issue_labels" "this" { + for_each = try(var.resources.github_issue_labels, local.resources.github_issue_labels) depends_on = [github_repository.this] repository = each.value.repository - name = each.value.name - color = try(each.value.color, null) - description = try(each.value.description, null) + dynamic "label" { + for_each = try(each.value.label, []) + content { + color = try(label.value["color"], "7B42BC") + description = try(label.value["description"], "") + name = label.value["name"] + } + } lifecycle { ignore_changes = [] diff --git a/terraform/terraform.tf b/terraform/terraform.tf index a3c809c..1ac9da9 100644 --- a/terraform/terraform.tf +++ b/terraform/terraform.tf @@ -2,10 +2,10 @@ terraform { required_providers { github = { source = "integrations/github" - version = "5.25.0" + version = "~> 6.6.0" } } # https://github.com/hashicorp/terraform/issues/32329 - required_version = "~> 1.2.9" + required_version = "~> 1.12.0" } diff --git a/terraform/variables.tf b/terraform/variables.tf index ee53007..eacdbfc 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -3,3 +3,19 @@ variable "write_delay_ms" { type = number default = 1000 } + +variable "resources" { + description = "Resources to import." + type = object({ + github_membership = optional(map(any), {}) + github_repository = optional(map(any), {}) + github_repository_collaborator = optional(map(any), {}) + github_branch_protection = optional(map(any), {}) + github_team = optional(map(any), {}) + github_team_repository = optional(map(any), {}) + github_team_membership = optional(map(any), {}) + github_repository_file = optional(map(any), {}) + github_issue_labels = optional(map(any), {}) + }) + default = null +}