From 3f5d0273990d6b21780e41bb7395422a16b54793 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Wed, 23 Oct 2024 16:33:24 -0700 Subject: [PATCH] Add support for universes regional secrets This adds support for regional secrets, but it's intentionally undocumented. It also adds support for universes, which is documented. --- .github/workflows/draft-release.yml | 2 +- .github/workflows/integration.yml | 6 +- .github/workflows/release.yml | 3 +- README.md | 13 +- action.yml | 9 + package-lock.json | 528 ++++++++++++++-------------- package.json | 23 +- src/client.ts | 44 +-- src/main.ts | 10 +- src/reference.ts | 56 ++- tests/reference.test.ts | 199 ++++------- 11 files changed, 424 insertions(+), 469 deletions(-) diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index 8f23e58..6c47e88 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -21,4 +21,4 @@ jobs: version_strategy: '${{ github.event.inputs.version_strategy }}' # secrets must be explicitly passed to reusable workflows https://docs.github.com/en/enterprise-cloud@latest/actions/using-workflows/reusing-workflows#using-inputs-and-secrets-in-a-reusable-workflow secrets: - ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}' \ No newline at end of file + ACTIONS_BOT_TOKEN: '${{ secrets.ACTIONS_BOT_TOKEN }}' diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 15f7bdc..609e4fb 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -44,9 +44,10 @@ jobs: secrets: |- token:${{ vars.SECRET_NAME }} password:${{ vars.SECRET_VERSION_NAME }} + regional:${{ vars.REGIONAL_SECRET_NAME }} - name: 'outputs' - run: echo '${{ steps.secrets.outputs.token }}${{ steps.secrets.outputs.password }}' + run: echo '${{ steps.secrets.outputs.token }}${{ steps.secrets.outputs.password }}${{ steps.secrets-encoded.outputs.regional }}' - id: 'secrets-encoded' name: 'secrets-encoded' @@ -56,6 +57,7 @@ jobs: secrets: |- token:${{ vars.SECRET_NAME }} password:${{ vars.SECRET_VERSION_NAME }} + regional:${{ vars.REGIONAL_SECRET_NAME }} - name: 'outputs-encoded' - run: echo '${{ steps.secrets-encoded.outputs.token }}${{ steps.secrets-encoded.outputs.password }}' + run: echo '${{ steps.secrets-encoded.outputs.token }}${{ steps.secrets-encoded.outputs.password }}${{ steps.secrets-encoded.outputs.regional }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15eea04..89296a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,7 @@ on: jobs: release: - if: "startsWith(github.event.head_commit.message, 'Release: v')" + if: |- + ${{ startsWith(github.event.head_commit.message, 'Release: v') }} name: 'Release' uses: 'google-github-actions/.github/.github/workflows/release.yml@v0' diff --git a/README.md b/README.md index 080cdfa..fdcec09 100644 --- a/README.md +++ b/README.md @@ -89,14 +89,6 @@ jobs: / ``` -- region: _(Optional)_ Region/location to fetch secrets from specific region. List of supported regions for Secret Manager can be [seen here](https://cloud.google.com/secret-manager/docs/locations). - ```yaml - region: us-west1 - secrets: |- - output1:my-project/my-secret1 - output2:my-project/my-secret2 - ``` - - min_mask_length: _(Optional, default: `4`)_ Minimum line length for a secret to be masked. Extremely short secrets (e.g. `{` or `a`) can make GitHub Actions log output unreadable. This is especially important for multi-line secrets, since each line of the secret @@ -111,6 +103,11 @@ jobs: available encoding types, please see the [Node.js Buffer and character encodings](https://nodejs.org/docs/latest/api/buffer.html#buffers-and-character-encodings). +- universe: _(Optional, default: `googleapis.com`)_ The Google Cloud universe to use for constructing API endpoints. The + default universe is "googleapis.com", which corresponds to + https://cloud.google.com. Trusted Partner Cloud and Google Distributed + Hosted Cloud should set this to their universe address. + diff --git a/action.yml b/action.yml index d5d4147..1e5fbf6 100644 --- a/action.yml +++ b/action.yml @@ -76,6 +76,15 @@ inputs: required: false default: 'utf8' + universe: + description: |- + The Google Cloud universe to use for constructing API endpoints. The + default universe is "googleapis.com", which corresponds to + https://cloud.google.com. Trusted Partner Cloud and Google Distributed + Hosted Cloud should set this to their universe address. + required: false + default: 'googleapis.com' + outputs: secrets: description: |- diff --git a/package-lock.json b/package-lock.json index 87974e7..f59ff5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,47 +9,63 @@ "version": "2.1.4", "license": "Apache-2.0", "dependencies": { - "@actions/core": "^1.10.1", - "@actions/http-client": "^2.2.1", + "@actions/core": "^1.11.1", + "@actions/http-client": "^2.2.3", "@google-github-actions/actions-utils": "^0.8.3", - "google-auth-library": "^9.13.0" + "google-auth-library": "^9.14.2", + "npm-check-updates": "^17.1.4" }, "devDependencies": { "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.8.0", - "@types/node": "^22.1.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "@vercel/ncc": "^0.38.1", - "eslint": "^9.8.0", + "@eslint/js": "^9.13.0", + "@types/node": "^22.7.9", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", + "@vercel/ncc": "^0.38.2", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "prettier": "^3.3.3", "ts-node": "^10.9.2", - "typescript": "^5.5.4", - "typescript-eslint": "^8.0.0" + "typescript": "^5.6.3", + "typescript-eslint": "^8.11.0" } }, "node_modules/@actions/core": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", - "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", + "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", "license": "MIT", "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/exec": "^1.1.1", + "@actions/http-client": "^2.0.1" + } + }, + "node_modules/@actions/exec": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", + "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", + "license": "MIT", + "dependencies": { + "@actions/io": "^1.0.1" } }, "node_modules/@actions/http-client": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.1.tgz", - "integrity": "sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz", + "integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==", "license": "MIT", "dependencies": { "tunnel": "^0.0.6", "undici": "^5.25.4" } }, + "node_modules/@actions/io": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", + "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", + "license": "MIT" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -80,9 +96,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, "license": "MIT", "engines": { @@ -90,9 +106,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -104,6 +120,16 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -129,9 +155,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true, "license": "MIT", "engines": { @@ -148,6 +174,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", + "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@fastify/busboy": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", @@ -169,6 +208,30 @@ "actions-gen-readme": "bin/actions-gen-readme.mjs" } }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -184,9 +247,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -304,28 +367,42 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", + "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.2" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0.tgz", - "integrity": "sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", + "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/type-utils": "8.0.0", - "@typescript-eslint/utils": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/type-utils": "8.11.0", + "@typescript-eslint/utils": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -349,16 +426,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.0.tgz", - "integrity": "sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", + "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/typescript-estree": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4" }, "engines": { @@ -378,14 +455,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0.tgz", - "integrity": "sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", + "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0" + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -396,14 +473,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.0.tgz", - "integrity": "sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", + "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.0.0", - "@typescript-eslint/utils": "8.0.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/utils": "8.11.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -421,9 +498,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0.tgz", - "integrity": "sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", + "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", "dev": true, "license": "MIT", "engines": { @@ -435,16 +512,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0.tgz", - "integrity": "sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", + "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/visitor-keys": "8.0.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", @@ -490,16 +567,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0.tgz", - "integrity": "sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", + "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.0", - "@typescript-eslint/types": "8.0.0", - "@typescript-eslint/typescript-estree": "8.0.0" + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -513,13 +590,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0.tgz", - "integrity": "sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", + "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.0", + "@typescript-eslint/types": "8.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -531,9 +608,9 @@ } }, "node_modules/@vercel/ncc": { - "version": "0.38.1", - "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz", - "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==", + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.2.tgz", + "integrity": "sha512-3yel3jaxUg9pHBv4+KeC9qlbdZPug+UMtUOlhvpDYCMSgcNSrS2Hv1LoqMsOV7hf2lYscx+BESfJOIla1WsmMQ==", "dev": true, "license": "MIT", "bin": { @@ -541,9 +618,9 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, "license": "MIT", "bin": { @@ -564,9 +641,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, "license": "MIT", "dependencies": { @@ -605,16 +682,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -645,16 +712,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -798,12 +855,12 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -831,19 +888,6 @@ "node": ">=0.3.1" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -867,28 +911,32 @@ } }, "node_modules/eslint": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", - "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.8.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -898,14 +946,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { @@ -916,6 +961,14 @@ }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { @@ -963,9 +1016,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -993,9 +1046,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1006,15 +1059,15 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1024,9 +1077,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1221,34 +1274,21 @@ "license": "ISC" }, "node_modules/gaxios": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", - "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^10.0.0" + "uuid": "^9.0.1" }, "engines": { "node": ">=14" } }, - "node_modules/gaxios/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/gcp-metadata": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", @@ -1288,31 +1328,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/google-auth-library": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.13.0.tgz", - "integrity": "sha512-p9Y03Uzp/Igcs36zAaB0XTSwZ8Y0/tpYiz5KIde5By+H9DCVUSYtDWZu6aFXsWTqENMb8BD/pDT3hR8NVrPkfA==", + "version": "9.14.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", + "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", @@ -1370,9 +1389,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -1439,16 +1458,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -1597,9 +1606,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -1624,9 +1633,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/natural-compare": { @@ -1656,6 +1665,20 @@ } } }, + "node_modules/npm-check-updates": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.4.tgz", + "integrity": "sha512-crOUeN2GngqlkRCFQ/zi1zsneWd9IGZgIfAWYGAuhYiPnfbBTmJBL7Yq1wI0e1dsW8CfWc+h348WmfCREqeOBA==", + "license": "Apache-2.0", + "bin": { + "ncu": "build/cli.js", + "npm-check-updates": "build/cli.js" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0", + "npm": ">=8.12.1" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -1739,16 +1762,6 @@ "node": ">=8" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1933,29 +1946,6 @@ "node": ">=8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1983,9 +1973,9 @@ } }, "node_modules/synckit": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", - "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", "dev": true, "license": "MIT", "dependencies": { @@ -2083,9 +2073,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", "dev": true, "license": "0BSD" }, @@ -2112,9 +2102,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2126,15 +2116,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.0.0.tgz", - "integrity": "sha512-yQWBJutWL1PmpmDddIOl9/Mi6vZjqNCjqSGBMQ4vsc2Aiodk0SnbQQWPXbSy0HNuKCuGkw1+u4aQ2mO40TdhDQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.11.0.tgz", + "integrity": "sha512-cBRGnW3FSlxaYwU8KfAewxFK5uzeOAp0l2KebIlPDOT5olVi65KDG/yjBooPBG0kGW/HLkoz1c/iuBFehcS3IA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.0.0", - "@typescript-eslint/parser": "8.0.0", - "@typescript-eslint/utils": "8.0.0" + "@typescript-eslint/eslint-plugin": "8.11.0", + "@typescript-eslint/parser": "8.11.0", + "@typescript-eslint/utils": "8.11.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2162,9 +2152,9 @@ } }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, @@ -2179,9 +2169,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -2237,9 +2231,9 @@ } }, "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "license": "ISC", "bin": { "yaml": "bin.mjs" diff --git a/package.json b/package.json index 9447069..8f4eea9 100644 --- a/package.json +++ b/package.json @@ -23,24 +23,25 @@ "author": "GoogleCloudPlatform", "license": "Apache-2.0", "dependencies": { - "@actions/core": "^1.10.1", - "@actions/http-client": "^2.2.1", + "@actions/core": "^1.11.1", + "@actions/http-client": "^2.2.3", "@google-github-actions/actions-utils": "^0.8.3", - "google-auth-library": "^9.13.0" + "google-auth-library": "^9.14.2", + "npm-check-updates": "^17.1.4" }, "devDependencies": { "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.8.0", - "@types/node": "^22.1.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "@vercel/ncc": "^0.38.1", + "@eslint/js": "^9.13.0", + "@types/node": "^22.7.9", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", + "@vercel/ncc": "^0.38.2", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "eslint": "^9.8.0", "prettier": "^3.3.3", "ts-node": "^10.9.2", - "typescript-eslint": "^8.0.0", - "typescript": "^5.5.4" + "typescript": "^5.6.3", + "typescript-eslint": "^8.11.0" } } diff --git a/src/client.ts b/src/client.ts index 606a906..c37564c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -15,9 +15,11 @@ */ import { GoogleAuth } from 'google-auth-library'; -import { errorMessage } from '@google-github-actions/actions-utils'; +import { errorMessage, expandUniverseEndpoints } from '@google-github-actions/actions-utils'; import { HttpClient } from '@actions/http-client'; +import { Reference } from './reference'; + // Do not listen to the linter - this can NOT be rewritten as an ES6 import statement. const { version: appVersion } = require('../package.json'); @@ -30,7 +32,7 @@ const userAgent = `google-github-actions:get-secretmanager-secrets/${appVersion} * @param endpoint GCP endpoint (useful for testing). */ type ClientOptions = { - endpoint?: string; + universe?: string; }; /** @@ -52,23 +54,22 @@ type AccessSecretVersionResponse = { * @returns Client */ export class Client { - // location placeholder for secret reference with location - readonly defaultEndpoint = 'https://secretmanager{location}.googleapis.com/v1'; - readonly defaultScope = 'https://www.googleapis.com/auth/cloud-platform'; + readonly _endpoints = { + secretmanager: 'https://secretmanager.{universe}/v1', + }; readonly auth: GoogleAuth; - readonly endpoint: string; readonly client: HttpClient; constructor(opts?: ClientOptions) { - this.endpoint = opts?.endpoint || this.defaultEndpoint; this.auth = new GoogleAuth({ - scopes: [this.defaultScope], + scopes: ['https://www.googleapis.com/auth/cloud-platform'], }); this.client = new HttpClient(userAgent, [], { allowRetries: true, maxRetries: 3, }); + this._endpoints = expandUniverseEndpoints(this._endpoints, opts?.universe); } /** @@ -77,23 +78,22 @@ export class Client { * @param ref String of the full secret reference. * @returns string secret contents. */ - async accessSecret(ref: string, location: string, encoding: BufferEncoding): Promise { - if (!ref) { - throw new Error(`Secret ref "${ref}" is empty!`); + async accessSecret(ref: Reference, encoding: BufferEncoding): Promise { + const selfLink = ref.selfLink(); + if (!selfLink) { + throw new Error(`Secret ref "${selfLink}" is empty!`); } // Updating endpoint with location if available in reference - let location_endpoint = this.endpoint; - if (location) { - // updating endpoint with location from reference (ie.secretmanager.{location}.rep.googleapis.com/v1 ) - location_endpoint = this.endpoint.replace(/{location}/g, '.' + location + '.rep'); - } else { - // In case of location is not available use global endpoint - location_endpoint = this.endpoint.replace(/{location}/g, ''); - } + const endpoint = ref.location + ? this._endpoints.secretmanager.replace( + 'https://secretmanager.', + `https://secretmanager.${ref.location}.rep.`, + ) + : this._endpoints.secretmanager; try { const token = await this.auth.getAccessToken(); - const response = await this.client.get(`${location_endpoint}/${ref}:access`, { + const response = await this.client.get(`${endpoint}/${selfLink}:access`, { 'Authorization': `Bearer ${token}`, 'User-Agent': userAgent, }); @@ -107,7 +107,7 @@ export class Client { const parsed: AccessSecretVersionResponse = JSON.parse(body); const b64data = parsed.payload.data; if (!b64data) { - throw new Error(`Secret "${ref}" returned no data!`); + throw new Error(`Secret "${selfLink}" returned no data!`); } let str = b64data.replace(/-/g, '+').replace(/_/g, '/'); @@ -115,7 +115,7 @@ export class Client { return Buffer.from(str, 'base64').toString(encoding); } catch (err) { const msg = errorMessage(err); - throw new Error(`Failed to access secret "${ref}": ${msg}`); + throw new Error(`Failed to access secret "${selfLink}": ${msg}`); } } } diff --git a/src/main.ts b/src/main.ts index 7761227..7f3882c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -26,21 +26,23 @@ import { parseSecretsRefs } from './reference'; */ async function run(): Promise { try { + const universe = getInput('universe'); const secretsInput = getInput('secrets', { required: true }); const minMaskLength = parseInt(getInput('min_mask_length')); const exportEnvironment = parseBoolean(getInput('export_to_environment')); const encoding = (getInput('encoding') || 'utf8') as BufferEncoding; - const location = (getInput('region') || '').trim(); // Create an API client. - const client = new Client(); + const client = new Client({ + universe: universe, + }); // Parse all the provided secrets into references. - const secretsRefs = parseSecretsRefs(secretsInput, location); + const secretsRefs = parseSecretsRefs(secretsInput); // Access and export each secret. for (const ref of secretsRefs) { - const value = await client.accessSecret(ref.selfLink(), location, encoding); + const value = await client.accessSecret(ref, encoding); // Split multiline secrets by line break and mask each line. // Read more here: https://github.com/actions/runner/issues/161 diff --git a/src/reference.ts b/src/reference.ts index cb40859..692a712 100644 --- a/src/reference.ts +++ b/src/reference.ts @@ -33,9 +33,9 @@ export class Reference { readonly project: string; readonly name: string; readonly version: string; - readonly location: string; + readonly location?: string; - constructor(s: string, location: string) { + constructor(s: string) { const sParts = s.split(':'); if (sParts.length < 2) { throw new TypeError(`Invalid reference "${s}" - missing destination`); @@ -46,19 +46,45 @@ export class Reference { const ref = sParts.slice(1).join(':'); const refParts = ref.split('/'); switch (refParts.length) { - // projects/

/secrets//versions/ - case 6: { + // projects/

/locations//secrets//versions/ + case 8: { this.project = refParts[1]; - this.name = refParts[3]; - this.version = refParts[5]; + this.location = refParts[3]; + this.name = refParts[5]; + this.version = refParts[7]; break; } - // projects/

/secrets/ + // projects/

/secrets//versions/ OR projects/

/locations//secerts/ + case 6: { + if (refParts[2] === 'secrets') { + this.project = refParts[1]; + this.name = refParts[3]; + this.version = refParts[5]; + break; + } else if (refParts[2] === 'locations') { + this.project = refParts[1]; + this.location = refParts[3]; + this.name = refParts[5]; + this.version = 'latest'; + break; + } else { + throw new TypeError(`Invalid reference "${s}" - unknown format`); + } + } + // projects/

/secrets/ OR

/// case 4: { - this.project = refParts[1]; - this.name = refParts[3]; - this.version = 'latest'; - break; + if (refParts[0] === 'projects') { + this.project = refParts[1]; + this.name = refParts[3]; + this.version = 'latest'; + break; + } else { + this.project = refParts[0]; + this.location = refParts[1]; + this.name = refParts[2]; + this.version = refParts[3]; + break; + } } //

// case 3: { @@ -78,11 +104,11 @@ export class Reference { throw new TypeError(`Invalid reference "${s}" - unknown format`); } } - this.location = location; } /** - * Returns the full GCP self link. + * Returns the full GCP self link. For regional secrets, this will include the + * location path. * * @returns String self link. */ @@ -103,12 +129,12 @@ export class Reference { * @returns Array of References for each secret, in the same order they were * given. */ -export function parseSecretsRefs(input: string, location: string): Reference[] { +export function parseSecretsRefs(input: string): Reference[] { const secrets: Reference[] = []; for (const line of input.split(/\r|\n/)) { const pieces = parseCSV(line); for (const piece of pieces) { - secrets.push(new Reference(piece, location)); + secrets.push(new Reference(piece)); } } return secrets; diff --git a/tests/reference.test.ts b/tests/reference.test.ts index 0215313..23f1c11 100644 --- a/tests/reference.test.ts +++ b/tests/reference.test.ts @@ -20,77 +20,55 @@ import assert from 'node:assert'; import { Reference, parseSecretsRefs } from '../src/reference'; test('Reference', { concurrency: true }, async (suite) => { - await suite.test('parses a full ref without location', async () => { - const ref = new Reference('out:projects/fruits/secrets/apple/versions/123', ''); - const link = ref.selfLink(); - assert.deepStrictEqual(link, 'projects/fruits/secrets/apple/versions/123'); - }); - - await suite.test('parses a full ref with location', async () => { - const ref = new Reference('out:projects/fruits/secrets/apple/versions/123', 'us-central1'); - const link = ref.selfLink(); - assert.deepStrictEqual( - link, - 'projects/fruits/locations/us-central1/secrets/apple/versions/123', - ); - }); - - await suite.test('parses a full ref sans version without location', async () => { - const ref = new Reference('out:projects/fruits/secrets/apple', ''); - const link = ref.selfLink(); - assert.deepStrictEqual(link, 'projects/fruits/secrets/apple/versions/latest'); - }); - - await suite.test('parses a full ref sans version with location', async () => { - const ref = new Reference('out:projects/fruits/secrets/apple', 'us-central1'); - const link = ref.selfLink(); - assert.deepStrictEqual( - link, - 'projects/fruits/locations/us-central1/secrets/apple/versions/latest', - ); - }); - - await suite.test('parses a short ref without location', async () => { - const ref = new Reference('out:fruits/apple/123', ''); - const link = ref.selfLink(); - assert.deepStrictEqual(link, 'projects/fruits/secrets/apple/versions/123'); - }); - - await suite.test('parses a short ref with location', async () => { - const ref = new Reference('out:fruits/apple/123', 'us-central1'); - const link = ref.selfLink(); - assert.deepStrictEqual( - link, - 'projects/fruits/locations/us-central1/secrets/apple/versions/123', - ); - }); - - await suite.test('parses a short ref sans version without location', async () => { - const ref = new Reference('out:fruits/apple', ''); - const link = ref.selfLink(); - assert.deepStrictEqual(link, 'projects/fruits/secrets/apple/versions/latest'); - }); - - await suite.test('parses a short ref sans version with location', async () => { - const ref = new Reference('out:fruits/apple', 'us-central1'); - const link = ref.selfLink(); - assert.deepStrictEqual( - link, - 'projects/fruits/locations/us-central1/secrets/apple/versions/latest', - ); - }); - - await suite.test('errors on invalid format', async () => { - await assert.rejects(async () => { - return new Reference('out:projects/fruits/secrets/apple/versions/123/subversions/5', ''); - }, TypeError); - }); + const cases = [ + { + input: 'out:projects/my-project/secrets/my-secret/versions/123', + expected: 'projects/my-project/secrets/my-secret/versions/123', + }, + { + input: 'out:projects/my-project/secrets/my-secret', + expected: 'projects/my-project/secrets/my-secret/versions/latest', + }, + { + input: 'out:projects/my-project/locations/my-location/secrets/my-secret', + expected: 'projects/my-project/locations/my-location/secrets/my-secret/versions/latest', + }, + { + input: 'out:my-project/my-secret/123', + expected: 'projects/my-project/secrets/my-secret/versions/123', + }, + { + input: 'out:my-project/my-secret', + expected: 'projects/my-project/secrets/my-secret/versions/latest', + }, + { + input: '', + error: 'TypeError', + }, + { + input: 'projects/my-project/secrets/my-secret/versions/123', + error: 'TypeError', + }, + { + input: 'out:projects/my-project/pandas/my-location/secrets/my-secret', + error: 'TypeErorr', + }, + ]; - await suite.test('errors on missing output', async () => { - await assert.rejects(async () => { - return new Reference('fruits/apple/123', 'us-central1'); - }, TypeError); - }); + for await (const tc of cases) { + if (tc.expected) { + await suite.test(`parses "${tc.input}"`, async () => { + const actual = new Reference(tc.input); + assert.deepStrictEqual(actual.selfLink(), tc.expected); + }); + } else if (tc.error) { + await suite.test(`errors on "${tc.input}"`, async () => { + await assert.rejects(async () => { + new Reference(tc.input); + }, tc.error); + }); + } + } }); test('#parseSecretsRefs', { concurrency: true }, async (suite) => { @@ -102,98 +80,43 @@ test('#parseSecretsRefs', { concurrency: true }, async (suite) => { expected: [], }, { - name: 'single value without location', - input: 'output:project/secret', - location: '', - expected: [new Reference('output:project/secret', '')], - }, - { - name: 'single value with location', - input: 'output:project/secret', - location: 'us-east1', - expected: [new Reference('output:project/secret', 'us-east1')], - }, - { - name: 'multi value commas without location', + name: 'multi value commas', input: 'output1:project/secret, output2:project/secret', location: '', - expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - ], + expected: [new Reference('output1:project/secret'), new Reference('output2:project/secret')], }, { - name: 'multi value commas with location', - input: 'output1:project/secret, output2:project/secret', - location: 'us-east1', - expected: [ - new Reference('output1:project/secret', 'us-east1'), - new Reference('output2:project/secret', 'us-east1'), - ], - }, - { - name: 'multi value newlines without location', + name: 'multi value newlines', input: 'output1:project/secret\noutput2:project/secret', location: '', - expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - ], - }, - { - name: 'multi value newlines with location', - input: 'output1:project/secret\noutput2:project/secret', - location: 'us-east1', - expected: [ - new Reference('output1:project/secret', 'us-east1'), - new Reference('output2:project/secret', 'us-east1'), - ], + expected: [new Reference('output1:project/secret'), new Reference('output2:project/secret')], }, { name: 'multi value carriage', input: 'output1:project/secret\routput2:project/secret', location: '', - expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - ], + expected: [new Reference('output1:project/secret'), new Reference('output2:project/secret')], }, { name: 'multi value carriage newline', input: 'output1:project/secret\r\noutput2:project/secret', location: '', - expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - ], + expected: [new Reference('output1:project/secret'), new Reference('output2:project/secret')], }, { name: 'multi value empty lines', input: 'output1:project/secret\n\n\noutput2:project/secret', location: '', - expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - ], + expected: [new Reference('output1:project/secret'), new Reference('output2:project/secret')], }, { - name: 'multi value commas without location', + name: 'multi value commas', input: 'output1:project/secret\noutput2:project/secret,output3:project/secret', location: '', expected: [ - new Reference('output1:project/secret', ''), - new Reference('output2:project/secret', ''), - new Reference('output3:project/secret', ''), - ], - }, - { - name: 'multi value commas with location', - input: 'output1:project/secret\noutput2:project/secret,output3:project/secret', - location: 'us-east1', - expected: [ - new Reference('output1:project/secret', 'us-east1'), - new Reference('output2:project/secret', 'us-east1'), - new Reference('output3:project/secret', 'us-east1'), + new Reference('output1:project/secret'), + new Reference('output2:project/secret'), + new Reference('output3:project/secret'), ], }, { @@ -207,11 +130,11 @@ test('#parseSecretsRefs', { concurrency: true }, async (suite) => { for await (const tc of cases) { await suite.test(tc.name, async () => { if (tc.expected) { - const actual = parseSecretsRefs(tc.input, tc.location); + const actual = parseSecretsRefs(tc.input); assert.deepStrictEqual(actual, tc.expected); } else if (tc.error) { await assert.rejects(async () => { - parseSecretsRefs(tc.input, tc.location); + parseSecretsRefs(tc.input); }, tc.error); } });