From fd690f9bb009268766b64abab1c552bc9e30a14c Mon Sep 17 00:00:00 2001 From: philmillman Date: Sat, 21 Mar 2026 11:18:15 -0400 Subject: [PATCH 1/4] intellij plugin WIP --- .github/workflows/test.yaml | 17 + .idea/.gitignore | 10 + .idea/codeStyles/Project.xml | 10 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/modules.xml | 8 + .idea/varlock.iml | 8 + .idea/vcs.xml | 6 + bun.lock | 876 +----------------- eslint.config.mjs | 1 + packages/intellij-plugin/.gitignore | 19 + packages/intellij-plugin/README.md | 80 ++ packages/intellij-plugin/build.gradle.kts | 49 + packages/intellij-plugin/gradle.properties | 5 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43705 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + packages/intellij-plugin/gradlew | 251 +++++ packages/intellij-plugin/settings.gradle.kts | 1 + .../envspec/EnvSpecASTWrapperPsiElement.kt | 9 + .../kotlin/dev/dmno/envspec/EnvSpecCatalog.kt | 231 +++++ .../dev/dmno/envspec/EnvSpecCommenter.kt | 12 + .../envspec/EnvSpecCompletionContributor.kt | 257 +++++ .../dev/dmno/envspec/EnvSpecCompletionCore.kt | 101 ++ .../dmno/envspec/EnvSpecDiagnosticsCore.kt | 253 +++++ .../envspec/EnvSpecDocumentationProvider.kt | 25 + .../kotlin/dev/dmno/envspec/EnvSpecFile.kt | 10 + .../dev/dmno/envspec/EnvSpecFileType.kt | 18 + .../dev/dmno/envspec/EnvSpecInspection.kt | 74 ++ .../dev/dmno/envspec/EnvSpecLanguage.kt | 7 + .../kotlin/dev/dmno/envspec/EnvSpecLexer.kt | 60 ++ .../kotlin/dev/dmno/envspec/EnvSpecParser.kt | 18 + .../dmno/envspec/EnvSpecParserDefinition.kt | 33 + .../dmno/envspec/EnvSpecSyntaxHighlighter.kt | 28 + .../EnvSpecSyntaxHighlighterFactory.kt | 13 + .../dev/dmno/envspec/EnvSpecTokenTypes.kt | 12 + .../src/main/resources/META-INF/plugin.xml | 27 + .../dmno/envspec/EnvSpecCompletionCoreTest.kt | 66 ++ .../envspec/EnvSpecDiagnosticsCoreTest.kt | 52 ++ 38 files changed, 1808 insertions(+), 857 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/varlock.iml create mode 100644 .idea/vcs.xml create mode 100644 packages/intellij-plugin/.gitignore create mode 100644 packages/intellij-plugin/README.md create mode 100644 packages/intellij-plugin/build.gradle.kts create mode 100644 packages/intellij-plugin/gradle.properties create mode 100644 packages/intellij-plugin/gradle/wrapper/gradle-wrapper.jar create mode 100644 packages/intellij-plugin/gradle/wrapper/gradle-wrapper.properties create mode 100755 packages/intellij-plugin/gradlew create mode 100644 packages/intellij-plugin/settings.gradle.kts create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecASTWrapperPsiElement.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCatalog.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommenter.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionCore.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDocumentationProvider.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFile.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLanguage.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParser.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighterFactory.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt create mode 100644 packages/intellij-plugin/src/main/resources/META-INF/plugin.xml create mode 100644 packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionCoreTest.kt create mode 100644 packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCoreTest.kt diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 466a18c1..38adfda7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -38,3 +38,20 @@ jobs: run: bun run build:libs - name: Run tests run: bun run test:ci + + intellij-plugin: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/intellij-plugin + steps: + - uses: actions/checkout@v6 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build IntelliJ plugin + run: ./gradlew build diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..ab1f4164 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..dc3e940f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..03d9549e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..9b8317cd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/varlock.iml b/.idea/varlock.iml new file mode 100644 index 00000000..c956989b --- /dev/null +++ b/.idea/varlock.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bun.lock b/bun.lock index 46d0b052..7c14286d 100644 --- a/bun.lock +++ b/bun.lock @@ -55,7 +55,7 @@ }, "packages/integrations/astro": { "name": "@varlock/astro-integration", - "version": "0.2.4", + "version": "0.2.5", "devDependencies": { "@types/node": "catalog:", "@varlock/vite-integration": "workspace:*", @@ -71,7 +71,7 @@ }, "packages/integrations/nextjs": { "name": "@varlock/nextjs-integration", - "version": "0.2.3", + "version": "0.3.0", "devDependencies": { "@types/node": "catalog:", "tsup": "catalog:", @@ -85,7 +85,7 @@ }, "packages/integrations/vite": { "name": "@varlock/vite-integration", - "version": "0.2.5", + "version": "0.2.6", "devDependencies": { "@types/node": "catalog:", "ast-matcher": "^1.2.0", @@ -103,7 +103,7 @@ }, "packages/plugins/1password": { "name": "@varlock/1password-plugin", - "version": "0.2.3", + "version": "0.3.0", "devDependencies": { "@1password/sdk": "0.4.1-beta.1", "@1password/sdk-core": "0.4.1-beta.1", @@ -120,7 +120,7 @@ }, "packages/plugins/aws-secrets": { "name": "@varlock/aws-secrets-plugin", - "version": "0.0.4", + "version": "0.0.5", "devDependencies": { "@aws-sdk/client-secrets-manager": "^3.700.0", "@aws-sdk/client-ssm": "^3.700.0", @@ -137,7 +137,7 @@ }, "packages/plugins/azure-key-vault": { "name": "@varlock/azure-key-vault-plugin", - "version": "0.0.4", + "version": "0.0.5", "devDependencies": { "@azure/identity": "^4.13.0", "@azure/keyvault-secrets": "^4.10.0", @@ -154,7 +154,7 @@ }, "packages/plugins/bitwarden": { "name": "@varlock/bitwarden-plugin", - "version": "0.0.4", + "version": "0.0.5", "devDependencies": { "@env-spec/utils": "workspace:^", "@types/node": "catalog:", @@ -169,7 +169,7 @@ }, "packages/plugins/google-secret-manager": { "name": "@varlock/google-secret-manager-plugin", - "version": "0.1.4", + "version": "0.2.0", "devDependencies": { "@env-spec/utils": "workspace:^", "@types/node": "catalog:", @@ -184,10 +184,10 @@ }, "packages/plugins/infisical": { "name": "@varlock/infisical-plugin", - "version": "0.0.4", + "version": "0.0.5", "devDependencies": { "@env-spec/utils": "workspace:^", - "@infisical/sdk": "^4.0.6", + "@infisical/sdk": "^5.0.0", "@types/node": "catalog:", "tsup": "catalog:", "varlock": "workspace:^", @@ -199,7 +199,7 @@ }, "packages/plugins/pass": { "name": "@varlock/pass-plugin", - "version": "0.0.4", + "version": "0.0.5", "devDependencies": { "@env-spec/utils": "workspace:^", "@types/node": "catalog:", @@ -225,7 +225,7 @@ }, "packages/varlock": { "name": "varlock", - "version": "0.5.0", + "version": "0.6.0", "bin": { "varlock": "./bin/cli.js", }, @@ -294,7 +294,7 @@ }, "packages/vscode-plugin": { "name": "env-spec-language", - "version": "0.0.5", + "version": "0.1.0", "devDependencies": { "@types/node": "catalog:", "@types/vscode": "^1.99.0", @@ -361,8 +361,6 @@ "@astrojs/vue": ["@astrojs/vue@5.1.4", "", { "dependencies": { "@vitejs/plugin-vue": "5.2.4", "@vitejs/plugin-vue-jsx": "^4.2.0", "@vue/compiler-sfc": "^3.5.26", "vite": "^6.4.1", "vite-plugin-vue-devtools": "^7.7.9" }, "peerDependencies": { "astro": "^5.0.0", "vue": "^3.2.30" } }, "sha512-srE+3tgSnGG4FVr7Bs9JAgLcUAg1mtGrbBFdwlj++Y05Awwlc967WCcmOK6rnxQ6q5PcK5+WL2x2tKoWh5SN7A=="], - "@aws-crypto/crc32": ["@aws-crypto/crc32@3.0.0", "", { "dependencies": { "@aws-crypto/util": "^3.0.0", "@aws-sdk/types": "^3.222.0", "tslib": "^1.11.1" } }, "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA=="], - "@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-crypto/supports-web-crypto": "^5.2.0", "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-locate-window": "^3.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="], "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], @@ -377,12 +375,6 @@ "@aws-sdk/client-ssm": ["@aws-sdk/client-ssm@3.1011.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.20", "@aws-sdk/credential-provider-node": "^3.972.21", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.21", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.7", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.11", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.25", "@smithy/middleware-retry": "^4.4.42", "@smithy/middleware-serde": "^4.2.14", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.4.16", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.5", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.41", "@smithy/util-defaults-mode-node": "^4.2.44", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "@smithy/util-waiter": "^4.2.13", "tslib": "^2.6.2" } }, "sha512-XFrixqhD4Lp9Bq/ZefbeYLp9oOL+4htqo7UxDCgrON0HBoj5u/3bDQPPse7CrfaYVw986mvoDJVRnIY2g+TDjA=="], - "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.598.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw=="], - - "@aws-sdk/client-sso-oidc": ["@aws-sdk/client-sso-oidc@3.600.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sts": "3.600.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw=="], - - "@aws-sdk/client-sts": ["@aws-sdk/client-sts@3.600.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.600.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA=="], - "@aws-sdk/core": ["@aws-sdk/core@3.973.20", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/xml-builder": "^3.972.11", "@smithy/core": "^3.23.11", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.5", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-i3GuX+lowD892F3IuJf8o6AbyDupMTdyTxQrCJGcn71ni5hTZ82L4nQhcdumxZ7XPJRJJVHS/CR3uYOIIs0PVA=="], "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.13", "", { "dependencies": { "@aws-sdk/nested-clients": "^3.996.10", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-WZnIK8NPX+4OXkpVoNmUS+Ya1osqjszUsDqFEz97+a/LD5K012np9iR/eWEC43btx8zQjyRIK8kyiwbh8SiHzg=="], @@ -415,12 +407,8 @@ "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.10", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.20", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.21", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.7", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.11", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.25", "@smithy/middleware-retry": "^4.4.42", "@smithy/middleware-serde": "^4.2.14", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.4.16", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.5", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.41", "@smithy/util-defaults-mode-node": "^4.2.44", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-SlDol5Z+C7Ivnc2rKGqiqfSUmUZzY1qHfVs9myt/nxVwswgfpjdKahyTzLTx802Zfq0NFRs7AejwKzzzl5Co2w=="], - "@aws-sdk/protocol-http": ["@aws-sdk/protocol-http@3.374.0", "", { "dependencies": { "@smithy/protocol-http": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-9WpRUbINdGroV3HiZZIBoJvL2ndoWk39OfwxWs2otxByppJZNN14bg/lvCx5e8ggHUti7IBk5rb0nqQZ4m05pg=="], - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/config-resolver": "^4.4.11", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1eD4uhTDeambO/PNIDVG19A6+v4NdD7xzwLHDutHsUqz0B+i661MwQB2eYO4/crcCvCiQG4SRm1k81k54FEIvw=="], - "@aws-sdk/signature-v4": ["@aws-sdk/signature-v4@3.374.0", "", { "dependencies": { "@smithy/signature-v4": "^1.0.1", "tslib": "^2.5.0" } }, "sha512-2xLJvSdzcZZAg0lsDLUAuSQuihzK0dcxIK7WmfuJeF7DGKJFmp9czQmz5f3qiDz6IDQzvgK1M9vtJSVCslJbyQ=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1009.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.20", "@aws-sdk/nested-clients": "^3.996.10", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-KCPLuTqN9u0Rr38Arln78fRG9KXpzsPWmof+PZzfAHMMQq2QED6YjQrkrfiH7PDefLWEposY1o4/eGwrmKA4JA=="], "@aws-sdk/types": ["@aws-sdk/types@3.973.6", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw=="], @@ -433,8 +421,6 @@ "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.7", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.21", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-Hz6EZMUAEzqUd7e+vZ9LE7mn+5gMbxltXy18v+YSFY+9LBJz15wkNZvw5JqfX3z0FS9n3bgUtz3L5rAsfh4YlA=="], - "@aws-sdk/util-utf8-browser": ["@aws-sdk/util-utf8-browser@3.259.0", "", { "dependencies": { "tslib": "^2.3.1" } }, "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw=="], - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.11", "", { "dependencies": { "@smithy/types": "^4.13.1", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-iitV/gZKQMvY9d7ovmyFnFuTHbBAtrmLnvaSb/3X8vOKyevwtpmEtyc8AdhVWZe0pI/1GsHxlEvQeOePFzy7KQ=="], "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.4", "", {}, "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ=="], @@ -757,7 +743,7 @@ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], - "@infisical/sdk": ["@infisical/sdk@4.0.6", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-sdk/credential-providers": "3.600.0", "@aws-sdk/protocol-http": "^3.370.0", "@aws-sdk/signature-v4": "^3.370.0", "axios": "^1.11.0", "typescript": "^5.5.4", "zod": "^3.23.8" } }, "sha512-aK/oQj0prIx8jTybcwQfPYow3/KsBGPbHCyK8zCIWGvUjHzYU2is34AWjRvxQ6GhZFpW1LaXfgxgrmbWrsgWZA=="], + "@infisical/sdk": ["@infisical/sdk@5.0.0", "", { "dependencies": { "@aws-crypto/sha256-js": "^5.2.0", "@aws-sdk/credential-providers": "3.993.0", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", "axios": "^1.11.0", "typescript": "^5.5.4", "zod": "^3.23.8" } }, "sha512-W4+eggqzbV8aIq/f3djpPO2qpY6Z6WtNEtkC9gV42bBmG+ll6lT2FyvDu5OrEvewJ804QD4nFawnEJw3eUO5SA=="], "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], @@ -981,8 +967,6 @@ "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="], - "@smithy/eventstream-codec": ["@smithy/eventstream-codec@1.1.0", "", { "dependencies": { "@aws-crypto/crc32": "3.0.0", "@smithy/types": "^1.2.0", "@smithy/util-hex-encoding": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-3tEbUb8t8an226jKB6V/Q2XU/J53lCwCzULuBPEaF4JjSh+FlCMp7TmogE/Aij5J9DwlsZ4VAD/IRDuQ/0ZtMw=="], - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="], "@smithy/hash-node": ["@smithy/hash-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="], @@ -3041,232 +3025,10 @@ "@astrojs/vue/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], - "@aws-crypto/crc32/@aws-crypto/util": ["@aws-crypto/util@3.0.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@aws-sdk/util-utf8-browser": "^3.0.0", "tslib": "^1.11.1" } }, "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w=="], - - "@aws-crypto/crc32/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], - "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - "@aws-sdk/client-sso/@aws-sdk/core": ["@aws-sdk/core@3.598.0", "", { "dependencies": { "@smithy/core": "^2.2.1", "@smithy/protocol-http": "^4.0.1", "@smithy/signature-v4": "^3.1.0", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" } }, "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g=="], - - "@aws-sdk/client-sso/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA=="], - - "@aws-sdk/client-sso/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q=="], - - "@aws-sdk/client-sso/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ=="], - - "@aws-sdk/client-sso/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg=="], - - "@aws-sdk/client-sso/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw=="], - - "@aws-sdk/client-sso/@aws-sdk/types": ["@aws-sdk/types@3.598.0", "", { "dependencies": { "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ=="], - - "@aws-sdk/client-sso/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "@smithy/util-endpoints": "^2.0.2", "tslib": "^2.6.2" } }, "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ=="], - - "@aws-sdk/client-sso/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw=="], - - "@aws-sdk/client-sso/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A=="], - - "@aws-sdk/client-sso/@smithy/config-resolver": ["@smithy/config-resolver@3.0.13", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg=="], - - "@aws-sdk/client-sso/@smithy/core": ["@smithy/core@2.5.7", "", { "dependencies": { "@smithy/middleware-serde": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "@smithy/util-stream": "^3.3.4", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg=="], - - "@aws-sdk/client-sso/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@3.2.9", "", { "dependencies": { "@smithy/protocol-http": "^4.1.4", "@smithy/querystring-builder": "^3.0.7", "@smithy/types": "^3.5.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A=="], - - "@aws-sdk/client-sso/@smithy/hash-node": ["@smithy/hash-node@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA=="], - - "@aws-sdk/client-sso/@smithy/invalid-dependency": ["@smithy/invalid-dependency@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ=="], - - "@aws-sdk/client-sso/@smithy/middleware-content-length": ["@smithy/middleware-content-length@3.0.13", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw=="], - - "@aws-sdk/client-sso/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@3.2.8", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-serde": "^3.0.11", "@smithy/node-config-provider": "^3.1.12", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ=="], - - "@aws-sdk/client-sso/@smithy/middleware-retry": ["@smithy/middleware-retry@3.0.34", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/protocol-http": "^4.1.8", "@smithy/service-error-classification": "^3.0.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "@smithy/util-middleware": "^3.0.11", "@smithy/util-retry": "^3.0.11", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA=="], - - "@aws-sdk/client-sso/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@aws-sdk/client-sso/@smithy/middleware-stack": ["@smithy/middleware-stack@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA=="], - - "@aws-sdk/client-sso/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@aws-sdk/client-sso/@smithy/node-http-handler": ["@smithy/node-http-handler@3.3.3", "", { "dependencies": { "@smithy/abort-controller": "^3.1.9", "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ=="], - - "@aws-sdk/client-sso/@smithy/protocol-http": ["@smithy/protocol-http@4.1.8", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw=="], - - "@aws-sdk/client-sso/@smithy/smithy-client": ["@smithy/smithy-client@3.7.0", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-endpoint": "^3.2.8", "@smithy/middleware-stack": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-stream": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA=="], - - "@aws-sdk/client-sso/@smithy/types": ["@smithy/types@3.7.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg=="], - - "@aws-sdk/client-sso/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], - - "@aws-sdk/client-sso/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@aws-sdk/client-sso/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ=="], - - "@aws-sdk/client-sso/@smithy/util-body-length-node": ["@smithy/util-body-length-node@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA=="], - - "@aws-sdk/client-sso/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@3.0.34", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-FumjjF631lR521cX+svMLBj3SwSDh9VdtyynTYDAiBDEf8YPP5xORNXKQ9j0105o5+ARAGnOOP/RqSl40uXddA=="], - - "@aws-sdk/client-sso/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@3.0.34", "", { "dependencies": { "@smithy/config-resolver": "^3.0.13", "@smithy/credential-provider-imds": "^3.2.8", "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-vN6aHfzW9dVVzkI0wcZoUXvfjkl4CSbM9nE//08lmUMyf00S75uuCpTrqF9uD4bD9eldIXlt53colrlwKAT8Gw=="], - - "@aws-sdk/client-sso/@smithy/util-endpoints": ["@smithy/util-endpoints@2.1.7", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw=="], - - "@aws-sdk/client-sso/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@aws-sdk/client-sso/@smithy/util-retry": ["@smithy/util-retry@3.0.11", "", { "dependencies": { "@smithy/service-error-classification": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ=="], - - "@aws-sdk/client-sso/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/core": ["@aws-sdk/core@3.598.0", "", { "dependencies": { "@smithy/core": "^2.2.1", "@smithy/protocol-http": "^4.0.1", "@smithy/signature-v4": "^3.1.0", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" } }, "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.600.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-ini": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/types": ["@aws-sdk/types@3.598.0", "", { "dependencies": { "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "@smithy/util-endpoints": "^2.0.2", "tslib": "^2.6.2" } }, "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A=="], - - "@aws-sdk/client-sso-oidc/@smithy/config-resolver": ["@smithy/config-resolver@3.0.13", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg=="], - - "@aws-sdk/client-sso-oidc/@smithy/core": ["@smithy/core@2.5.7", "", { "dependencies": { "@smithy/middleware-serde": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "@smithy/util-stream": "^3.3.4", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg=="], - - "@aws-sdk/client-sso-oidc/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@3.2.9", "", { "dependencies": { "@smithy/protocol-http": "^4.1.4", "@smithy/querystring-builder": "^3.0.7", "@smithy/types": "^3.5.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A=="], - - "@aws-sdk/client-sso-oidc/@smithy/hash-node": ["@smithy/hash-node@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA=="], - - "@aws-sdk/client-sso-oidc/@smithy/invalid-dependency": ["@smithy/invalid-dependency@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-content-length": ["@smithy/middleware-content-length@3.0.13", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@3.2.8", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-serde": "^3.0.11", "@smithy/node-config-provider": "^3.1.12", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-retry": ["@smithy/middleware-retry@3.0.34", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/protocol-http": "^4.1.8", "@smithy/service-error-classification": "^3.0.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "@smithy/util-middleware": "^3.0.11", "@smithy/util-retry": "^3.0.11", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-stack": ["@smithy/middleware-stack@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-http-handler": ["@smithy/node-http-handler@3.3.3", "", { "dependencies": { "@smithy/abort-controller": "^3.1.9", "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/protocol-http": ["@smithy/protocol-http@4.1.8", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client": ["@smithy/smithy-client@3.7.0", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-endpoint": "^3.2.8", "@smithy/middleware-stack": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-stream": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA=="], - - "@aws-sdk/client-sso-oidc/@smithy/types": ["@smithy/types@3.7.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg=="], - - "@aws-sdk/client-sso-oidc/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-body-length-node": ["@smithy/util-body-length-node@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@3.0.34", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-FumjjF631lR521cX+svMLBj3SwSDh9VdtyynTYDAiBDEf8YPP5xORNXKQ9j0105o5+ARAGnOOP/RqSl40uXddA=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@3.0.34", "", { "dependencies": { "@smithy/config-resolver": "^3.0.13", "@smithy/credential-provider-imds": "^3.2.8", "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-vN6aHfzW9dVVzkI0wcZoUXvfjkl4CSbM9nE//08lmUMyf00S75uuCpTrqF9uD4bD9eldIXlt53colrlwKAT8Gw=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-endpoints": ["@smithy/util-endpoints@2.1.7", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-retry": ["@smithy/util-retry@3.0.11", "", { "dependencies": { "@smithy/service-error-classification": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@aws-sdk/client-sts/@aws-sdk/core": ["@aws-sdk/core@3.598.0", "", { "dependencies": { "@smithy/core": "^2.2.1", "@smithy/protocol-http": "^4.0.1", "@smithy/signature-v4": "^3.1.0", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" } }, "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.600.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-ini": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ=="], - - "@aws-sdk/client-sts/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg=="], - - "@aws-sdk/client-sts/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw=="], - - "@aws-sdk/client-sts/@aws-sdk/types": ["@aws-sdk/types@3.598.0", "", { "dependencies": { "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ=="], - - "@aws-sdk/client-sts/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "@smithy/util-endpoints": "^2.0.2", "tslib": "^2.6.2" } }, "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ=="], - - "@aws-sdk/client-sts/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw=="], - - "@aws-sdk/client-sts/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A=="], - - "@aws-sdk/client-sts/@smithy/config-resolver": ["@smithy/config-resolver@3.0.13", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg=="], - - "@aws-sdk/client-sts/@smithy/core": ["@smithy/core@2.5.7", "", { "dependencies": { "@smithy/middleware-serde": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "@smithy/util-stream": "^3.3.4", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg=="], - - "@aws-sdk/client-sts/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@3.2.9", "", { "dependencies": { "@smithy/protocol-http": "^4.1.4", "@smithy/querystring-builder": "^3.0.7", "@smithy/types": "^3.5.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A=="], - - "@aws-sdk/client-sts/@smithy/hash-node": ["@smithy/hash-node@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA=="], - - "@aws-sdk/client-sts/@smithy/invalid-dependency": ["@smithy/invalid-dependency@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ=="], - - "@aws-sdk/client-sts/@smithy/middleware-content-length": ["@smithy/middleware-content-length@3.0.13", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw=="], - - "@aws-sdk/client-sts/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@3.2.8", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-serde": "^3.0.11", "@smithy/node-config-provider": "^3.1.12", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ=="], - - "@aws-sdk/client-sts/@smithy/middleware-retry": ["@smithy/middleware-retry@3.0.34", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/protocol-http": "^4.1.8", "@smithy/service-error-classification": "^3.0.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "@smithy/util-middleware": "^3.0.11", "@smithy/util-retry": "^3.0.11", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA=="], - - "@aws-sdk/client-sts/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@aws-sdk/client-sts/@smithy/middleware-stack": ["@smithy/middleware-stack@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA=="], - - "@aws-sdk/client-sts/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@aws-sdk/client-sts/@smithy/node-http-handler": ["@smithy/node-http-handler@3.3.3", "", { "dependencies": { "@smithy/abort-controller": "^3.1.9", "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ=="], - - "@aws-sdk/client-sts/@smithy/protocol-http": ["@smithy/protocol-http@4.1.8", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw=="], - - "@aws-sdk/client-sts/@smithy/smithy-client": ["@smithy/smithy-client@3.7.0", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-endpoint": "^3.2.8", "@smithy/middleware-stack": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-stream": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA=="], - - "@aws-sdk/client-sts/@smithy/types": ["@smithy/types@3.7.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg=="], - - "@aws-sdk/client-sts/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], - - "@aws-sdk/client-sts/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@aws-sdk/client-sts/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ=="], - - "@aws-sdk/client-sts/@smithy/util-body-length-node": ["@smithy/util-body-length-node@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA=="], - - "@aws-sdk/client-sts/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@3.0.34", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-FumjjF631lR521cX+svMLBj3SwSDh9VdtyynTYDAiBDEf8YPP5xORNXKQ9j0105o5+ARAGnOOP/RqSl40uXddA=="], - - "@aws-sdk/client-sts/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@3.0.34", "", { "dependencies": { "@smithy/config-resolver": "^3.0.13", "@smithy/credential-provider-imds": "^3.2.8", "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-vN6aHfzW9dVVzkI0wcZoUXvfjkl4CSbM9nE//08lmUMyf00S75uuCpTrqF9uD4bD9eldIXlt53colrlwKAT8Gw=="], - - "@aws-sdk/client-sts/@smithy/util-endpoints": ["@smithy/util-endpoints@2.1.7", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw=="], - - "@aws-sdk/client-sts/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@aws-sdk/client-sts/@smithy/util-retry": ["@smithy/util-retry@3.0.11", "", { "dependencies": { "@smithy/service-error-classification": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ=="], - - "@aws-sdk/client-sts/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@aws-sdk/protocol-http/@smithy/protocol-http": ["@smithy/protocol-http@1.2.0", "", { "dependencies": { "@smithy/types": "^1.2.0", "tslib": "^2.5.0" } }, "sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4": ["@smithy/signature-v4@1.1.0", "", { "dependencies": { "@smithy/eventstream-codec": "^1.1.0", "@smithy/is-array-buffer": "^1.1.0", "@smithy/types": "^1.2.0", "@smithy/util-hex-encoding": "^1.1.0", "@smithy/util-middleware": "^1.1.0", "@smithy/util-uri-escape": "^1.1.0", "@smithy/util-utf8": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-fDo3m7YqXBs7neciOePPd/X9LPm5QLlDMdIC4m1H6dgNLnXfLMFNIxEfPyohGA8VW9Wn4X8lygnPSGxDZSmp0Q=="], - "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], @@ -3285,7 +3047,7 @@ "@expressive-code/plugin-shiki/shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], - "@infisical/sdk/@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.600.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.600.0", "@aws-sdk/client-sso": "3.598.0", "@aws-sdk/client-sts": "3.600.0", "@aws-sdk/credential-provider-cognito-identity": "3.600.0", "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-ini": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-cC9uqmX0rgx1efiJGqeR+i0EXr8RQ5SAzH7M45WNBZpYiLEe6reWgIYJY9hmOxuaoMdWSi8kekuN3IjTIORRjw=="], + "@infisical/sdk/@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.993.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.993.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-cognito-identity": "^3.972.3", "@aws-sdk/credential-provider-env": "^3.972.9", "@aws-sdk/credential-provider-http": "^3.972.11", "@aws-sdk/credential-provider-ini": "^3.972.9", "@aws-sdk/credential-provider-login": "^3.972.9", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/credential-provider-process": "^3.972.9", "@aws-sdk/credential-provider-sso": "^3.972.9", "@aws-sdk/credential-provider-web-identity": "^3.972.9", "@aws-sdk/nested-clients": "3.993.0", "@aws-sdk/types": "^3.973.1", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-1M/nukgPSLqe9krzOKHnE8OylUaKAiokAV3xRLdeExVHcRE7WG5uzCTKWTj1imKvPjDqXq/FWhlbbdWIn7xIwA=="], "@infisical/sdk/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -3313,10 +3075,6 @@ "@secretlint/formatter/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], - "@smithy/eventstream-codec/@smithy/types": ["@smithy/types@1.2.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA=="], - - "@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@1.1.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg=="], - "@textlint/linter-formatter/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "@textlint/linter-formatter/pluralize": ["pluralize@2.0.0", "", {}, "sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw=="], @@ -3599,188 +3357,6 @@ "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], - "@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@3.1.2", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/core/fast-xml-parser": ["fast-xml-parser@4.2.5", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/node-http-handler": "^3.0.1", "@smithy/property-provider": "^3.1.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/util-stream": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.598.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.598.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.598.0", "@aws-sdk/token-providers": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/region-config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso-oidc/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sso-oidc/@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@3.1.9", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@3.1.2", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA=="], - - "@aws-sdk/client-sso/@aws-sdk/core/fast-xml-parser": ["fast-xml-parser@4.2.5", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="], - - "@aws-sdk/client-sso/@aws-sdk/region-config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sso/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sso/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sso/@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - - "@aws-sdk/client-sso/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@3.1.9", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw=="], - - "@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sso/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - - "@aws-sdk/client-sso/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@aws-sdk/client-sso/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sso/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@3.1.2", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA=="], - - "@aws-sdk/client-sts/@aws-sdk/core/fast-xml-parser": ["fast-xml-parser@4.2.5", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/node-http-handler": "^3.0.1", "@smithy/property-provider": "^3.1.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/util-stream": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.598.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.598.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.598.0", "@aws-sdk/token-providers": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sts/@aws-sdk/region-config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sts/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sts/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sts/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sts/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sts/@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - - "@aws-sdk/client-sts/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sts/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@aws-sdk/client-sts/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@3.1.9", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw=="], - - "@aws-sdk/client-sts/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sts/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - - "@aws-sdk/client-sts/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sts/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@aws-sdk/client-sts/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@aws-sdk/client-sts/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@aws-sdk/client-sts/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/protocol-http/@smithy/protocol-http/@smithy/types": ["@smithy/types@1.2.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@1.1.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/types": ["@smithy/types@1.2.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@1.1.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@1.1.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@1.1.0", "", { "dependencies": { "tslib": "^2.5.0" } }, "sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@1.1.0", "", { "dependencies": { "@smithy/util-buffer-from": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A=="], - "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "@expressive-code/core/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -3797,31 +3373,9 @@ "@expressive-code/plugin-shiki/shiki/@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.600.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.600.0", "@aws-sdk/client-sts": "3.600.0", "@aws-sdk/core": "3.598.0", "@aws-sdk/credential-provider-node": "3.600.0", "@aws-sdk/middleware-host-header": "3.598.0", "@aws-sdk/middleware-logger": "3.598.0", "@aws-sdk/middleware-recursion-detection": "3.598.0", "@aws-sdk/middleware-user-agent": "3.598.0", "@aws-sdk/region-config-resolver": "3.598.0", "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@aws-sdk/util-user-agent-browser": "3.598.0", "@aws-sdk/util-user-agent-node": "3.598.0", "@smithy/config-resolver": "^3.0.2", "@smithy/core": "^2.2.1", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/hash-node": "^3.0.1", "@smithy/invalid-dependency": "^3.0.1", "@smithy/middleware-content-length": "^3.0.1", "@smithy/middleware-endpoint": "^3.0.2", "@smithy/middleware-retry": "^3.0.4", "@smithy/middleware-serde": "^3.0.1", "@smithy/middleware-stack": "^3.0.1", "@smithy/node-config-provider": "^3.1.1", "@smithy/node-http-handler": "^3.0.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/url-parser": "^3.0.1", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.4", "@smithy/util-defaults-mode-node": "^3.0.4", "@smithy/util-endpoints": "^2.0.2", "@smithy/util-middleware": "^3.0.1", "@smithy/util-retry": "^3.0.1", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8dYsnDLiD0rjujRiZZl0E57heUkHqMSFZHBi0YMs57SM8ODPxK3tahwDYZtS7bqanvFKZwGy+o9jIcij7jBOlA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.600.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.600.0", "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-AIM+B06d1+71EuBrk2UR9ZZgRS3a+ARxE3oZKMZYlfqtZ3kY8w4DkhEt7OVruc6uSsMhkrcQT6nxsOxFSi4RtA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/fetch-http-handler": "^3.0.2", "@smithy/node-http-handler": "^3.0.1", "@smithy/property-provider": "^3.1.1", "@smithy/protocol-http": "^4.0.1", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "@smithy/util-stream": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.598.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.600.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.598.0", "@aws-sdk/credential-provider-http": "3.598.0", "@aws-sdk/credential-provider-ini": "3.598.0", "@aws-sdk/credential-provider-process": "3.598.0", "@aws-sdk/credential-provider-sso": "3.598.0", "@aws-sdk/credential-provider-web-identity": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/credential-provider-imds": "^3.1.1", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.598.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.598.0", "@aws-sdk/token-providers": "3.598.0", "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA=="], + "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/credential-provider-node": "^3.972.10", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7Ne3Yk/bgQPVebAkv7W+RfhiwTRSbfER9BtbhOa2w/+dIr902LrJf6vrZlxiqaJbGj2ALx8M+ZK1YIHVxSwu9A=="], - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sts": "^3.598.0" } }, "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/types": ["@aws-sdk/types@3.598.0", "", { "dependencies": { "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.8", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/property-provider": ["@smithy/property-provider@3.1.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/types": ["@smithy/types@3.7.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg=="], + "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.993.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.11", "@aws-sdk/middleware-host-header": "^3.972.3", "@aws-sdk/middleware-logger": "^3.972.3", "@aws-sdk/middleware-recursion-detection": "^3.972.3", "@aws-sdk/middleware-user-agent": "^3.972.11", "@aws-sdk/region-config-resolver": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.993.0", "@aws-sdk/util-user-agent-browser": "^3.972.3", "@aws-sdk/util-user-agent-node": "^3.972.9", "@smithy/config-resolver": "^4.4.6", "@smithy/core": "^3.23.2", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", "@smithy/middleware-endpoint": "^4.4.16", "@smithy/middleware-retry": "^4.4.33", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.10", "@smithy/protocol-http": "^5.3.8", "@smithy/smithy-client": "^4.11.5", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.32", "@smithy/util-defaults-mode-node": "^4.2.35", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iOq86f2H67924kQUIPOAvlmMaOAvOLoDOIb66I2YqSUpMYB6ufiuJW3RlREgskxv86S5qKzMnfy/X6CqMjK6XQ=="], "@manypkg/find-root/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], @@ -4193,195 +3747,9 @@ "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], - "@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/core/fast-xml-parser/strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sso-oidc": "^3.598.0" } }, "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso-oidc/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso/@aws-sdk/core/fast-xml-parser/strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sts/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@aws-sdk/core/fast-xml-parser/strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sso-oidc": "^3.598.0" } }, "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sts/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sts/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@1.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core": ["@aws-sdk/core@3.598.0", "", { "dependencies": { "@smithy/core": "^2.2.1", "@smithy/protocol-http": "^4.0.1", "@smithy/signature-v4": "^3.1.0", "@smithy/smithy-client": "^3.1.2", "@smithy/types": "^3.1.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" } }, "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@aws-sdk/util-endpoints": "3.598.0", "@smithy/protocol-http": "^4.0.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" } }, "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "@smithy/util-endpoints": "^2.0.2", "tslib": "^2.6.2" } }, "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/types": "^3.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/node-config-provider": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/config-resolver": ["@smithy/config-resolver@3.0.13", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/util-config-provider": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core": ["@smithy/core@2.5.7", "", { "dependencies": { "@smithy/middleware-serde": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "@smithy/util-stream": "^3.3.4", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@3.2.9", "", { "dependencies": { "@smithy/protocol-http": "^4.1.4", "@smithy/querystring-builder": "^3.0.7", "@smithy/types": "^3.5.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node": ["@smithy/hash-node@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/invalid-dependency": ["@smithy/invalid-dependency@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-content-length": ["@smithy/middleware-content-length@3.0.13", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@3.2.8", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-serde": "^3.0.11", "@smithy/node-config-provider": "^3.1.12", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-retry": ["@smithy/middleware-retry@3.0.34", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/protocol-http": "^4.1.8", "@smithy/service-error-classification": "^3.0.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "@smithy/util-middleware": "^3.0.11", "@smithy/util-retry": "^3.0.11", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-yVRr/AAtPZlUvwEkrq7S3x7Z8/xCd97m2hLDaqdz6ucP2RKHsBjEqaUA2ebNv2SsZoPEi+ZD0dZbOB1u37tGCA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-stack": ["@smithy/middleware-stack@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler": ["@smithy/node-http-handler@3.3.3", "", { "dependencies": { "@smithy/abort-controller": "^3.1.9", "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/protocol-http": ["@smithy/protocol-http@4.1.8", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client": ["@smithy/smithy-client@3.7.0", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-endpoint": "^3.2.8", "@smithy/middleware-stack": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-stream": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-body-length-node": ["@smithy/util-body-length-node@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@3.0.34", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-FumjjF631lR521cX+svMLBj3SwSDh9VdtyynTYDAiBDEf8YPP5xORNXKQ9j0105o5+ARAGnOOP/RqSl40uXddA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@3.0.34", "", { "dependencies": { "@smithy/config-resolver": "^3.0.13", "@smithy/credential-provider-imds": "^3.2.8", "@smithy/node-config-provider": "^3.1.12", "@smithy/property-provider": "^3.1.11", "@smithy/smithy-client": "^3.7.0", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-vN6aHfzW9dVVzkI0wcZoUXvfjkl4CSbM9nE//08lmUMyf00S75uuCpTrqF9uD4bD9eldIXlt53colrlwKAT8Gw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-endpoints": ["@smithy/util-endpoints@2.1.7", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-retry": ["@smithy/util-retry@3.0.11", "", { "dependencies": { "@smithy/service-error-classification": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@3.2.9", "", { "dependencies": { "@smithy/protocol-http": "^4.1.4", "@smithy/querystring-builder": "^3.0.7", "@smithy/types": "^3.5.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@3.3.3", "", { "dependencies": { "@smithy/abort-controller": "^3.1.9", "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-BrpZOaZ4RCbcJ2igiSNG16S+kgAc65l/2hmxWdmhyoGWHTLlzQzr06PXavJp9OBlPEG/sHlqdxjWmjzV66+BSQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/protocol-http": ["@smithy/protocol-http@4.1.8", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@3.7.0", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-endpoint": "^3.2.8", "@smithy/middleware-stack": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-stream": "^3.3.4", "tslib": "^2.6.2" } }, "sha512-9wYrjAZFlqWhgVo3C4y/9kpc68jgiSsKUnsFPzr/MSiRL93+QRDafGTfhhKAb2wsr69Ru87WTiqSfQusSmWipA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-ini/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], + "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-process/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.598.0", "", { "dependencies": { "@aws-sdk/types": "3.598.0", "@smithy/property-provider": "^3.1.1", "@smithy/shared-ini-file-loader": "^3.1.1", "@smithy/types": "^3.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "@aws-sdk/client-sso-oidc": "^3.598.0" } }, "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-sso/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], + "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.993.0", "", { "dependencies": { "@aws-sdk/types": "^3.973.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-endpoints": "^3.2.8", "tslib": "^2.6.2" } }, "sha512-j6vioBeRZ4eHX4SWGvGPpwGg/xSOcK7f1GL0VM+rdf3ZFTIsUEhCFmD78B+5r2PgztcECSzEfvHQX01k8dPQPw=="], "@manypkg/find-root/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], @@ -4739,106 +4107,6 @@ "@astrojs/starlight/astro/vite/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@3.1.2", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/fast-xml-parser": ["fast-xml-parser@4.2.5", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/region-config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@3.1.9", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@3.3.4", "", { "dependencies": { "@smithy/fetch-http-handler": "^4.1.3", "@smithy/node-http-handler": "^3.3.3", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-SGhGBG/KupieJvJSZp/rfHHka8BFgj56eek9px4pp7lZbOF+fRiVr4U7A3y3zJD8uGhxq32C5D96HxsTC9BckQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2" } }, "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@3.1.9", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core": ["@smithy/core@2.5.7", "", { "dependencies": { "@smithy/middleware-serde": "^3.0.11", "@smithy/protocol-http": "^4.1.8", "@smithy/types": "^3.7.2", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-middleware": "^3.0.11", "@smithy/util-stream": "^3.3.4", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-8olpW6mKCa0v+ibCjoCzgZHQx1SQmZuW/WkrdZo73wiTprTH6qhmskT60QLFdT9DRa5mXxjz89kQPZ7ZSsoqqg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@3.2.8", "", { "dependencies": { "@smithy/core": "^2.5.7", "@smithy/middleware-serde": "^3.0.11", "@smithy/node-config-provider": "^3.1.12", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "@smithy/url-parser": "^3.0.11", "@smithy/util-middleware": "^3.0.11", "tslib": "^2.6.2" } }, "sha512-OEJZKVUEhMOqMs3ktrTWp7UvvluMJEvD5XgQwRePSbDg1VvBaL8pX8mwPltFn6wk1GySbcVwwyldL8S+iqnrEQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@smithy/credential-provider-imds/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - "@manypkg/find-root/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], "@textlint/linter-formatter/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], @@ -5010,111 +4278,5 @@ "starlight-llms-txt/astro/vite/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "vscode-tmgrammar-test/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso-oidc/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sts/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@aws-sdk/core/fast-xml-parser/strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@4.1.3", "", { "dependencies": { "@smithy/protocol-http": "^4.1.8", "@smithy/querystring-builder": "^3.0.11", "@smithy/types": "^3.7.2", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-6SxNltSncI8s689nvnzZQc/dPXcpHQ34KUj6gR/HBroytKOd/isMG3gJF/zBE1TBmTT18TXyzhg3O3SOOqGEhA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.12", "", { "dependencies": { "@smithy/property-provider": "^3.1.11", "@smithy/shared-ini-file-loader": "^3.1.12", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.12", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@3.0.11", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.11", "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@aws-sdk/client-sso-oidc/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@aws-sdk/client-sts/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@3.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.11", "", { "dependencies": { "@smithy/types": "^3.7.2", "tslib": "^2.6.2" } }, "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg=="], - - "@infisical/sdk/@aws-sdk/credential-providers/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="], } } diff --git a/eslint.config.mjs b/eslint.config.mjs index 4e76eb99..34e6d24d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -56,6 +56,7 @@ export default tseslint.config( '.magent', 'framework-tests/.test-projects', 'framework-tests/.packed', + 'packages/intellij-plugin/build', ], }, diff --git a/packages/intellij-plugin/.gitignore b/packages/intellij-plugin/.gitignore new file mode 100644 index 00000000..adc56834 --- /dev/null +++ b/packages/intellij-plugin/.gitignore @@ -0,0 +1,19 @@ +# Gradle +.gradle/ +build/ + +# Kotlin (incremental compilation / daemon metadata) +.kotlin/ + +# IntelliJ Platform Gradle Plugin (IDE dependency cache, optional project cache) +.intellijPlatform/ + +# IntelliJ IDEA / Android Studio +.idea/ +*.iml +*.ipr +*.iws +out/ + +# Local SDK or machine-specific paths (if present) +local.properties diff --git a/packages/intellij-plugin/README.md b/packages/intellij-plugin/README.md new file mode 100644 index 00000000..4e0bfa23 --- /dev/null +++ b/packages/intellij-plugin/README.md @@ -0,0 +1,80 @@ +# Env Spec Language - IntelliJ / WebStorm Plugin + +Adds syntax highlighting and IntelliSense for [@env-spec](https://varlock.dev/env-spec) enabled `.env` files in IntelliJ IDEA and WebStorm. + +## Features + +Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): + +- **Completion (IntelliSense)** for: + - Decorators (`@required`, `@type=`, etc.) + - `@type=` data types (string, number, enum, url, etc.) + - Type options (e.g. `string(minLength=5)`) + - Resolver functions (`concat`, `fallback`, `forEnv`, etc.) + - `$KEY` references + - Enum values when `@type=enum(...)` is used + +- **Inline diagnostics** for: + - Duplicate single-use decorators + - Incompatible decorators (`@required` + `@optional`, etc.) + - Invalid enum values + - Static value validation (url prependHttps, string length, number range, etc.) + +- **Documentation** on hover for decorators + +- **Syntax highlighting** for .env and .env.* files + +- **Toggle line comment** (`# `) support + +## Installation + +### From JetBrains Marketplace + +1. Open **Settings** | **Plugins** | **Marketplace** +2. Search for "Env Spec" or "@env-spec" +3. Install and restart the IDE + +### From disk (development) + +1. Build the plugin: `./gradlew buildPlugin` (or `./gradlew build`, which includes it) +2. The plugin ZIP is in `build/distributions/` +3. Install via **Settings** | **Plugins** | **⚙️** | **Install Plugin from Disk...** + +## Supported file patterns + +- `.env` +- `.env.*` (e.g. `.env.schema`, `.env.local`, `.env.example`) + +## Requirements + +- IntelliJ IDEA 2024.3+ or WebStorm 2024.3+ +- **Java 17** (for building) — Java 24/25 are not yet supported by Gradle 8.x and the IntelliJ Platform plugin + +## Development + +```bash +# Build +./gradlew build + +# Run IDE with plugin +./gradlew runIde + +# Run tests +./gradlew test +``` + +### Troubleshooting + +**Build fails with "What went wrong: 25"** — You're using Java 25, which Gradle 8.x doesn't support. Use Java 17: + +```bash +# Homebrew (openjdk@17) +export JAVA_HOME="/opt/homebrew/opt/openjdk@17" +./gradlew build +``` + +You can add that `export` to your `~/.zshrc` or run it before each build. + +## License + +MIT diff --git a/packages/intellij-plugin/build.gradle.kts b/packages/intellij-plugin/build.gradle.kts new file mode 100644 index 00000000..b50531d5 --- /dev/null +++ b/packages/intellij-plugin/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + id("java") + id("org.jetbrains.kotlin.jvm") version "2.0.21" + id("org.jetbrains.intellij.platform") version "2.13.1" +} + +group = "dev.dmno" +version = "0.1.0" + +repositories { + mavenCentral() + intellijPlatform { + defaultRepositories() + } +} + +dependencies { + intellijPlatform { + intellijIdea("2024.3.6") + } + testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testRuntimeOnly("junit:junit:4.13.2") // IntelliJ test framework needs JUnit4 classes (IJPL-159134) +} + +tasks.test { + useJUnitPlatform() +} + +// Ensure `build` produces the plugin zip (buildPlugin is not included by default) +tasks.named("build") { + dependsOn(tasks.named("buildPlugin")) +} + +intellijPlatform { + buildSearchableOptions.set(false) + pluginConfiguration { + name.set("Env Spec Language") + description.set("Adds syntax highlighting and IntelliSense for @env-spec enabled .env files") + vendor { + name.set("dmno-dev") + url.set("https://varlock.dev") + } + } +} + +kotlin { + jvmToolchain(17) +} diff --git a/packages/intellij-plugin/gradle.properties b/packages/intellij-plugin/gradle.properties new file mode 100644 index 00000000..bf9fef3d --- /dev/null +++ b/packages/intellij-plugin/gradle.properties @@ -0,0 +1,5 @@ +org.gradle.jvmargs=-Xmx2048m +org.gradle.parallel=true + +# Suppress "no searchable options" warning (plugin has no Settings UI) +org.jetbrains.intellij.platform.noSearchableOptionsWarning=false diff --git a/packages/intellij-plugin/gradle/wrapper/gradle-wrapper.jar b/packages/intellij-plugin/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..9bbc975c742b298b441bfb90dbc124400a3751b9 GIT binary patch literal 43705 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 DHx0+F literal 0 HcmV?d00001 diff --git a/packages/intellij-plugin/gradle/wrapper/gradle-wrapper.properties b/packages/intellij-plugin/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2a84e188 --- /dev/null +++ b/packages/intellij-plugin/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/intellij-plugin/gradlew b/packages/intellij-plugin/gradlew new file mode 100755 index 00000000..d24fc200 --- /dev/null +++ b/packages/intellij-plugin/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/packages/intellij-plugin/settings.gradle.kts b/packages/intellij-plugin/settings.gradle.kts new file mode 100644 index 00000000..d17e53cc --- /dev/null +++ b/packages/intellij-plugin/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "env-spec-intellij-plugin" diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecASTWrapperPsiElement.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecASTWrapperPsiElement.kt new file mode 100644 index 00000000..2ced0ab1 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecASTWrapperPsiElement.kt @@ -0,0 +1,9 @@ +package dev.dmno.envspec + +import com.intellij.extapi.psi.ASTWrapperPsiElement +import com.intellij.lang.ASTNode + +class EnvSpecASTWrapperPsiElement(node: ASTNode) : ASTWrapperPsiElement(node) { + + override fun toString(): String = "EnvSpec:" + node.elementType.toString() +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCatalog.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCatalog.kt new file mode 100644 index 00000000..ff40e084 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCatalog.kt @@ -0,0 +1,231 @@ +package dev.dmno.envspec + +data class DecoratorInfo( + val name: String, + val scope: String, // "root" | "item" + val summary: String, + val documentation: String, + val insertText: String, + val isFunction: Boolean = false, + val deprecated: String? = null, +) + +data class DataTypeOptionSnippet( + val name: String, + val insertText: String, + val documentation: String, +) + +data class DataTypeInfo( + val name: String, + val summary: String, + val documentation: String, + val insertText: String? = null, + val optionSnippets: List? = null, +) + +data class ResolverInfo( + val name: String, + val summary: String, + val documentation: String, + val insertText: String, +) + +private fun booleanChoiceSnippet(defaultValue: String = "true"): String { + val d = "\${'$'}" + return if (defaultValue == "false") "${d}{1|false,true|}" else "${d}{1|true,false|}" +} + +object EnvSpecCatalog { + + val ROOT_DECORATORS = listOf( + DecoratorInfo( + name = "envFlag", + scope = "root", + summary = "Deprecated environment flag decorator.", + documentation = "Deprecated at v0.1. Use `@currentEnv=\$APP_ENV` instead.", + insertText = "@envFlag=\${'$'}{1:APP_ENV}", + deprecated = "Use @currentEnv instead.", + ), + DecoratorInfo( + name = "currentEnv", + scope = "root", + summary = "Sets the env var reference used to select environment-specific files.", + documentation = "Usually used in `.env.schema`, for example `# @currentEnv=\$APP_ENV`.", + insertText = "@currentEnv=\${'$'}\${'$'}{1:APP_ENV}", + ), + DecoratorInfo( + name = "defaultRequired", + scope = "root", + summary = "Controls whether items default to required, optional, or inferred.", + documentation = "Valid values are `true`, `false`, or `infer`.", + insertText = "@defaultRequired=\${'$'}{1|infer,true,false|}", + ), + DecoratorInfo( + name = "defaultSensitive", + scope = "root", + summary = "Controls whether items default to sensitive.", + documentation = "Valid values are `true`, `false`, or `inferFromPrefix(PUBLIC_)`.", + insertText = "@defaultSensitive=\${'$'}{1|true,false,inferFromPrefix(PUBLIC_)|}", + ), + DecoratorInfo( + name = "disable", + scope = "root", + summary = "Disables the current file, optionally conditionally.", + documentation = "Can be set directly or with a boolean resolver like `forEnv(test)`.", + insertText = "@disable=${booleanChoiceSnippet()}", + ), + DecoratorInfo( + name = "generateTypes", + scope = "root", + summary = "Generates types from the schema.", + documentation = "Common usage: `# @generateTypes(lang=ts, path=./env.d.ts)`.", + insertText = "@generateTypes(lang=\${'$'}{1:ts}, path=\${'$'}{2:./env.d.ts})", + isFunction = true, + ), + DecoratorInfo( + name = "import", + scope = "root", + summary = "Imports schema and values from another file or directory.", + documentation = "Takes a path as the first positional arg. Optional named args include `enabled` and `allowMissing`.", + insertText = "@import(\${'$'}{1:./.env.shared})", + isFunction = true, + ), + DecoratorInfo( + name = "plugin", + scope = "root", + summary = "Loads a plugin that can register decorators, types, and resolvers.", + documentation = "Use the package name or identifier as the first argument.", + insertText = "@plugin(\${'$'}{1:@varlock/plugin-name})", + isFunction = true, + ), + DecoratorInfo( + name = "redactLogs", + scope = "root", + summary = "Controls whether sensitive values are redacted in logs.", + documentation = "Boolean decorator. Sensitive values are replaced with redacted output when enabled.", + insertText = "@redactLogs=${booleanChoiceSnippet()}", + ), + DecoratorInfo( + name = "preventLeaks", + scope = "root", + summary = "Controls whether outgoing responses are scanned for secret leaks.", + documentation = "Boolean decorator that enables leak-prevention checks.", + insertText = "@preventLeaks=${booleanChoiceSnippet()}", + ), + DecoratorInfo( + name = "setValuesBulk", + scope = "root", + summary = "Injects many config values from a single data source.", + documentation = "Common usage: `# @setValuesBulk(exec(\"vault kv get ...\"), format=json)`.", + insertText = "@setValuesBulk(\${'$'}{1:exec(\"command\")}, format=\${'$'}{2|json,env|})", + isFunction = true, + ), + ) + + val ITEM_DECORATORS = listOf( + DecoratorInfo(name = "required", scope = "item", summary = "Marks an item as required.", + documentation = "Equivalent to `@required=true`. Can also be driven by boolean resolvers like `forEnv(...)`.", + insertText = "@required"), + DecoratorInfo(name = "optional", scope = "item", summary = "Marks an item as optional.", + documentation = "Equivalent to `@required=false`.", insertText = "@optional"), + DecoratorInfo(name = "sensitive", scope = "item", summary = "Marks an item as sensitive.", + documentation = "Sensitive items are redacted and treated as secrets.", insertText = "@sensitive"), + DecoratorInfo(name = "public", scope = "item", summary = "Marks an item as not sensitive.", + documentation = "Equivalent to `@sensitive=false`.", insertText = "@public"), + DecoratorInfo(name = "type", scope = "item", summary = "Sets the item data type.", + documentation = "Accepts a data type name or configured type call like `string(minLength=5)`.", + insertText = "@type=\${'$'}{1:string}"), + DecoratorInfo(name = "example", scope = "item", summary = "Adds an example value.", + documentation = "Use an example when the stored value should stay empty or secret.", + insertText = "@example=\${'$'}{1:\"example value\"}"), + DecoratorInfo(name = "docsUrl", scope = "item", summary = "Deprecated single docs URL decorator.", + documentation = "Deprecated. Prefer `@docs(...)`, which supports multiple docs entries.", + insertText = "@docsUrl=\${'$'}{1:https://example.com/docs}", deprecated = "Use docs() instead."), + DecoratorInfo(name = "docs", scope = "item", summary = "Attaches documentation URLs to an item.", + documentation = "Supports `@docs(url)` or `@docs(\"Label\", url)` and may be used multiple times.", + insertText = "@docs(\${'$'}{1:https://example.com/docs})", isFunction = true), + DecoratorInfo(name = "icon", scope = "item", summary = "Attaches an icon identifier to an item.", + documentation = "Useful for generated docs and UI surfaces that show schema metadata.", + insertText = "@icon=\${'$'}{1:mdi:key}"), + ) + + val DATA_TYPES = listOf( + DataTypeInfo("string", "String value with optional length, casing, and pattern settings.", + "Example: `@type=string(minLength=5, startsWith=pk-)`.", "string", + listOf( + DataTypeOptionSnippet("minLength", "minLength=\${'$'}{1:1}", "Minimum allowed string length."), + DataTypeOptionSnippet("maxLength", "maxLength=\${'$'}{1:255}", "Maximum allowed string length."), + DataTypeOptionSnippet("isLength", "isLength=\${'$'}{1:32}", "Exact required string length."), + DataTypeOptionSnippet("startsWith", "startsWith=\${'$'}{1:prefix-}", "Required starting substring."), + DataTypeOptionSnippet("endsWith", "endsWith=\${'$'}{1:-suffix}", "Required ending substring."), + DataTypeOptionSnippet("matches", "matches=\${'$'}{1:\"^[A-Z0-9_]+\${'$'}\"}", "Regex or string pattern to match."), + DataTypeOptionSnippet("toUpperCase", "toUpperCase=${booleanChoiceSnippet()}", "Coerce the final value to uppercase."), + DataTypeOptionSnippet("toLowerCase", "toLowerCase=${booleanChoiceSnippet()}", "Coerce the final value to lowercase."), + DataTypeOptionSnippet("allowEmpty", "allowEmpty=${booleanChoiceSnippet()}", "Allow empty string values."), + )), + DataTypeInfo("number", "Number with min/max, precision, and divisibility options.", + "Example: `@type=number(min=0, max=100, precision=1)`.", "number", + listOf( + DataTypeOptionSnippet("min", "min=\${'$'}{1:0}", "Minimum allowed number."), + DataTypeOptionSnippet("max", "max=\${'$'}{1:100}", "Maximum allowed number."), + DataTypeOptionSnippet("coerceToMinMaxRange", "coerceToMinMaxRange=${booleanChoiceSnippet()}", "Clamp values into the allowed min/max range."), + DataTypeOptionSnippet("isDivisibleBy", "isDivisibleBy=\${'$'}{1:1}", "Require divisibility by the given number."), + DataTypeOptionSnippet("isInt", "isInt=${booleanChoiceSnippet()}", "Require integer values."), + DataTypeOptionSnippet("precision", "precision=\${'$'}{1:2}", "Allowed decimal precision for non-integers."), + )), + DataTypeInfo("boolean", "Boolean value.", "Accepts common truthy and falsy string values during coercion.", "boolean"), + DataTypeInfo("url", "URL with optional HTTPS prepending and allowed-domain checks.", + "Example: `@type=url(prependHttps=true)`.", "url", + listOf( + DataTypeOptionSnippet("prependHttps", "prependHttps=${booleanChoiceSnippet()}", "Automatically add `https://` when missing."), + DataTypeOptionSnippet("allowedDomains", "allowedDomains=\${'$'}{1:\"example.com\"}", "Restrict the URL host to an allowed domain list."), + )), + DataTypeInfo("simple-object", "JSON-like object value.", "Coerces plain objects or JSON strings into objects.", "simple-object"), + DataTypeInfo("enum", "Restricted value list.", "Requires explicit options, for example `@type=enum(dev, preview, prod)`.", + "enum(\${'$'}{1:development}, \${'$'}{2:preview}, \${'$'}{3:production})"), + DataTypeInfo("email", "Email address.", "Example: `@type=email(normalize=true)`.", "email", + listOf(DataTypeOptionSnippet("normalize", "normalize=${booleanChoiceSnippet()}", "Lowercase the email before validation."))), + DataTypeInfo("ip", "IPv4 or IPv6 address.", "Example: `@type=ip(version=4, normalize=true)`.", "ip", + listOf( + DataTypeOptionSnippet("version", "version=\${'$'}{1|4,6|}", "Restrict to IPv4 or IPv6."), + DataTypeOptionSnippet("normalize", "normalize=${booleanChoiceSnippet()}", "Normalize the value before validation."), + )), + DataTypeInfo("port", "Port number between 0 and 65535.", "Example: `@type=port(min=1024, max=9999)`.", "port", + listOf( + DataTypeOptionSnippet("min", "min=\${'$'}{1:1024}", "Minimum allowed port."), + DataTypeOptionSnippet("max", "max=\${'$'}{1:9999}", "Maximum allowed port."), + )), + DataTypeInfo("semver", "Semantic version string.", "Validates standard semver values like `1.2.3`.", "semver"), + DataTypeInfo("isoDate", "ISO 8601 date string.", "Supports date strings with optional time and milliseconds.", "isoDate"), + DataTypeInfo("uuid", "UUID string.", "Validates RFC4122 UUIDs.", "uuid"), + DataTypeInfo("md5", "MD5 hash string.", "Validates 32-character hexadecimal MD5 values.", "md5"), + ) + + val RESOLVERS = listOf( + ResolverInfo("concat", "Concatenates multiple values into one string.", "Equivalent to string expansion with multiple segments.", + "concat(\${'$'}{1:\"prefix-\"}, \${'$'}{2:\$OTHER})"), + ResolverInfo("fallback", "Returns the first non-empty value.", "Useful for layered defaults and optional sources.", + "fallback(\${'$'}{1:\$PRIMARY}, \${'$'}{2:\$SECONDARY}, \${'$'}{3:\"default\"})"), + ResolverInfo("exec", "Executes a command and uses stdout as the value.", "Trailing newlines are trimmed automatically.", + """exec(`${'$'}{1:command}`)"""), + ResolverInfo("ref", "References another config item.", "Usually you can use `\$ITEM` directly, but `ref()` is useful when composing functions.", + "ref(\${'$'}{1:\"OTHER_KEY\"})"), + ResolverInfo("regex", "Creates a regular expression for use inside other functions.", "Intended for use in other resolvers like `remap()`.", + "regex(\${'$'}{1:\"^dev.*\"})"), + ResolverInfo("remap", "Maps one value to another based on match rules.", "Use key/value remapping pairs after the source value.", + "remap(\${'$'}{1:\$SOURCE}, \${'$'}{2:production}=\${'$'}{3:\"main\"})"), + ResolverInfo("forEnv", "Resolves to true when the current environment matches.", "Requires `@currentEnv` to be set in the schema.", + "forEnv(\${'$'}{1:development})"), + ResolverInfo("eq", "Checks whether two values are equal.", "Returns a boolean.", "eq(\${'$'}{1:\$LEFT}, \${'$'}{2:\"value\"})"), + ResolverInfo("if", "Returns different values based on a boolean condition.", "Supports boolean-only usage or explicit true/false values.", + "if(\${'$'}{1:eq(\$ENV, \"prod\")}, \${'$'}{2:\"https://api.example.com\"}, \${'$'}{3:\"https://staging-api.example.com\"})"), + ResolverInfo("not", "Negates a value.", "Falsy values become `true`, truthy values become `false`.", "not(\${'$'}{1:forEnv(production)})"), + ResolverInfo("isEmpty", "Checks whether a value is undefined or empty.", "Useful for conditionals and optional env values.", + "isEmpty(\${'$'}{1:\$OPTIONAL_KEY})"), + ResolverInfo("inferFromPrefix", "Special helper for `@defaultSensitive`.", + "Used as `@defaultSensitive=inferFromPrefix(PUBLIC_)`.", "inferFromPrefix(\${'$'}{1:PUBLIC_})"), + ) + + val DECORATORS_BY_NAME: Map = (ROOT_DECORATORS + ITEM_DECORATORS).associateBy { it.name } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommenter.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommenter.kt new file mode 100644 index 00000000..62a20895 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommenter.kt @@ -0,0 +1,12 @@ +package dev.dmno.envspec + +import com.intellij.lang.Commenter + +class EnvSpecCommenter : Commenter { + + override fun getLineCommentPrefix(): String = "# " + override fun getBlockCommentPrefix(): String? = null + override fun getBlockCommentSuffix(): String? = null + override fun getCommentedBlockCommentPrefix(): String? = null + override fun getCommentedBlockCommentSuffix(): String? = null +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt new file mode 100644 index 00000000..fea86040 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt @@ -0,0 +1,257 @@ +package dev.dmno.envspec + +import com.intellij.codeInsight.completion.CompletionContributor +import com.intellij.codeInsight.completion.CompletionParameters +import com.intellij.codeInsight.completion.CompletionProvider +import com.intellij.codeInsight.completion.CompletionResultSet +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.codeInsight.completion.InsertHandler +import com.intellij.codeInsight.completion.InsertionContext +import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.patterns.PlatformPatterns +import com.intellij.util.ProcessingContext +import java.util.regex.Pattern + +class EnvSpecCompletionContributor : CompletionContributor() { + + init { + extend(CompletionType.BASIC, PlatformPatterns.psiElement().withLanguage(EnvSpecLanguage), + object : CompletionProvider() { + override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { + doAddCompletions(parameters, result) + } + }) + } + + companion object { + private val ENV_KEY_PATTERN = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=") + } + + private fun doAddCompletions(params: CompletionParameters, result: CompletionResultSet) { + val file = params.originalFile as? EnvSpecFile ?: return + val document = params.editor.document + val offset = params.offset + val line = document.getLineNumber(offset) + val lineStart = document.getLineStartOffset(line) + val linePrefix = document.getText(com.intellij.openapi.util.TextRange(lineStart, offset)) + val commentStart = linePrefix.indexOf('#') + val commentPrefix = if (commentStart >= 0) linePrefix.substring(commentStart + 1) else "" + + val lineDocument = object : LineDocument { + override val lineCount: Int get() = document.lineCount + override fun lineAt(l: Int): LineInfo = LineInfo(document.getText(com.intellij.openapi.util.TextRange(document.getLineStartOffset(l), document.getLineEndOffset(l)))) + } + + // $KEY reference completion + val referenceContext = matchReference(linePrefix, line, offset, lineStart) + if (referenceContext != null) { + createReferenceItems(lineDocument, referenceContext).forEach { result.addElement(it) } + return + } + + // Enum value completion + val enumValueContext = getEnumValueContext(lineDocument, line, linePrefix, lineStart, offset) + if (enumValueContext != null) { + createEnumValueItems(enumValueContext).forEach { result.addElement(it) } + return + } + + if (commentStart >= 0) { + val existingDecoratorNames = EnvSpecCompletionCore.getExistingDecoratorNames(lineDocument, line, commentPrefix) + + // Type option completion + val typeOptionContext = matchTypeOption(commentPrefix, line, offset, lineStart) + if (typeOptionContext != null) { + typeOptionContext.dataType.optionSnippets!!.forEach { option -> + result.addElement(createDataTypeOptionItem(option, typeOptionContext)) + } + return + } + + // @type= completion + val typeContext = matchTypeValue(commentPrefix, line, offset, lineStart) + if (typeContext != null) { + EnvSpecCatalog.DATA_TYPES.forEach { result.addElement(createDataTypeItem(it, typeContext)) } + return + } + + // Decorator value completion + val decoratorValueContext = matchDecoratorValue(commentPrefix, line, offset, lineStart) + if (decoratorValueContext != null) { + createDecoratorValueItems(lineDocument, decoratorValueContext).forEach { result.addElement(it) } + return + } + + // Decorator completion + val decoratorContext = matchDecoratorName(commentPrefix, line, offset, lineStart) + if (decoratorContext != null) { + val decorators = if (EnvSpecCompletionCore.isInHeader(lineDocument, line)) EnvSpecCatalog.ROOT_DECORATORS else EnvSpecCatalog.ITEM_DECORATORS + EnvSpecCompletionCore.filterAvailableDecorators(decorators, existingDecoratorNames).forEach { + result.addElement(createDecoratorItem(it, decoratorContext)) + } + return + } + } + + // Resolver completion + val resolverContext = matchResolverValue(linePrefix, line, offset, lineStart) + if (resolverContext != null) { + EnvSpecCatalog.RESOLVERS.forEach { result.addElement(createResolverItem(it, resolverContext)) } + } + } + + private data class ReplaceRange(val line: Int, val start: Int, val end: Int) + + private fun matchDecoratorName(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { + val match = Regex("(^|\\s)(@[\\w-]*)$").find(commentPrefix) ?: return null + val token = match.groupValues[2] + val endInLine = offset - lineStart + return ReplaceRange(line, endInLine - token.length, endInLine) + } + + private fun matchTypeValue(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { + val match = Regex("(^|\\s)@type=([\\w-]*)$").find(commentPrefix) ?: return null + val typedValue = match.groupValues[2] + val endInLine = offset - lineStart + return ReplaceRange(line, endInLine - typedValue.length, endInLine) + } + + private fun matchTypeOption(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRangeData? { + val dataType = EnvSpecCompletionCore.getTypeOptionDataType(EnvSpecCatalog.DATA_TYPES, commentPrefix) ?: return null + if (dataType.optionSnippets.isNullOrEmpty()) return null + val match = Regex("(^|\\s)@type=([A-Za-z][\\w-]*)\\((?:[^#)]*?,\\s*)?([\\w-]*)$").find(commentPrefix) ?: return null + val typedValue = match.groupValues[3] + val endInLine = offset - lineStart + return ReplaceRangeData(dataType, ReplaceRange(line, endInLine - typedValue.length, endInLine)) + } + + private data class ReplaceRangeData(val dataType: DataTypeInfo, val range: ReplaceRange) + + private fun matchReference(linePrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { + val match = Regex("\\$([A-Za-z0-9_]*)$").find(linePrefix) ?: return null + val endInLine = offset - lineStart + return ReplaceRange(line, endInLine - match.value.length, endInLine) + } + + private fun matchResolverValue(linePrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { + val match = Regex("(?:=\\s*|[(,]\\s*)([A-Za-z][\\w-]*)$").find(linePrefix) ?: return null + val endInLine = offset - lineStart + return ReplaceRange(line, endInLine - match.groupValues[1].length, endInLine) + } + + private fun matchDecoratorValue(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRangeDecorator? { + val match = Regex("(^|\\s)@([\\w-]+)=([A-Za-z][\\w-]*)$").find(commentPrefix) ?: return null + val decorator = EnvSpecCatalog.DECORATORS_BY_NAME[match.groupValues[2]] + val typedValue = match.groupValues[3] + val endInLine = offset - lineStart + return ReplaceRangeDecorator(decorator, ReplaceRange(line, endInLine - typedValue.length, endInLine)) + } + + private data class ReplaceRangeDecorator(val decorator: DecoratorInfo?, val range: ReplaceRange) + + private fun matchItemValue(linePrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { + val match = Regex("^\\s*[A-Za-z_][A-Za-z0-9._-]*\\s*=\\s*([A-Za-z0-9._-]*)$").find(linePrefix) ?: return null + val typedValue = match.groupValues[1] + val endInLine = offset - lineStart + return ReplaceRange(line, endInLine - typedValue.length, endInLine) + } + + private fun getEnumValueContext(document: LineDocument, line: Int, linePrefix: String, lineStart: Int, offset: Int): EnumValueContext? { + val itemContext = matchItemValue(linePrefix, line, offset, lineStart) ?: return null + val enumValues = EnvSpecCompletionCore.getEnumValuesFromPrecedingComments(document, line) ?: return null + return EnumValueContext(itemContext, enumValues) + } + + private data class EnumValueContext(val range: ReplaceRange, val enumValues: List) + + private fun createDecoratorItem(info: DecoratorInfo, range: ReplaceRange): LookupElementBuilder { + val insertHandler = createReplaceHandler(range, info.insertText) + var item = LookupElementBuilder.create("@${info.name}") + .withInsertHandler(insertHandler) + .withTypeText(if (info.scope == "root") "Root decorator" else "Item decorator") + .withTailText(" " + info.insertText, true) + if (info.deprecated != null) { + item = item.withStrikeoutness(true) + } + return item + } + + private fun createReplaceHandler(range: ReplaceRange, insertText: String): InsertHandler { + return InsertHandler { ctx: InsertionContext, _ -> + WriteCommandAction.runWriteCommandAction(ctx.project) { + val doc = ctx.document + val start = doc.getLineStartOffset(range.line) + range.start + val end = doc.getLineStartOffset(range.line) + range.end + doc.replaceString(start, end, insertText) + } + } + } + + private fun createDataTypeItem(info: DataTypeInfo, range: ReplaceRange): LookupElementBuilder { + val insertText = info.insertText ?: info.name + return LookupElementBuilder.create(info.name) + .withInsertHandler(createReplaceHandler(range, insertText)) + .withTypeText("@type data type") + .withTailText(" ${info.summary}", true) + } + + private fun createDataTypeOptionItem(option: DataTypeOptionSnippet, context: ReplaceRangeData): LookupElementBuilder { + val range = context.range + return LookupElementBuilder.create(option.name) + .withInsertHandler(createReplaceHandler(range, option.insertText)) + .withTypeText("@type option") + .withTailText(" ${option.documentation}", true) + } + + private fun createResolverItem(info: ResolverInfo, range: ReplaceRange): LookupElementBuilder { + return LookupElementBuilder.create("${info.name}()") + .withInsertHandler(createReplaceHandler(range, info.insertText)) + .withTypeText("Resolver function") + .withTailText(" ${info.summary}", true) + } + + private fun createReferenceItems(document: LineDocument, range: ReplaceRange): List { + val keys = mutableSetOf("VARLOCK_ENV") + for (i in 0 until document.lineCount) { + val matcher = ENV_KEY_PATTERN.matcher(document.lineAt(i).text) + if (matcher.find()) keys.add(matcher.group(1)) + } + return keys.sorted().map { key -> + LookupElementBuilder.create(key) + .withInsertHandler(createReplaceHandler(range, key)) + .withTypeText("Config item reference") + .withTailText(" Reference `$key` with `\$$key`.", true) + } + } + + private fun createKeywordItems(values: List, range: ReplaceRange): List { + return values.map { value -> + LookupElementBuilder.create(value) + .withInsertHandler(createReplaceHandler(range, value)) + } + } + + private fun createDecoratorValueItems(document: LineDocument, context: ReplaceRangeDecorator): List { + return when (context.decorator?.name) { + "currentEnv" -> createReferenceItems(document, context.range) + "defaultRequired" -> createKeywordItems(listOf("infer", "true", "false"), context.range) + "defaultSensitive" -> createKeywordItems(listOf("true", "false"), context.range) + + EnvSpecCatalog.RESOLVERS.filter { it.name == "inferFromPrefix" }.map { createResolverItem(it, context.range) } + "required", "optional", "sensitive", "public", "disable" -> createKeywordItems(listOf("true", "false"), context.range) + + EnvSpecCatalog.RESOLVERS.filter { it.name in listOf("forEnv", "eq", "if", "not", "isEmpty") }.map { createResolverItem(it, context.range) } + else -> emptyList() + } + } + + private fun createEnumValueItems(context: EnumValueContext): List { + val range = context.range + return context.enumValues.map { value -> + LookupElementBuilder.create(value) + .withInsertHandler(createReplaceHandler(range, value)) + .withTypeText("@type=enum value") + .withTailText(" Allowed enum value `$value`.", true) + } + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionCore.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionCore.kt new file mode 100644 index 00000000..3e4dd2ee --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionCore.kt @@ -0,0 +1,101 @@ +package dev.dmno.envspec + +interface LineDocument { + val lineCount: Int + fun lineAt(line: Int): LineInfo +} + +data class LineInfo(val text: String) + +object EnvSpecCompletionCore { + + private val HEADER_SEPARATOR_PATTERN = Regex("^\\s*#\\s*---+\\s*$") + private val DECORATOR_PATTERN = Regex("@([A-Za-z][\\w-]*)") + private val INCOMPATIBLE_DECORATORS = mapOf( + "required" to setOf("optional"), + "optional" to setOf("required"), + "sensitive" to setOf("public"), + "public" to setOf("sensitive"), + ) + + fun isInHeader(document: LineDocument, lineNumber: Int): Boolean { + for (line in lineNumber downTo 0) { + if (HEADER_SEPARATOR_PATTERN.containsMatchIn(document.lineAt(line).text)) return false + } + return true + } + + fun getExistingDecoratorNames(document: LineDocument, lineNumber: Int, commentPrefix: String): Set { + val names = mutableSetOf() + for (line in lineNumber - 1 downTo 0) { + val text = document.lineAt(line).text.trim() + if (!text.startsWith("#")) break + DECORATOR_PATTERN.findAll(text).forEach { names.add(it.groupValues[1]) } + } + DECORATOR_PATTERN.findAll(commentPrefix).forEach { names.add(it.groupValues[1]) } + return names + } + + fun filterAvailableDecorators(decorators: List, existingDecoratorNames: Set): List { + return decorators.filter { decorator -> + if (!decorator.isFunction && existingDecoratorNames.contains(decorator.name)) return@filter false + val incompatible = INCOMPATIBLE_DECORATORS[decorator.name] ?: return@filter true + !incompatible.any { existingDecoratorNames.contains(it) } + } + } + + fun splitEnumArgs(input: String): List { + return splitArgs(input).map { it.replace(Regex("^['\"]|['\"]$"), "").trim() }.filter { it.isNotEmpty() } + } + + fun getEnumValuesFromPrecedingComments(document: LineDocument, lineNumber: Int): List? { + for (line in lineNumber - 1 downTo 0) { + val text = document.lineAt(line).text.trim() + if (!text.startsWith("#")) break + val match = Regex("@type=enum\\((.*)\\)").find(text) ?: continue + return splitEnumArgs(match.groupValues[1]) + } + return null + } + + fun getTypeOptionDataType(dataTypes: List, commentPrefix: String): DataTypeInfo? { + val match = Regex("(^|\\s)@type=([A-Za-z][\\w-]*)\\([^#)]*$").find(commentPrefix) ?: return null + return dataTypes.find { it.name == match.groupValues[2] } + } + + private fun splitArgs(input: String): List { + val parts = mutableListOf() + var current = "" + var quote: Char? = null + var depth = 0 + for (char in input) { + when { + quote != null -> { + current += char + if (char == quote) quote = null + } + char == '"' || char == '\'' -> { + quote = char + current += char + } + char == '(' -> { + depth++ + current += char + } + char == ')' -> { + depth = maxOf(depth - 1, 0) + current += char + } + char == ',' && depth == 0 -> { + val value = current.trim() + if (value.isNotEmpty()) parts.add(value) + current = "" + } + else -> current += char + } + } + val value = current.trim() + if (value.isNotEmpty()) parts.add(value) + return parts + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt new file mode 100644 index 00000000..5c15428b --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt @@ -0,0 +1,253 @@ +package dev.dmno.envspec + +import java.net.InetAddress + +object EnvSpecDiagnosticsCore { + + private val DECORATOR_PATTERN = Regex("@([A-Za-z][\\w-]*)(?:\\([^)]*\\)|=[^\\s#]+)?") + private const val MAX_MATCHES_PATTERN_LENGTH = 200 + private val INCOMPATIBLE_DECORATOR_PAIRS = listOf( + listOf("required", "optional"), + listOf("sensitive", "public"), + ) + + data class TypeInfo(val name: String, val args: List, val options: Map) + data class DecoratorOccurrence(val name: String, val line: Int, val start: Int, val end: Int) + data class CoreDiagnostic(val line: Int, val start: Int, val end: Int, val message: String) + + fun stripInlineComment(value: String): String { + var quote: Char? = null + for (i in value.indices) { + val char = value[i] + when { + quote != null -> { + if (char == quote) quote = null + } + char == '"' || char == '\'' -> quote = char + char == '#' && (i == 0 || value[i - 1].isWhitespace()) -> + return value.substring(0, i).trimEnd() + else -> {} + } + } + return value.trim() + } + + fun unquote(value: String): String { + if ((value.startsWith('"') && value.endsWith('"')) || + (value.startsWith('\'') && value.endsWith('\''))) { + return value.substring(1, value.length - 1) + } + return value + } + + fun isDynamicValue(value: String): Boolean = + Regex("\\\$[A-Za-z_]").containsMatchIn(value) || Regex("^[A-Za-z][\\w-]*\\(").containsMatchIn(value) + + private fun splitCommaSeparatedArgs(input: String): List { + val parts = mutableListOf() + var current = "" + var quote: Char? = null + var depth = 0 + for (char in input) { + when { + quote != null -> { + current += char + if (char == quote) quote = null + } + char == '"' || char == '\'' -> { quote = char; current += char } + char == '(' -> { depth++; current += char } + char == ')' -> { depth = maxOf(depth - 1, 0); current += char } + char == ',' && depth == 0 -> { + val v = current.trim() + if (v.isNotEmpty()) parts.add(v) + current = "" + } + else -> current += char + } + } + val v = current.trim() + if (v.isNotEmpty()) parts.add(v) + return parts + } + + fun splitEnumArgs(input: String): List = + splitCommaSeparatedArgs(input).map { unquote(it).trim() }.filter { it.isNotEmpty() } + + private fun parseBooleanOption(value: Any?): Boolean? { + when (value) { + true -> return true + false -> return false + "true" -> return true + "false" -> return false + } + return null + } + + private fun parseTypeOptions(input: String): Map { + return splitCommaSeparatedArgs(input).mapNotNull { part -> + val sep = part.indexOf('=') + if (sep < 0) return@mapNotNull null + val key = part.substring(0, sep).trim() + val rawValue = part.substring(sep + 1).trim() + if (key.isEmpty()) return@mapNotNull null + key to unquote(rawValue) + }.toMap() + } + + fun getPrecedingCommentBlock(document: LineDocument, lineNumber: Int): List { + val lines = mutableListOf() + for (line in lineNumber - 1 downTo 0) { + val text = document.lineAt(line).text.trim() + if (!text.startsWith("#")) break + lines.add(0, text) + } + return lines + } + + fun getTypeInfoFromPrecedingComments(document: LineDocument, lineNumber: Int): TypeInfo? { + val commentBlock = getPrecedingCommentBlock(document, lineNumber) + for (index in commentBlock.indices.reversed()) { + val match = Regex("@type=([A-Za-z][\\w-]*)(?:\\((.*)\\))?").find(commentBlock[index]) ?: continue + return if (match.groupValues[1] == "enum") { + TypeInfo("enum", splitEnumArgs(match.groupValues[2]), emptyMap()) + } else { + TypeInfo(match.groupValues[1], emptyList(), parseTypeOptions(match.groupValues[2])) + } + } + return null + } + + fun getDecoratorOccurrences(lineText: String, lineNumber: Int): List { + return DECORATOR_PATTERN.findAll(lineText).map { match -> + DecoratorOccurrence(match.groupValues[1], lineNumber, match.range.first, match.range.last + 1) + }.toList() + } + + fun createDecoratorDiagnostics(occurrences: List): List { + val diagnostics = mutableListOf() + val seenCounts = mutableMapOf() + val reportedRanges = mutableSetOf() + for (occ in occurrences) { + val count = seenCounts.getOrDefault(occ.name, 0) + seenCounts[occ.name] = count + 1 + val decorator = EnvSpecCatalog.DECORATORS_BY_NAME[occ.name] + if (decorator?.isFunction != true && count >= 1) { + diagnostics.add(CoreDiagnostic(occ.line, occ.start, occ.end, + "@${occ.name} can only be used once in the same decorator block.")) + } + } + for ((left, right) in INCOMPATIBLE_DECORATOR_PAIRS) { + val conflicting = occurrences.filter { it.name == left || it.name == right } + if (!conflicting.any { it.name == left } || !conflicting.any { it.name == right }) continue + for (occ in conflicting) { + val key = "${occ.line}:${occ.start}:${occ.end}" + if (key in reportedRanges) continue + reportedRanges.add(key) + diagnostics.add(CoreDiagnostic(occ.line, occ.start, occ.end, + "@$left and @$right cannot be used together.")) + } + } + return diagnostics + } + + private fun validateStringValue(value: String, options: Map): String? { + val allowEmpty = parseBooleanOption(options["allowEmpty"]) + if (allowEmpty != true && value.isEmpty()) return "Value cannot be empty." + (options["minLength"] as? String)?.let { if (value.length < it.toInt()) return "Value must be at least $it characters long." } + (options["maxLength"] as? String)?.let { if (value.length > it.toInt()) return "Value must be at most $it characters long." } + (options["isLength"] as? String)?.let { if (value.length != it.toInt()) return "Value must be exactly $it characters long." } + (options["startsWith"] as? String)?.let { if (!value.startsWith(it)) return "Value must start with `$it`." } + (options["endsWith"] as? String)?.let { if (!value.endsWith(it)) return "Value must end with `$it`." } + (options["matches"] as? String)?.let { m -> + if (m.length > MAX_MATCHES_PATTERN_LENGTH) return@let + try { + if (!Regex(m).containsMatchIn(value)) return "Value must match `$m`." + } catch (_: Exception) {} + } + return null + } + + private fun validateNumberValue(value: String, options: Map): String? { + val n = value.toDoubleOrNull() ?: return "Value must be a valid number." + if (!n.isFinite()) return "Value must be a valid number." + (options["min"] as? String)?.let { if (n < it.toDouble()) return "Value must be greater than or equal to $it." } + (options["max"] as? String)?.let { if (n > it.toDouble()) return "Value must be less than or equal to $it." } + if (options["isInt"] == "true" || options["isInt"] == true) { + if (value.toDoubleOrNull()?.let { it != it.toInt().toDouble() } == true) return "Value must be an integer." + } + (options["isDivisibleBy"] as? String)?.let { + if (n % it.toDouble() != 0.0) return "Value must be divisible by $it." + } + (options["precision"] as? String)?.let { + val decimals = value.substringAfter('.', "") + if (decimals.length > it.toInt()) return "Value must have at most $it decimal places." + } + return null + } + + private fun validateUrlValue(value: String, options: Map): String? { + val prependHttps = parseBooleanOption(options["prependHttps"]) + val hasProtocol = Regex("^https?://", RegexOption.IGNORE_CASE).containsMatchIn(value) + if (prependHttps == true && hasProtocol) return "URL should omit the protocol when prependHttps=true." + if (prependHttps != true && !hasProtocol) return "URL must include a protocol unless prependHttps=true." + return try { + val url = java.net.URL(if (prependHttps == true) "https://$value" else value) + val allowedDomains = (options["allowedDomains"] as? String)?.let { splitEnumArgs(it) } ?: emptyList() + if (allowedDomains.isNotEmpty() && !allowedDomains.contains(url.host.lowercase())) { + "URL host must be one of: ${allowedDomains.joinToString(", ")}." + } else null + } catch (_: Exception) { + "Value must be a valid URL." + } + } + + private fun isIP(value: String): Int? { + return try { + val addr = InetAddress.getByName(value) + when (addr) { + is java.net.Inet4Address -> 4 + is java.net.Inet6Address -> 6 + else -> null + } + } catch (_: Exception) { + null + } + } + + fun validateStaticValue(typeInfo: TypeInfo, value: String): String? { + return when (typeInfo.name) { + "string" -> validateStringValue(value, typeInfo.options) + "number" -> validateNumberValue(value, typeInfo.options) + "boolean" -> if (Regex("^(true|false|1|0|yes|no|on|off)$", RegexOption.IGNORE_CASE).matches(value)) null else "Value must be a boolean." + "email" -> if (Regex("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$").matches(value)) null else "Value must be a valid email address." + "url" -> validateUrlValue(value, typeInfo.options) + "ip" -> { + val version = (typeInfo.options["version"] as? String)?.toIntOrNull() ?: 0 + val detected = isIP(value) + when { + detected == null -> "Value must be a valid IPv4 or IPv6 address." + (version == 4 || version == 6) && detected != version -> "Value must be a valid IPv$version address." + else -> null + } + } + "port" -> { + val n = value.toIntOrNull() ?: -1 + if (n !in 0..65535) return "Value must be a valid port number." + (typeInfo.options["min"] as? String)?.let { if (n < it.toInt()) return "Port must be greater than or equal to $it." } + (typeInfo.options["max"] as? String)?.let { if (n > it.toInt()) return "Port must be less than or equal to $it." } + null + } + "semver" -> if (Regex("^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$").matches(value)) null else "Value must be a valid semantic version." + "isoDate" -> if (Regex("^\\d{4}-\\d{2}-\\d{2}(?:[T ][0-9:.+-Z]*)?$").matches(value)) { + try { + java.time.LocalDate.parse(value.substring(0, 10)) + null + } catch (_: Exception) { "Value must be a valid ISO date." } + } else "Value must be a valid ISO date." + "uuid" -> if (Regex("^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", RegexOption.IGNORE_CASE).matches(value)) null else "Value must be a valid UUID." + "md5" -> if (Regex("^[0-9a-f]{32}$", RegexOption.IGNORE_CASE).matches(value)) null else "Value must be a valid MD5 hash." + "enum" -> if (value in typeInfo.args) null else "Value must be one of: ${typeInfo.args.joinToString(", ")}." + else -> null + } + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDocumentationProvider.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDocumentationProvider.kt new file mode 100644 index 00000000..badba2e9 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDocumentationProvider.kt @@ -0,0 +1,25 @@ +package dev.dmno.envspec + +import com.intellij.lang.documentation.DocumentationProvider +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiManager + +class EnvSpecDocumentationProvider : DocumentationProvider { + + override fun getQuickNavigateInfo(element: PsiElement, originalElement: PsiElement): String? = null + + override fun getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement): PsiElement? = null + + override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { + if (element.containingFile !is EnvSpecFile) return null + val text = element.text + if (text.startsWith("@")) { + val decName = text.substring(1).takeWhile { it.isLetterOrDigit() || it == '-' } + val dec = EnvSpecCatalog.DECORATORS_BY_NAME[decName] + if (dec != null) { + return "${dec.summary}\n\n${dec.documentation}" + } + } + return null + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFile.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFile.kt new file mode 100644 index 00000000..69166f45 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFile.kt @@ -0,0 +1,10 @@ +package dev.dmno.envspec + +import com.intellij.extapi.psi.PsiFileBase +import com.intellij.openapi.fileTypes.FileType +import com.intellij.psi.FileViewProvider + +class EnvSpecFile(viewProvider: FileViewProvider) : PsiFileBase(viewProvider, EnvSpecLanguage) { + + override fun getFileType(): FileType = EnvSpecFileType.INSTANCE +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt new file mode 100644 index 00000000..9a2f71d1 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt @@ -0,0 +1,18 @@ +package dev.dmno.envspec + +import com.intellij.lang.Language +import com.intellij.openapi.fileTypes.LanguageFileType +import javax.swing.Icon + +class EnvSpecFileType private constructor() : LanguageFileType(EnvSpecLanguage) { + + override fun getName(): String = "EnvSpec" + override fun getDescription(): String = "@env-spec (.env) file" + override fun getDefaultExtension(): String = "env" + override fun getIcon(): Icon? = null + + companion object { + @JvmStatic + val INSTANCE = EnvSpecFileType() + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt new file mode 100644 index 00000000..93f20994 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt @@ -0,0 +1,74 @@ +package dev.dmno.envspec + +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.codeInspection.ProblemHighlightType +import com.intellij.codeInspection.ProblemsHolder +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiElementVisitor +import java.util.regex.Pattern + +class EnvSpecInspection : LocalInspectionTool() { + + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { + return object : PsiElementVisitor() { + override fun visitFile(file: com.intellij.psi.PsiFile) { + if (file !is EnvSpecFile) return + val document = com.intellij.psi.PsiDocumentManager.getInstance(file.project).getDocument(file) ?: return + val lineDocument = object : LineDocument { + override val lineCount: Int get() = document.lineCount + override fun lineAt(l: Int): LineInfo = LineInfo( + document.getText(com.intellij.openapi.util.TextRange(document.getLineStartOffset(l), document.getLineEndOffset(l))) + ) + } + var decoratorBlock = listOf() + for (lineNumber in 0 until document.lineCount) { + val lineText = document.getText(com.intellij.openapi.util.TextRange(document.getLineStartOffset(lineNumber), document.getLineEndOffset(lineNumber))) + val trimmed = lineText.trim() + if (trimmed.startsWith("#")) { + decoratorBlock = decoratorBlock + EnvSpecDiagnosticsCore.getDecoratorOccurrences(lineText, lineNumber) + } else { + if (decoratorBlock.isNotEmpty()) { + EnvSpecDiagnosticsCore.createDecoratorDiagnostics(decoratorBlock).forEach { d -> + holder.registerProblem( + file, + d.message, + ProblemHighlightType.ERROR, + TextRange(document.getLineStartOffset(d.line) + d.start, document.getLineStartOffset(d.line) + d.end) + ) + } + decoratorBlock = emptyList() + } + } + val match = ENV_ASSIGNMENT.matcher(lineText) + if (!match.matches()) continue + val rawValue = EnvSpecDiagnosticsCore.stripInlineComment(match.group(2)!!) + if (rawValue.isEmpty()) continue + if (EnvSpecDiagnosticsCore.isDynamicValue(rawValue)) continue + val typeInfo = EnvSpecDiagnosticsCore.getTypeInfoFromPrecedingComments(lineDocument, lineNumber) ?: continue + val message = EnvSpecDiagnosticsCore.validateStaticValue(typeInfo, EnvSpecDiagnosticsCore.unquote(rawValue)) ?: continue + val valueStart = lineText.indexOf(rawValue) + holder.registerProblem( + file, + message, + ProblemHighlightType.ERROR, + TextRange(document.getLineStartOffset(lineNumber) + valueStart, document.getLineStartOffset(lineNumber) + valueStart + rawValue.length) + ) + } + if (decoratorBlock.isNotEmpty()) { + EnvSpecDiagnosticsCore.createDecoratorDiagnostics(decoratorBlock).forEach { d -> + holder.registerProblem( + file, + d.message, + ProblemHighlightType.ERROR, + TextRange(document.getLineStartOffset(d.line) + d.start, document.getLineStartOffset(d.line) + d.end) + ) + } + } + } + } + } + + companion object { + private val ENV_ASSIGNMENT = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*?)\\s*$") + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLanguage.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLanguage.kt new file mode 100644 index 00000000..db9d6917 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLanguage.kt @@ -0,0 +1,7 @@ +package dev.dmno.envspec + +import com.intellij.lang.Language + +object EnvSpecLanguage : Language("EnvSpec") { + const val ID = "EnvSpec" +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt new file mode 100644 index 00000000..aed1a9a8 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt @@ -0,0 +1,60 @@ +package dev.dmno.envspec + +import com.intellij.lexer.LexerBase +import com.intellij.psi.TokenType +import com.intellij.psi.tree.IElementType + +class EnvSpecLexer : LexerBase() { + + private var buffer: CharSequence = "" + private var bufferEnd = 0 + private var tokenStart = 0 + private var tokenEnd = 0 + private var tokenType: IElementType? = null + + override fun start(buffer: CharSequence, startOffset: Int, endOffset: Int, initialState: Int) { + this.buffer = buffer + this.bufferEnd = endOffset + this.tokenStart = startOffset + this.tokenEnd = startOffset + advance() + } + + override fun getState(): Int = 0 + + override fun getTokenType(): IElementType? = tokenType + + override fun getTokenStart(): Int = tokenStart + + override fun getTokenEnd(): Int = tokenEnd + + override fun getBufferSequence(): CharSequence = buffer + + override fun getBufferEnd(): Int = bufferEnd + + override fun advance() { + tokenStart = tokenEnd + if (tokenEnd >= bufferEnd) { + tokenType = null + return + } + val c = buffer[tokenEnd] + when (c) { + '\r' -> { + tokenEnd++ + if (tokenEnd < bufferEnd && buffer[tokenEnd] == '\n') tokenEnd++ + tokenType = EnvSpecTokenTypes.NEWLINE + } + '\n' -> { + tokenEnd++ + tokenType = EnvSpecTokenTypes.NEWLINE + } + else -> { + while (tokenEnd < bufferEnd && buffer[tokenEnd] != '\r' && buffer[tokenEnd] != '\n') { + tokenEnd++ + } + tokenType = EnvSpecTokenTypes.LINE_CONTENT + } + } + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParser.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParser.kt new file mode 100644 index 00000000..66235987 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParser.kt @@ -0,0 +1,18 @@ +package dev.dmno.envspec + +import com.intellij.lang.ASTNode +import com.intellij.lang.PsiBuilder +import com.intellij.lang.PsiParser +import com.intellij.psi.tree.IElementType + +class EnvSpecParser : PsiParser { + + override fun parse(root: IElementType, builder: PsiBuilder): ASTNode { + val marker = builder.mark() + while (!builder.eof()) { + builder.advanceLexer() + } + marker.done(root) + return builder.treeBuilt + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt new file mode 100644 index 00000000..e0153753 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt @@ -0,0 +1,33 @@ +package dev.dmno.envspec + +import com.intellij.lang.ASTNode +import com.intellij.lang.ParserDefinition +import com.intellij.lang.PsiParser +import com.intellij.lexer.Lexer +import com.intellij.psi.FileViewProvider +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.TokenType +import com.intellij.psi.tree.IFileElementType +import com.intellij.psi.tree.TokenSet + +class EnvSpecParserDefinition : ParserDefinition { + + override fun createLexer(project: com.intellij.openapi.project.Project?): Lexer = EnvSpecLexer() + + override fun createParser(project: com.intellij.openapi.project.Project?): PsiParser = EnvSpecParser() + + override fun getFileNodeType(): IFileElementType = FILE + + override fun getCommentTokens(): TokenSet = TokenSet.EMPTY + + override fun getStringLiteralElements(): TokenSet = TokenSet.EMPTY + + override fun createElement(node: ASTNode): PsiElement = EnvSpecASTWrapperPsiElement(node) + + override fun createFile(viewProvider: FileViewProvider): PsiFile = EnvSpecFile(viewProvider) + + companion object { + val FILE = IFileElementType(EnvSpecLanguage) + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt new file mode 100644 index 00000000..67c1255c --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt @@ -0,0 +1,28 @@ +package dev.dmno.envspec + +import com.intellij.lexer.Lexer +import com.intellij.openapi.editor.colors.TextAttributesKey +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase +import com.intellij.psi.tree.IElementType +import com.intellij.psi.TokenType +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors as Default + +class EnvSpecSyntaxHighlighter : SyntaxHighlighterBase() { + + override fun getHighlightingLexer(): Lexer = EnvSpecLexer() + + override fun getTokenHighlights(tokenType: IElementType): Array { + return when (tokenType) { + EnvSpecTokenTypes.LINE_CONTENT -> LINE_KEYS + EnvSpecTokenTypes.NEWLINE -> EMPTY_KEYS + TokenType.BAD_CHARACTER -> BAD_CHARACTER_KEYS + else -> EMPTY_KEYS + } + } + + companion object { + private val LINE_KEYS = arrayOf(Default.TEMPLATE_LANGUAGE_COLOR) + private val BAD_CHARACTER_KEYS = arrayOf(Default.INVALID_STRING_ESCAPE) + private val EMPTY_KEYS = emptyArray() + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighterFactory.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighterFactory.kt new file mode 100644 index 00000000..61b78c12 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighterFactory.kt @@ -0,0 +1,13 @@ +package dev.dmno.envspec + +import com.intellij.openapi.fileTypes.SyntaxHighlighter +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile + +class EnvSpecSyntaxHighlighterFactory : SyntaxHighlighterFactory() { + + override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?): SyntaxHighlighter { + return EnvSpecSyntaxHighlighter() + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt new file mode 100644 index 00000000..39ee666a --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt @@ -0,0 +1,12 @@ +package dev.dmno.envspec + +import com.intellij.psi.TokenType +import com.intellij.psi.tree.IElementType + +object EnvSpecTokenTypes { + @JvmField + val NEWLINE: IElementType = object : IElementType("ENV_SPEC_NEWLINE", EnvSpecLanguage) {} + + @JvmField + val LINE_CONTENT: IElementType = object : IElementType("ENV_SPEC_LINE_CONTENT", EnvSpecLanguage) {} +} diff --git a/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml b/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml new file mode 100644 index 00000000..ae08c7bd --- /dev/null +++ b/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,27 @@ + + dev.dmno.env-spec + Env Spec Language + dmno-dev + + + + com.intellij.modules.platform + + + + + + + + + + + diff --git a/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionCoreTest.kt b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionCoreTest.kt new file mode 100644 index 00000000..d1e54362 --- /dev/null +++ b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionCoreTest.kt @@ -0,0 +1,66 @@ +package dev.dmno.envspec + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test + +class EnvSpecCompletionCoreTest { + + private fun createDocument(lines: List): LineDocument = object : LineDocument { + override val lineCount: Int get() = lines.size + override fun lineAt(line: Int): LineInfo = LineInfo(lines.getOrElse(line) { "" }) + } + + @Test + fun detectsRootHeaderVsItemSections() { + val document = createDocument(listOf( + "# @defaultRequired=false", + "# ---", + "# @required", + "APP_ENV=", + )) + assertTrue(EnvSpecCompletionCore.isInHeader(document, 0)) + assertFalse(EnvSpecCompletionCore.isInHeader(document, 2)) + } + + @Test + fun collectsDecoratorsAlreadyUsedInCurrentBlock() { + val document = createDocument(listOf( + "# @docs(https://example.com)", + "# @required @type=enum(prod, dev) @", + )) + assertEquals( + setOf("docs", "required", "type"), + EnvSpecCompletionCore.getExistingDecoratorNames(document, 1, " @required @type=enum(prod, dev) @") + ) + } + + @Test + fun filtersDuplicateAndIncompatibleDecoratorsButKeepsRepeatableOnes() { + val available = EnvSpecCompletionCore.filterAvailableDecorators( + EnvSpecCatalog.ITEM_DECORATORS, + setOf("required", "docs"), + ).map { it.name } + assertFalse(available.contains("required")) + assertFalse(available.contains("optional")) + assertTrue(available.contains("docs")) + assertTrue(available.contains("sensitive")) + } + + @Test + fun extractsEnumValuesFromPrecedingComments() { + val document = createDocument(listOf( + "# @required @type=enum(prod, \"preview-app\", dev)", + "APP_ENV=", + )) + assertEquals( + listOf("prod", "preview-app", "dev"), + EnvSpecCompletionCore.getEnumValuesFromPrecedingComments(document, 1) + ) + } + + @Test + fun detectsActiveTypeOptionContext() { + assertEquals("email", EnvSpecCompletionCore.getTypeOptionDataType(EnvSpecCatalog.DATA_TYPES, " @required @type=email(norm")?.name) + assertNull(EnvSpecCompletionCore.getTypeOptionDataType(EnvSpecCatalog.DATA_TYPES, " @required @type=email")) + } +} diff --git a/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCoreTest.kt b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCoreTest.kt new file mode 100644 index 00000000..80696193 --- /dev/null +++ b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCoreTest.kt @@ -0,0 +1,52 @@ +package dev.dmno.envspec + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test + +class EnvSpecDiagnosticsCoreTest { + + private fun createDocument(lines: List): LineDocument = object : LineDocument { + override val lineCount: Int get() = lines.size + override fun lineAt(line: Int): LineInfo = LineInfo(lines.getOrElse(line) { "" }) + } + + @Test + fun flagsDuplicateSingleUseDecoratorsButNotRepeatableFunctionDecorators() { + val duplicates = EnvSpecDiagnosticsCore.createDecoratorDiagnostics( + EnvSpecDiagnosticsCore.getDecoratorOccurrences("# @required @required", 0) + + EnvSpecDiagnosticsCore.getDecoratorOccurrences("# @docs(https://a.com) @docs(https://b.com)", 1) + ) + assertTrue(duplicates.any { it.message.contains("@required can only be used once") }) + assertFalse(duplicates.any { it.message.contains("@docs") }) + } + + @Test + fun flagsIncompatibleDecoratorPairsInline() { + val diagnostics = EnvSpecDiagnosticsCore.createDecoratorDiagnostics( + EnvSpecDiagnosticsCore.getDecoratorOccurrences("# @required @optional @sensitive @public", 0) + ) + assertTrue(diagnostics.any { it.message.contains("@required and @optional") }) + assertTrue(diagnostics.any { it.message.contains("@sensitive and @public") }) + } + + @Test + fun readsTypeInfoFromCommentBlockAboveItem() { + val document = createDocument(listOf( + "# @required @type=url(prependHttps=true, allowedDomains=\"example.com,api.example.com\")", + "API_URL=example.com", + )) + val typeInfo = EnvSpecDiagnosticsCore.getTypeInfoFromPrecedingComments(document, 1) + assertNotNull(typeInfo) + assertEquals("url", typeInfo!!.name) + assertEquals(mapOf("prependHttps" to "true", "allowedDomains" to "example.com,api.example.com"), typeInfo.options) + } + + @Test + fun validatesEnumValuesAgainstDecoratorList() { + val typeInfo = EnvSpecDiagnosticsCore.TypeInfo("enum", listOf("prod", "dev"), emptyMap()) + assertNull(EnvSpecDiagnosticsCore.validateStaticValue(typeInfo, "prod")) + assertNull(EnvSpecDiagnosticsCore.validateStaticValue(typeInfo, "dev")) + assertNotNull(EnvSpecDiagnosticsCore.validateStaticValue(typeInfo, "staging")) + assertTrue(EnvSpecDiagnosticsCore.validateStaticValue(typeInfo, "staging")!!.contains("prod")) + } +} From b6f695240fcb4dfcd4e93c626993360498a968c5 Mon Sep 17 00:00:00 2001 From: philmillman Date: Mon, 23 Mar 2026 16:23:53 -0400 Subject: [PATCH 2/4] build working and manual and automated tests pass! --- packages/intellij-plugin/CONTEXT.md | 42 ++ packages/intellij-plugin/README.md | 10 +- packages/intellij-plugin/build.gradle.kts | 6 + .../dmno/envspec/EnvSpecColorSettingsPage.kt | 57 +++ .../envspec/EnvSpecCommentEnterHandler.kt | 60 +++ .../envspec/EnvSpecCompletionContributor.kt | 65 ++- .../dev/dmno/envspec/EnvSpecFileType.kt | 7 +- .../kotlin/dev/dmno/envspec/EnvSpecLexer.kt | 427 +++++++++++++++++- .../dmno/envspec/EnvSpecParserDefinition.kt | 4 +- .../dmno/envspec/EnvSpecSyntaxHighlighter.kt | 86 +++- .../dev/dmno/envspec/EnvSpecTokenTypes.kt | 46 +- .../src/main/resources/META-INF/plugin.xml | 2 + .../src/main/resources/icons/env-spec.svg | 3 + .../EnvSpecCompletionContributorTest.kt | 71 +++ .../dev/dmno/envspec/EnvSpecLexerTest.kt | 114 +++++ packages/vscode-plugin/src/completion-core.ts | 84 +++- .../vscode-plugin/src/completion-provider.ts | 5 +- .../vscode-plugin/src/diagnostics-core.ts | 30 +- .../vscode-plugin/src/diagnostics-provider.ts | 11 +- .../test/completion-core.test.ts | 121 ++++- .../test/diagnostics-core.test.ts | 43 ++ .../test/diagnostics-provider.test.ts | 64 +++ 22 files changed, 1301 insertions(+), 57 deletions(-) create mode 100644 packages/intellij-plugin/CONTEXT.md create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecColorSettingsPage.kt create mode 100644 packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommentEnterHandler.kt create mode 100644 packages/intellij-plugin/src/main/resources/icons/env-spec.svg create mode 100644 packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionContributorTest.kt create mode 100644 packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecLexerTest.kt create mode 100644 packages/vscode-plugin/test/diagnostics-provider.test.ts diff --git a/packages/intellij-plugin/CONTEXT.md b/packages/intellij-plugin/CONTEXT.md new file mode 100644 index 00000000..405e6da5 --- /dev/null +++ b/packages/intellij-plugin/CONTEXT.md @@ -0,0 +1,42 @@ +# Compressed context — Env Spec IntelliJ plugin + +## Purpose +JetBrains plugin for [@env-spec](https://varlock.dev/env-spec) on `.env` / `.env.*`: completion, diagnostics, hover, comments, syntax, tests, CI. Parallels the [VS Code extension](../../vscode-plugin). + +## Build / toolchain +- **Gradle** 9.0+ (wrapper in repo); **IntelliJ Platform Gradle Plugin** 2.13.x requires Gradle ≥ 9.0. +- **JDK 17** for `./gradlew` (e.g. `JAVA_HOME=/opt/homebrew/opt/openjdk@17`). Java 25 + older Gradle showed a useless `What went wrong: 25` message. +- **Plugin ZIP**: `./gradlew buildPlugin` (or `./gradlew build` — `build` depends on `buildPlugin` in `build.gradle.kts`). Output: `build/distributions/*.zip`. +- **`./gradlew runIde`**: launches a sandbox IDE with the plugin for manual testing and opens the monorepo root (`../..` from `packages/intellij-plugin`) automatically. + +## UX / editor (recent) +- **Syntax (comments/decorators)**: Comment lines now tokenize decorators with structure (`@name`, `=`, function name, arg keys/values, commas/parens) instead of a single flat comment token. New token families include `DECORATOR`, `DECORATOR_VALUE`, `DECORATOR_ARG_KEY`, and `DECORATOR_ARG_VALUE`. +- **Syntax (assignment values)**: Assignment values now tokenize resolver function names (`if`, `eq`, etc.) and refs (`$ENV`, `${ENV}`) separately from generic value text, improving parity with VS Code highlighting. +- **Incremental lexing stability**: Lexer now re-tokenizes from true line start (then trims to current offset), preventing state drift where highlights looked correct initially but degraded after incremental rehighlight. +- **Color scheme page**: Added descriptors for decorator subparts, value function calls, and value references in **Settings → Editor → Color Scheme → Env Spec**. +- **Icon**: `src/main/resources/icons/env-spec.svg`; `EnvSpecFileType.getIcon()` via `IconLoader`. +- **Enter on `#` lines**: `EnvSpecCommentEnterHandler` (`EnterHandlerDelegate`) inserts newline + indent + `# `; registered in `plugin.xml` as `enterHandlerDelegate`. +- **Completion insertion behavior**: + - Fixed duplicate/append issues on accept (Tab/Enter) by replacing `startOffset..tailOffset` instead of static line ranges. + - Prevents duplicate `@` when accepting decorator suggestions after typing `@`. + - Type-option completions now insert `optionName=` and place caret directly after `=`. + - Added snippet normalization for catalog insert text so VS Code-style placeholders are not inserted literally. + +## Tests (recent additions) +- Added `EnvSpecLexerTest` coverage for: + - Decorator segmentation (`@type=enum(...)`, `@generateTypes(...)`) + - Arg key/value tokenization across multi-arg decorators + - Incomplete vs closed paren forms + - Mid-line incremental lexing start offsets + - Assignment value function/reference tokenization (`if(eq($ENV,...))`) +- Added `EnvSpecCompletionContributorTest` coverage for: + - Completion match contexts immediately after `=` + - Snippet text normalization paths + +## Key paths +| Area | Path | +|------------|------| +| Plugin src | `src/main/kotlin/dev/dmno/envspec/` | +| Plugin XML | `src/main/resources/META-INF/plugin.xml` | +| Build | `build.gradle.kts`, `gradle/wrapper/` | +| Docs | `README.md` (this file is additive only) | diff --git a/packages/intellij-plugin/README.md b/packages/intellij-plugin/README.md index 4e0bfa23..1dd69a3a 100644 --- a/packages/intellij-plugin/README.md +++ b/packages/intellij-plugin/README.md @@ -22,10 +22,16 @@ Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): - **Documentation** on hover for decorators -- **Syntax highlighting** for .env and .env.* files +- **Syntax highlighting** for .env and .env.* files: + - Comment lines (`# …`) vs assignments (`KEY=value`, optional `export`) + - Colors follow **Settings → Editor → Color Scheme → Env Spec** (defaults match line comments, keywords, keys, `=`, and string-like values) + +- **Project view icon** for registered `.env` / `.env.*` files - **Toggle line comment** (`# `) support +- **Enter on a `#` line** inserts a new line with the same indent and `# ` (block comment continuation) + ## Installation ### From JetBrains Marketplace @@ -48,7 +54,7 @@ Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): ## Requirements - IntelliJ IDEA 2024.3+ or WebStorm 2024.3+ -- **Java 17** (for building) — Java 24/25 are not yet supported by Gradle 8.x and the IntelliJ Platform plugin +- **Java 17** (for building) — use a supported JDK for the Gradle version in this repo (see Troubleshooting if you see a cryptic `25` error with Java 25) ## Development diff --git a/packages/intellij-plugin/build.gradle.kts b/packages/intellij-plugin/build.gradle.kts index b50531d5..7ee80f1f 100644 --- a/packages/intellij-plugin/build.gradle.kts +++ b/packages/intellij-plugin/build.gradle.kts @@ -27,6 +27,12 @@ tasks.test { useJUnitPlatform() } +tasks.named("runIde") { + // Open the varlock repository root when the sandbox IDE starts. + val repoRoot = layout.projectDirectory.dir("../..").asFile.absolutePath + args(repoRoot) +} + // Ensure `build` produces the plugin zip (buildPlugin is not included by default) tasks.named("build") { dependsOn(tasks.named("buildPlugin")) diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecColorSettingsPage.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecColorSettingsPage.kt new file mode 100644 index 00000000..2b56c2c5 --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecColorSettingsPage.kt @@ -0,0 +1,57 @@ +package dev.dmno.envspec + +import com.intellij.openapi.editor.colors.TextAttributesKey +import com.intellij.openapi.fileTypes.SyntaxHighlighter +import com.intellij.openapi.options.colors.AttributesDescriptor +import com.intellij.openapi.options.colors.ColorDescriptor +import com.intellij.openapi.options.colors.ColorSettingsPage +import javax.swing.Icon + +/** + * Exposes Env Spec syntax colors in Settings → Editor → Color Scheme → Env Spec. + */ +class EnvSpecColorSettingsPage : ColorSettingsPage { + + override fun getDisplayName(): String = "Env Spec" + + override fun getIcon(): Icon? = EnvSpecFileType.INSTANCE.getIcon() + + override fun getHighlighter(): SyntaxHighlighter = EnvSpecSyntaxHighlighter() + + override fun getDemoText(): String = """ + # Root / header decorators + # @defaultRequired=false + # --- + + # Item block + # @required + # @type=number + MY_URL="test.com" + export PUBLIC_API=https://api.example.com + + """.trimIndent() + + override fun getAdditionalHighlightingTagToDescriptorMap(): Map? = null + + override fun getAttributeDescriptors(): Array = DESCRIPTORS + + override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY + + companion object { + private val DESCRIPTORS = arrayOf( + AttributesDescriptor("Comment", EnvSpecSyntaxHighlighter.LINE_COMMENT), + AttributesDescriptor("Decorator", EnvSpecSyntaxHighlighter.DECORATOR), + AttributesDescriptor("Decorator value", EnvSpecSyntaxHighlighter.DECORATOR_VALUE), + AttributesDescriptor("Decorator function args", EnvSpecSyntaxHighlighter.DECORATOR_ARGS), + AttributesDescriptor("Decorator arg key", EnvSpecSyntaxHighlighter.DECORATOR_ARG_KEY), + AttributesDescriptor("Decorator arg value", EnvSpecSyntaxHighlighter.DECORATOR_ARG_VALUE), + AttributesDescriptor("Export keyword", EnvSpecSyntaxHighlighter.EXPORT_KEYWORD), + AttributesDescriptor("Variable name", EnvSpecSyntaxHighlighter.ENV_KEY), + AttributesDescriptor("Assignment (=)", EnvSpecSyntaxHighlighter.EQUALS), + AttributesDescriptor("Value", EnvSpecSyntaxHighlighter.ENV_VALUE), + AttributesDescriptor("Value function call", EnvSpecSyntaxHighlighter.VALUE_FUNCTION), + AttributesDescriptor("Value item reference", EnvSpecSyntaxHighlighter.VALUE_REFERENCE), + AttributesDescriptor("Other text", EnvSpecSyntaxHighlighter.DEFAULT), + ) + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommentEnterHandler.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommentEnterHandler.kt new file mode 100644 index 00000000..a139b12a --- /dev/null +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommentEnterHandler.kt @@ -0,0 +1,60 @@ +package dev.dmno.envspec + +import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.actionSystem.EditorActionHandler +import com.intellij.openapi.util.Ref +import com.intellij.psi.PsiFile + +/** + * After Enter on a line that starts (after whitespace) with `#`, inserts a new line and `# ` + * with the same leading indentation — same idea as VS Code onEnterRules for line comments. + */ +class EnvSpecCommentEnterHandler : EnterHandlerDelegate { + + override fun preprocessEnter( + file: PsiFile, + editor: Editor, + caretOffsetRef: Ref, + caretAdvance: Ref, + dataContext: DataContext, + originalHandler: EditorActionHandler?, + ): EnterHandlerDelegate.Result { + if (file.language != EnvSpecLanguage) return EnterHandlerDelegate.Result.Continue + + val document = editor.document + val caretOffset = caretOffsetRef.get() + val line = document.getLineNumber(caretOffset) + val lineStart = document.getLineStartOffset(line) + val lineEnd = document.getLineEndOffset(line) + val lineText = document.charsSequence.subSequence(lineStart, lineEnd).toString() + + val m = COMMENT_LINE_PREFIX.matchEntire(lineText) ?: return EnterHandlerDelegate.Result.Continue + val indent = m.groupValues[1] + val hashOffset = lineStart + indent.length + if (caretOffset < hashOffset) return EnterHandlerDelegate.Result.Continue + + val project = file.project + val insert = "\n$indent# " + WriteCommandAction.runWriteCommandAction(project) { + document.insertString(caretOffset, insert) + val newOffset = caretOffset + insert.length + caretOffsetRef.set(newOffset) + caretAdvance.set(0) + editor.caretModel.moveToOffset(newOffset) + } + return EnterHandlerDelegate.Result.Stop + } + + override fun postProcessEnter( + file: PsiFile, + editor: Editor, + dataContext: DataContext, + ): EnterHandlerDelegate.Result = EnterHandlerDelegate.Result.Continue + + companion object { + private val COMMENT_LINE_PREFIX = Regex("""^([ \t]*)(#.*)$""") + } +} diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt index fea86040..9aa8de25 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt @@ -27,6 +27,11 @@ class EnvSpecCompletionContributor : CompletionContributor() { companion object { private val ENV_KEY_PATTERN = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=") + private val KOTLIN_ESCAPED_DOLLAR_RE = Regex("\\$\\{'\\$'\\}") + private val CHOICE_SNIPPET_RE = Regex("""\$\{\d+\|([^}]*)\|\}""") + private val DEFAULT_SNIPPET_RE = Regex("""\$\{\d+:([^}]*)\}""") + private val TABSTOP_SNIPPET_RE = Regex("""\$\{\d+\}""") + private val SIMPLE_TABSTOP_SNIPPET_RE = Regex("""\$\d+""") } private fun doAddCompletions(params: CompletionParameters, result: CompletionResultSet) { @@ -104,6 +109,10 @@ class EnvSpecCompletionContributor : CompletionContributor() { private data class ReplaceRange(val line: Int, val start: Int, val end: Int) + override fun invokeAutoPopup(position: com.intellij.psi.PsiElement, typeChar: Char): Boolean { + return typeChar == '@' || typeChar == '$' || typeChar == '=' || typeChar == ',' + } + private fun matchDecoratorName(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { val match = Regex("(^|\\s)(@[\\w-]*)$").find(commentPrefix) ?: return null val token = match.groupValues[2] @@ -136,13 +145,13 @@ class EnvSpecCompletionContributor : CompletionContributor() { } private fun matchResolverValue(linePrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRange? { - val match = Regex("(?:=\\s*|[(,]\\s*)([A-Za-z][\\w-]*)$").find(linePrefix) ?: return null + val match = Regex("(?:=\\s*|[(,]\\s*)([A-Za-z]?[\\w-]*)$").find(linePrefix) ?: return null val endInLine = offset - lineStart return ReplaceRange(line, endInLine - match.groupValues[1].length, endInLine) } private fun matchDecoratorValue(commentPrefix: String, line: Int, offset: Int, lineStart: Int): ReplaceRangeDecorator? { - val match = Regex("(^|\\s)@([\\w-]+)=([A-Za-z][\\w-]*)$").find(commentPrefix) ?: return null + val match = Regex("(^|\\s)@([\\w-]+)=([A-Za-z]?[\\w-]*)$").find(commentPrefix) ?: return null val decorator = EnvSpecCatalog.DECORATORS_BY_NAME[match.groupValues[2]] val typedValue = match.groupValues[3] val endInLine = offset - lineStart @@ -167,7 +176,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { private data class EnumValueContext(val range: ReplaceRange, val enumValues: List) private fun createDecoratorItem(info: DecoratorInfo, range: ReplaceRange): LookupElementBuilder { - val insertHandler = createReplaceHandler(range, info.insertText) + val insertHandler = createReplaceHandler(info.insertText) var item = LookupElementBuilder.create("@${info.name}") .withInsertHandler(insertHandler) .withTypeText(if (info.scope == "root") "Root decorator" else "Item decorator") @@ -178,36 +187,66 @@ class EnvSpecCompletionContributor : CompletionContributor() { return item } - private fun createReplaceHandler(range: ReplaceRange, insertText: String): InsertHandler { + private fun createReplaceHandler(insertText: String, caretOffsetInInsert: Int? = null): InsertHandler { + val normalizedInsertText = normalizeSnippetInsertText(insertText) return InsertHandler { ctx: InsertionContext, _ -> WriteCommandAction.runWriteCommandAction(ctx.project) { val doc = ctx.document - val start = doc.getLineStartOffset(range.line) + range.start - val end = doc.getLineStartOffset(range.line) + range.end - doc.replaceString(start, end, insertText) + // IntelliJ applies default completion insertion before this handler runs. + // Replace that inserted segment directly to avoid duplicate/append behavior. + val start = ctx.startOffset + val end = ctx.tailOffset + val hasAtPrefix = start > 0 && doc.charsSequence[start - 1] == '@' + val textToInsert = if (hasAtPrefix && normalizedInsertText.startsWith("@")) { + normalizedInsertText.substring(1) + } else { + normalizedInsertText + } + ctx.setAddCompletionChar(false) + doc.replaceString(start, end, textToInsert) + ctx.tailOffset = start + textToInsert.length + val caretOffset = if (caretOffsetInInsert == null) { + start + textToInsert.length + } else { + start + caretOffsetInInsert.coerceIn(0, textToInsert.length) + } + ctx.editor.caretModel.moveToOffset(caretOffset) } } } + private fun normalizeSnippetInsertText(text: String): String { + var out = text + out = KOTLIN_ESCAPED_DOLLAR_RE.replace(out) { "$" } + out = CHOICE_SNIPPET_RE.replace(out) { match -> + match.groupValues[1].split(",").firstOrNull()?.trim().orEmpty() + } + out = DEFAULT_SNIPPET_RE.replace(out) { match -> match.groupValues[1] } + out = TABSTOP_SNIPPET_RE.replace(out, "") + out = SIMPLE_TABSTOP_SNIPPET_RE.replace(out, "") + return out + } + private fun createDataTypeItem(info: DataTypeInfo, range: ReplaceRange): LookupElementBuilder { val insertText = info.insertText ?: info.name return LookupElementBuilder.create(info.name) - .withInsertHandler(createReplaceHandler(range, insertText)) + .withInsertHandler(createReplaceHandler(insertText)) .withTypeText("@type data type") .withTailText(" ${info.summary}", true) } private fun createDataTypeOptionItem(option: DataTypeOptionSnippet, context: ReplaceRangeData): LookupElementBuilder { val range = context.range + val insertText = "${option.name}=" return LookupElementBuilder.create(option.name) - .withInsertHandler(createReplaceHandler(range, option.insertText)) + .withInsertHandler(createReplaceHandler(insertText, insertText.length)) .withTypeText("@type option") .withTailText(" ${option.documentation}", true) } private fun createResolverItem(info: ResolverInfo, range: ReplaceRange): LookupElementBuilder { return LookupElementBuilder.create("${info.name}()") - .withInsertHandler(createReplaceHandler(range, info.insertText)) + .withInsertHandler(createReplaceHandler(info.insertText)) .withTypeText("Resolver function") .withTailText(" ${info.summary}", true) } @@ -220,7 +259,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { } return keys.sorted().map { key -> LookupElementBuilder.create(key) - .withInsertHandler(createReplaceHandler(range, key)) + .withInsertHandler(createReplaceHandler(key)) .withTypeText("Config item reference") .withTailText(" Reference `$key` with `\$$key`.", true) } @@ -229,7 +268,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { private fun createKeywordItems(values: List, range: ReplaceRange): List { return values.map { value -> LookupElementBuilder.create(value) - .withInsertHandler(createReplaceHandler(range, value)) + .withInsertHandler(createReplaceHandler(value)) } } @@ -249,7 +288,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { val range = context.range return context.enumValues.map { value -> LookupElementBuilder.create(value) - .withInsertHandler(createReplaceHandler(range, value)) + .withInsertHandler(createReplaceHandler(value)) .withTypeText("@type=enum value") .withTailText(" Allowed enum value `$value`.", true) } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt index 9a2f71d1..a82b6ff4 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt @@ -1,7 +1,7 @@ package dev.dmno.envspec -import com.intellij.lang.Language import com.intellij.openapi.fileTypes.LanguageFileType +import com.intellij.openapi.util.IconLoader import javax.swing.Icon class EnvSpecFileType private constructor() : LanguageFileType(EnvSpecLanguage) { @@ -9,9 +9,12 @@ class EnvSpecFileType private constructor() : LanguageFileType(EnvSpecLanguage) override fun getName(): String = "EnvSpec" override fun getDescription(): String = "@env-spec (.env) file" override fun getDefaultExtension(): String = "env" - override fun getIcon(): Icon? = null + override fun getIcon(): Icon = ICON companion object { + @JvmField + val ICON: Icon = IconLoader.getIcon("/icons/env-spec.svg", EnvSpecFileType::class.java) + @JvmStatic val INSTANCE = EnvSpecFileType() } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt index aed1a9a8..23e0c5fc 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt @@ -4,6 +4,9 @@ import com.intellij.lexer.LexerBase import com.intellij.psi.TokenType import com.intellij.psi.tree.IElementType +/** + * Line-oriented lexer: comments (#…), assignments (optional export, KEY=value), or unparsed line content. + */ class EnvSpecLexer : LexerBase() { private var buffer: CharSequence = "" @@ -12,11 +15,17 @@ class EnvSpecLexer : LexerBase() { private var tokenEnd = 0 private var tokenType: IElementType? = null + private val queue = ArrayList(8) + private var queuePos = 0 + + private data class QueuedToken(val start: Int, val end: Int, val type: IElementType) + override fun start(buffer: CharSequence, startOffset: Int, endOffset: Int, initialState: Int) { this.buffer = buffer this.bufferEnd = endOffset - this.tokenStart = startOffset this.tokenEnd = startOffset + this.queue.clear() + this.queuePos = 0 advance() } @@ -34,27 +43,417 @@ class EnvSpecLexer : LexerBase() { override fun advance() { tokenStart = tokenEnd + if (pollQueue()) return + + queue.clear() + queuePos = 0 + if (tokenEnd >= bufferEnd) { tokenType = null return } - val c = buffer[tokenEnd] - when (c) { - '\r' -> { - tokenEnd++ - if (tokenEnd < bufferEnd && buffer[tokenEnd] == '\n') tokenEnd++ - tokenType = EnvSpecTokenTypes.NEWLINE + + val ch = buffer[tokenEnd] + if (ch == '\r' || ch == '\n') { + emitNewlineAt(tokenEnd) + return + } + + val lineStart = findLineStart(tokenEnd) + val lineEnd = findLineEnd(lineStart) + enqueueLineTokens(lineStart, lineEnd) + trimQueuedTokensBefore(tokenEnd) + enqueueNewlineAfterLine(lineEnd) + trimQueuedTokensBefore(tokenEnd) + + if (!pollQueue()) { + tokenType = null + } + } + + private fun trimQueuedTokensBefore(offset: Int) { + if (queue.isEmpty()) return + val trimmed = ArrayList(queue.size) + for (token in queue) { + if (token.end <= offset) continue + if (token.start < offset) { + trimmed.add(QueuedToken(offset, token.end, token.type)) + } else { + trimmed.add(token) + } + } + queue.clear() + queue.addAll(trimmed) + queuePos = 0 + } + + private fun findLineStart(from: Int): Int { + var i = from + while (i > 0) { + val prev = buffer[i - 1] + if (prev == '\n' || prev == '\r') break + i-- + } + return i + } + + private fun pollQueue(): Boolean { + if (queuePos >= queue.size) return false + val t = queue[queuePos++] + tokenStart = t.start + tokenEnd = t.end + tokenType = t.type + return true + } + + private fun findLineEnd(from: Int): Int { + var i = from + while (i < bufferEnd && buffer[i] != '\n' && buffer[i] != '\r') i++ + return i + } + + private fun enqueueNewlineAfterLine(lineEnd: Int) { + if (lineEnd >= bufferEnd) return + var end = lineEnd + if (buffer[end] == '\r') { + end++ + if (end < bufferEnd && buffer[end] == '\n') end++ + } else if (buffer[end] == '\n') { + end++ + } + queue.add(QueuedToken(lineEnd, end, EnvSpecTokenTypes.NEWLINE)) + } + + private fun emitNewlineAt(from: Int) { + var end = from + if (end < bufferEnd && buffer[end] == '\r') { + end++ + if (end < bufferEnd && buffer[end] == '\n') end++ + } else if (end < bufferEnd && buffer[end] == '\n') { + end++ + } + tokenStart = from + tokenEnd = end + tokenType = EnvSpecTokenTypes.NEWLINE + } + + private fun enqueueLineTokens(lineStart: Int, lineEnd: Int) { + if (lineStart >= lineEnd) return + + val lineStr = buffer.subSequence(lineStart, lineEnd).toString() + + if (lineStr.isBlank()) { + queue.add(QueuedToken(lineStart, lineEnd, TokenType.WHITE_SPACE)) + return + } + + val comment = COMMENT_LINE.matchEntire(lineStr) + if (comment != null) { + val ws = comment.groupValues[1] + val wsLen = ws.length + if (wsLen > 0) { + queue.add(QueuedToken(lineStart, lineStart + wsLen, TokenType.WHITE_SPACE)) + } + enqueueCommentTokens(lineStart + wsLen, lineEnd) + return + } + + val assign = ASSIGNMENT_LINE.matchEntire(lineStr) + if (assign != null) { + val wsLead = assign.groups[1]!!.range + val export = assign.groups[2] + val key = assign.groups[3]!!.range + val wsMid = assign.groups[4]!!.range + val eq = assign.groups[5]!!.range + val value = assign.groups[6]!!.range + + if (!wsLead.isEmpty()) { + queue.add(QueuedToken(lineStart + wsLead.first, lineStart + wsLead.last + 1, TokenType.WHITE_SPACE)) + } + if (export != null) { + val r = export.range + queue.add(QueuedToken(lineStart + r.first, lineStart + r.last + 1, EnvSpecTokenTypes.EXPORT_KEYWORD)) + } + queue.add(QueuedToken(lineStart + key.first, lineStart + key.last + 1, EnvSpecTokenTypes.ENV_KEY)) + if (!wsMid.isEmpty()) { + queue.add(QueuedToken(lineStart + wsMid.first, lineStart + wsMid.last + 1, TokenType.WHITE_SPACE)) + } + queue.add(QueuedToken(lineStart + eq.first, lineStart + eq.last + 1, EnvSpecTokenTypes.EQUALS)) + if (!value.isEmpty()) { + val valueStart = lineStart + value.first + val valueText = lineStr.substring(value.first, value.last + 1) + enqueueAssignmentValueTokens(valueStart, valueText) + } + return + } + + queue.add(QueuedToken(lineStart, lineEnd, EnvSpecTokenTypes.LINE_CONTENT)) + } + + private fun enqueueCommentTokens(start: Int, end: Int) { + if (start >= end) return + val text = buffer.subSequence(start, end).toString() + var i = 0 + var plainStart = 0 + + while (i < text.length) { + val atIndex = text.indexOf('@', i) + if (atIndex < 0) break + + if (atIndex + 1 >= text.length || !isDecoratorNameStart(text[atIndex + 1])) { + i = atIndex + 1 + continue + } + + if (atIndex > plainStart) { + queue.add(QueuedToken(start + plainStart, start + atIndex, EnvSpecTokenTypes.LINE_COMMENT)) + } + + var nameEnd = atIndex + 2 + while (nameEnd < text.length && isDecoratorNamePart(text[nameEnd])) nameEnd++ + queue.add(QueuedToken(start + atIndex, start + nameEnd, EnvSpecTokenTypes.DECORATOR)) + + i = nameEnd + plainStart = i + + if (i < text.length && text[i] == '=') { + queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS)) + i++ + val valueStart = i + if (i < text.length && isDecoratorValueNameStart(text[i])) { + var valueEnd = i + 1 + while (valueEnd < text.length && isDecoratorValueNamePart(text[valueEnd])) valueEnd++ + queue.add(QueuedToken(start + i, start + valueEnd, EnvSpecTokenTypes.DECORATOR_VALUE)) + i = valueEnd + if (i < text.length && text[i] == '(') { + queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS)) + val close = findClosingParen(text, i) + if (close > i + 1) { + enqueueDecoratorArgsTokens(start + i + 1, text.substring(i + 1, close)) + } + if (close < text.length) { + queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.EQUALS)) + i = close + 1 + } else { + i = text.length + } + } + } else { + var valueEnd = i + while (valueEnd < text.length && !text[valueEnd].isWhitespace() && text[valueEnd] != '#') valueEnd++ + if (valueEnd > valueStart) { + queue.add(QueuedToken(start + valueStart, start + valueEnd, EnvSpecTokenTypes.DECORATOR_VALUE)) + } + i = valueEnd + } + plainStart = i + continue + } + + if (i < text.length && text[i] == '(') { + queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS)) + val close = findClosingParen(text, i) + if (close > i + 1) { + enqueueDecoratorArgsTokens(start + i + 1, text.substring(i + 1, close)) + } + if (close < text.length) { + queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.EQUALS)) + i = close + 1 + } else { + i = text.length + } + plainStart = i + continue + } + + plainStart = i + } + + if (plainStart < text.length) { + queue.add(QueuedToken(start + plainStart, end, EnvSpecTokenTypes.LINE_COMMENT)) + } + } + + private fun enqueueDecoratorArgsTokens(argsStartOffset: Int, argsText: String) { + if (argsText.isEmpty()) return + + var segmentStart = 0 + var i = 0 + var depth = 0 + var quote: Char? = null + + while (i < argsText.length) { + val ch = argsText[i] + when { + quote != null -> if (ch == quote) quote = null + ch == '\'' || ch == '"' || ch == '`' -> quote = ch + ch == '(' -> depth++ + ch == ')' -> if (depth > 0) depth-- + ch == ',' && depth == 0 -> { + enqueueDecoratorArgSegment(argsStartOffset + segmentStart, argsText.substring(segmentStart, i)) + queue.add(QueuedToken(argsStartOffset + i, argsStartOffset + i + 1, EnvSpecTokenTypes.EQUALS)) + segmentStart = i + 1 + } + } + i++ + } + + if (segmentStart < argsText.length) { + enqueueDecoratorArgSegment(argsStartOffset + segmentStart, argsText.substring(segmentStart)) + } + } + + private fun enqueueDecoratorArgSegment(segmentStartOffset: Int, segmentText: String) { + if (segmentText.isEmpty()) return + + val leadingWs = segmentText.takeWhile { it.isWhitespace() }.length + val trailingWs = segmentText.takeLastWhile { it.isWhitespace() }.length + val coreStart = leadingWs + val coreEnd = segmentText.length - trailingWs + + if (leadingWs > 0) { + queue.add(QueuedToken(segmentStartOffset, segmentStartOffset + leadingWs, TokenType.WHITE_SPACE)) + } + if (coreStart >= coreEnd) { + return + } + + val core = segmentText.substring(coreStart, coreEnd) + val coreAbsStart = segmentStartOffset + coreStart + val eqIdx = findTopLevelEquals(core) + val keyCandidateEnd = if (eqIdx > 0) core.substring(0, eqIdx).trimEnd().length else -1 + val hasKeyValueShape = keyCandidateEnd > 0 && + core.substring(0, keyCandidateEnd).matches(Regex("""[A-Za-z][A-Za-z0-9_-]*""")) + + if (!hasKeyValueShape) { + queue.add(QueuedToken(coreAbsStart, coreAbsStart + core.length, EnvSpecTokenTypes.DECORATOR_ARG_VALUE)) + } else { + queue.add(QueuedToken(coreAbsStart, coreAbsStart + keyCandidateEnd, EnvSpecTokenTypes.DECORATOR_ARG_KEY)) + var cursor = keyCandidateEnd + while (cursor < eqIdx) { + queue.add(QueuedToken(coreAbsStart + cursor, coreAbsStart + cursor + 1, TokenType.WHITE_SPACE)) + cursor++ } - '\n' -> { - tokenEnd++ - tokenType = EnvSpecTokenTypes.NEWLINE + queue.add(QueuedToken(coreAbsStart + eqIdx, coreAbsStart + eqIdx + 1, EnvSpecTokenTypes.EQUALS)) + if (eqIdx + 1 < core.length) { + queue.add(QueuedToken(coreAbsStart + eqIdx + 1, coreAbsStart + core.length, EnvSpecTokenTypes.DECORATOR_ARG_VALUE)) } - else -> { - while (tokenEnd < bufferEnd && buffer[tokenEnd] != '\r' && buffer[tokenEnd] != '\n') { - tokenEnd++ + } + + if (trailingWs > 0) { + queue.add(QueuedToken(segmentStartOffset + coreEnd, segmentStartOffset + segmentText.length, TokenType.WHITE_SPACE)) + } + } + + private fun findTopLevelEquals(text: String): Int { + var depth = 0 + var quote: Char? = null + for (i in text.indices) { + val ch = text[i] + when { + quote != null -> if (ch == quote) quote = null + ch == '\'' || ch == '"' || ch == '`' -> quote = ch + ch == '(' -> depth++ + ch == ')' -> if (depth > 0) depth-- + ch == '=' && depth == 0 -> return i + } + } + return -1 + } + + private fun enqueueAssignmentValueTokens(valueStartOffset: Int, valueText: String) { + var i = 0 + var plainStart = 0 + var quote: Char? = null + + while (i < valueText.length) { + val ch = valueText[i] + if (quote != null) { + if (ch == quote) quote = null + i++ + continue + } + if (ch == '"' || ch == '\'' || ch == '`') { + quote = ch + i++ + continue + } + + if (ch == '$') { + val refEnd = findReferenceEnd(valueText, i) + if (refEnd > i + 1) { + if (i > plainStart) { + queue.add(QueuedToken(valueStartOffset + plainStart, valueStartOffset + i, EnvSpecTokenTypes.ENV_VALUE)) + } + queue.add(QueuedToken(valueStartOffset + i, valueStartOffset + refEnd, EnvSpecTokenTypes.VALUE_REFERENCE)) + i = refEnd + plainStart = i + continue + } + } + + if (isValueFunctionNameStart(ch)) { + val nameStart = i + var nameEnd = i + 1 + while (nameEnd < valueText.length && isDecoratorValueNamePart(valueText[nameEnd])) nameEnd++ + if (nameEnd < valueText.length && valueText[nameEnd] == '(') { + if (nameStart > plainStart) { + queue.add(QueuedToken(valueStartOffset + plainStart, valueStartOffset + nameStart, EnvSpecTokenTypes.ENV_VALUE)) + } + queue.add(QueuedToken(valueStartOffset + nameStart, valueStartOffset + nameEnd, EnvSpecTokenTypes.VALUE_FUNCTION)) + i = nameEnd + plainStart = i + continue + } + } + i++ + } + + if (plainStart < valueText.length) { + queue.add(QueuedToken(valueStartOffset + plainStart, valueStartOffset + valueText.length, EnvSpecTokenTypes.ENV_VALUE)) + } + } + + private fun findReferenceEnd(text: String, dollarIndex: Int): Int { + if (dollarIndex + 1 >= text.length) return dollarIndex + 1 + if (text[dollarIndex + 1] == '{') { + var i = dollarIndex + 2 + while (i < text.length && text[i] != '}') i++ + return if (i < text.length) i + 1 else dollarIndex + 1 + } + var i = dollarIndex + 1 + if (!isRefNameStart(text[i])) return dollarIndex + 1 + i++ + while (i < text.length && isRefNamePart(text[i])) i++ + return i + } + + private fun findClosingParen(text: String, openIndex: Int): Int { + var depth = 0 + var i = openIndex + while (i < text.length) { + when (text[i]) { + '(' -> depth++ + ')' -> { + depth-- + if (depth == 0) return i } - tokenType = EnvSpecTokenTypes.LINE_CONTENT } + i++ } + return text.length + } + + private fun isDecoratorNameStart(ch: Char): Boolean = ch.isLetter() + private fun isDecoratorNamePart(ch: Char): Boolean = ch.isLetterOrDigit() || ch == '_' || ch == '-' + private fun isDecoratorValueNameStart(ch: Char): Boolean = ch.isLetter() + private fun isDecoratorValueNamePart(ch: Char): Boolean = ch.isLetterOrDigit() || ch == '_' || ch == '-' + private fun isValueFunctionNameStart(ch: Char): Boolean = ch.isLetter() + private fun isRefNameStart(ch: Char): Boolean = ch.isLetter() || ch == '_' + private fun isRefNamePart(ch: Char): Boolean = ch.isLetterOrDigit() || ch == '_' + + companion object { + private val COMMENT_LINE = Regex("""^([ \t]*)(#.*)$""") + private val ASSIGNMENT_LINE = Regex("""^([ \t]*)(export[ \t]+)?([A-Za-z_][\w.-]*)([ \t]*)(=)(.*)$""") } } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt index e0153753..691d8fb3 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt @@ -19,7 +19,9 @@ class EnvSpecParserDefinition : ParserDefinition { override fun getFileNodeType(): IFileElementType = FILE - override fun getCommentTokens(): TokenSet = TokenSet.EMPTY + override fun getCommentTokens(): TokenSet = TokenSet.create(EnvSpecTokenTypes.LINE_COMMENT) + + override fun getWhitespaceTokens(): TokenSet = TokenSet.create(TokenType.WHITE_SPACE) override fun getStringLiteralElements(): TokenSet = TokenSet.EMPTY diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt index 67c1255c..b2022a4b 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt @@ -2,10 +2,10 @@ package dev.dmno.envspec import com.intellij.lexer.Lexer import com.intellij.openapi.editor.colors.TextAttributesKey +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors as Default import com.intellij.openapi.fileTypes.SyntaxHighlighterBase -import com.intellij.psi.tree.IElementType import com.intellij.psi.TokenType -import com.intellij.openapi.editor.DefaultLanguageHighlighterColors as Default +import com.intellij.psi.tree.IElementType class EnvSpecSyntaxHighlighter : SyntaxHighlighterBase() { @@ -13,15 +13,93 @@ class EnvSpecSyntaxHighlighter : SyntaxHighlighterBase() { override fun getTokenHighlights(tokenType: IElementType): Array { return when (tokenType) { - EnvSpecTokenTypes.LINE_CONTENT -> LINE_KEYS + TokenType.WHITE_SPACE -> EMPTY_KEYS EnvSpecTokenTypes.NEWLINE -> EMPTY_KEYS + EnvSpecTokenTypes.LINE_COMMENT -> LINE_COMMENT_KEYS + EnvSpecTokenTypes.DECORATOR -> DECORATOR_KEYS + EnvSpecTokenTypes.DECORATOR_VALUE -> DECORATOR_VALUE_KEYS + EnvSpecTokenTypes.DECORATOR_ARGS -> DECORATOR_ARGS_KEYS + EnvSpecTokenTypes.DECORATOR_ARG_KEY -> DECORATOR_ARG_KEY_KEYS + EnvSpecTokenTypes.DECORATOR_ARG_VALUE -> DECORATOR_ARG_VALUE_KEYS + EnvSpecTokenTypes.EXPORT_KEYWORD -> KEYWORD_KEYS + EnvSpecTokenTypes.ENV_KEY -> INSTANCE_FIELD_KEYS + EnvSpecTokenTypes.EQUALS -> OPERATION_SIGN_KEYS + EnvSpecTokenTypes.ENV_VALUE -> STRING_KEYS + EnvSpecTokenTypes.VALUE_FUNCTION -> FUNCTION_CALL_KEYS + EnvSpecTokenTypes.VALUE_REFERENCE -> VALUE_REFERENCE_KEYS + EnvSpecTokenTypes.LINE_CONTENT -> DEFAULT_KEYS TokenType.BAD_CHARACTER -> BAD_CHARACTER_KEYS else -> EMPTY_KEYS } } companion object { - private val LINE_KEYS = arrayOf(Default.TEMPLATE_LANGUAGE_COLOR) + val LINE_COMMENT: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.LINE_COMMENT", + Default.LINE_COMMENT, + ) + val EXPORT_KEYWORD: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.EXPORT", + Default.KEYWORD, + ) + val DECORATOR: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DECORATOR", + Default.METADATA, + ) + val DECORATOR_VALUE: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DECORATOR_VALUE", + Default.STRING, + ) + val DECORATOR_ARGS: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DECORATOR_ARGS", + Default.IDENTIFIER, + ) + val DECORATOR_ARG_KEY: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DECORATOR_ARG_KEY", + Default.PARAMETER, + ) + val DECORATOR_ARG_VALUE: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DECORATOR_ARG_VALUE", + Default.STRING, + ) + val ENV_KEY: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.KEY", + Default.INSTANCE_FIELD, + ) + val EQUALS: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.EQUALS", + Default.OPERATION_SIGN, + ) + val ENV_VALUE: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.VALUE", + Default.STRING, + ) + val VALUE_FUNCTION: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.VALUE_FUNCTION", + Default.FUNCTION_CALL, + ) + val VALUE_REFERENCE: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.VALUE_REFERENCE", + Default.GLOBAL_VARIABLE, + ) + val DEFAULT: TextAttributesKey = TextAttributesKey.createTextAttributesKey( + "ENV_SPEC.DEFAULT", + Default.IDENTIFIER, + ) + + private val LINE_COMMENT_KEYS = arrayOf(LINE_COMMENT) + private val DECORATOR_KEYS = arrayOf(DECORATOR) + private val DECORATOR_VALUE_KEYS = arrayOf(DECORATOR_VALUE) + private val DECORATOR_ARGS_KEYS = arrayOf(DECORATOR_ARGS) + private val DECORATOR_ARG_KEY_KEYS = arrayOf(DECORATOR_ARG_KEY) + private val DECORATOR_ARG_VALUE_KEYS = arrayOf(DECORATOR_ARG_VALUE) + private val KEYWORD_KEYS = arrayOf(EXPORT_KEYWORD) + private val INSTANCE_FIELD_KEYS = arrayOf(ENV_KEY) + private val OPERATION_SIGN_KEYS = arrayOf(EQUALS) + private val STRING_KEYS = arrayOf(ENV_VALUE) + private val FUNCTION_CALL_KEYS = arrayOf(VALUE_FUNCTION) + private val VALUE_REFERENCE_KEYS = arrayOf(VALUE_REFERENCE) + private val DEFAULT_KEYS = arrayOf(DEFAULT) private val BAD_CHARACTER_KEYS = arrayOf(Default.INVALID_STRING_ESCAPE) private val EMPTY_KEYS = emptyArray() } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt index 39ee666a..8ed13475 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt @@ -1,12 +1,56 @@ package dev.dmno.envspec -import com.intellij.psi.TokenType import com.intellij.psi.tree.IElementType object EnvSpecTokenTypes { @JvmField val NEWLINE: IElementType = object : IElementType("ENV_SPEC_NEWLINE", EnvSpecLanguage) {} + /** Fallback for lines that are not a comment or KEY=value assignment. */ @JvmField val LINE_CONTENT: IElementType = object : IElementType("ENV_SPEC_LINE_CONTENT", EnvSpecLanguage) {} + + /** From # through end of line (comment lines only). */ + @JvmField + val LINE_COMMENT: IElementType = object : IElementType("ENV_SPEC_LINE_COMMENT", EnvSpecLanguage) {} + + /** @decorator segments inside comment lines. */ + @JvmField + val DECORATOR: IElementType = object : IElementType("ENV_SPEC_DECORATOR", EnvSpecLanguage) {} + + /** Decorator value text after @name=... or fn name in @name(...). */ + @JvmField + val DECORATOR_VALUE: IElementType = object : IElementType("ENV_SPEC_DECORATOR_VALUE", EnvSpecLanguage) {} + + /** Function arguments inside decorator call parentheses. */ + @JvmField + val DECORATOR_ARGS: IElementType = object : IElementType("ENV_SPEC_DECORATOR_ARGS", EnvSpecLanguage) {} + + /** Argument key inside decorator function args, e.g. startsWith in startsWith=foo. */ + @JvmField + val DECORATOR_ARG_KEY: IElementType = object : IElementType("ENV_SPEC_DECORATOR_ARG_KEY", EnvSpecLanguage) {} + + /** Argument value inside decorator function args. */ + @JvmField + val DECORATOR_ARG_VALUE: IElementType = object : IElementType("ENV_SPEC_DECORATOR_ARG_VALUE", EnvSpecLanguage) {} + + @JvmField + val EXPORT_KEYWORD: IElementType = object : IElementType("ENV_SPEC_EXPORT", EnvSpecLanguage) {} + + @JvmField + val ENV_KEY: IElementType = object : IElementType("ENV_SPEC_KEY", EnvSpecLanguage) {} + + @JvmField + val EQUALS: IElementType = object : IElementType("ENV_SPEC_EQUALS", EnvSpecLanguage) {} + + @JvmField + val ENV_VALUE: IElementType = object : IElementType("ENV_SPEC_VALUE", EnvSpecLanguage) {} + + /** Resolver/function name used inside assignment values (e.g. if, eq). */ + @JvmField + val VALUE_FUNCTION: IElementType = object : IElementType("ENV_SPEC_VALUE_FUNCTION", EnvSpecLanguage) {} + + /** Item reference used inside assignment values (e.g. $ENV, ${ENV}). */ + @JvmField + val VALUE_REFERENCE: IElementType = object : IElementType("ENV_SPEC_VALUE_REFERENCE", EnvSpecLanguage) {} } diff --git a/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml b/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml index ae08c7bd..7f72d501 100644 --- a/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml +++ b/packages/intellij-plugin/src/main/resources/META-INF/plugin.xml @@ -15,7 +15,9 @@ + + diff --git a/packages/intellij-plugin/src/main/resources/icons/env-spec.svg b/packages/intellij-plugin/src/main/resources/icons/env-spec.svg new file mode 100644 index 00000000..76f3be6d --- /dev/null +++ b/packages/intellij-plugin/src/main/resources/icons/env-spec.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionContributorTest.kt b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionContributorTest.kt new file mode 100644 index 00000000..903d6b63 --- /dev/null +++ b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionContributorTest.kt @@ -0,0 +1,71 @@ +package dev.dmno.envspec + +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class EnvSpecCompletionContributorTest { + + private fun invokePrivateMatch( + contributor: EnvSpecCompletionContributor, + methodName: String, + text: String, + ): Any? { + val method = EnvSpecCompletionContributor::class.java.getDeclaredMethod( + methodName, + String::class.java, + Int::class.javaPrimitiveType, + Int::class.javaPrimitiveType, + Int::class.javaPrimitiveType, + ) + method.isAccessible = true + return method.invoke(contributor, text, 0, text.length, 0) + } + + @Test + fun matchesDecoratorValueEvenWhenNothingTypedAfterEquals() { + val contributor = EnvSpecCompletionContributor() + val match = invokePrivateMatch(contributor, "matchDecoratorValue", "@required=") + assertNotNull(match) + } + + @Test + fun matchesResolverValueEvenWhenNothingTypedAfterEquals() { + val contributor = EnvSpecCompletionContributor() + val match = invokePrivateMatch(contributor, "matchResolverValue", "API_URL=") + assertNotNull(match) + } + + @Test + fun normalizesSnippetInsertTextForIntellij() { + val contributor = EnvSpecCompletionContributor() + val method = EnvSpecCompletionContributor::class.java.getDeclaredMethod( + "normalizeSnippetInsertText", + String::class.java, + ) + method.isAccessible = true + + val normalized = method.invoke(contributor, """matches=${'$'}{1:"^[A-Z0-9_]+${'$'}"}""") as String + assertEquals("""matches="^[A-Z0-9_]+$"""", normalized) + + val choiceNormalized = method.invoke( + contributor, + """@defaultRequired=${'$'}{1|infer,true,false|}""", + ) as String + assertEquals("@defaultRequired=infer", choiceNormalized) + + val tabstopNormalized = method.invoke( + contributor, + """value=${'$'}{1}""", + ) as String + assertEquals("value=", tabstopNormalized) + + val kotlinEscaped = method.invoke( + contributor, + """matches=\${'$'}{1:"^[A-Z0-9_]+\${'$'}"}""", + ) as String + assertTrue(kotlinEscaped.startsWith("matches=")) + assertTrue(!kotlinEscaped.contains("\${")) + } +} diff --git a/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecLexerTest.kt b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecLexerTest.kt new file mode 100644 index 00000000..ca617f1d --- /dev/null +++ b/packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecLexerTest.kt @@ -0,0 +1,114 @@ +package dev.dmno.envspec + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +class EnvSpecLexerTest { + + private data class LexedToken(val type: String, val text: String) + + private fun lex(input: String): List { + return lexFromOffset(input, 0) + } + + private fun lexFromOffset(input: String, startOffset: Int): List { + val lexer = EnvSpecLexer() + lexer.start(input, startOffset, input.length, 0) + + val out = mutableListOf() + while (true) { + val tokenType = lexer.tokenType ?: break + out += LexedToken( + type = tokenType.toString(), + text = input.substring(lexer.tokenStart, lexer.tokenEnd), + ) + lexer.advance() + } + return out + } + + @Test + fun tokenizesDecoratorsInsideCommentLines() { + val tokens = lex("# @required @type=enum(prod, dev)") + + val decoratorTexts = tokens + .filter { it.type == EnvSpecTokenTypes.DECORATOR.toString() } + .map { it.text } + assertEquals(listOf("@required", "@type"), decoratorTexts) + + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.LINE_COMMENT.toString() && it.text.contains("#") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_VALUE.toString() && it.text == "enum" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "prod" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "dev" }) + } + + @Test + fun tokenizesDecoratorFunctionArgs() { + val tokens = lex("# @generateTypes(lang='ts', path='env.d.ts')") + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR.toString() && it.text == "@generateTypes" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "lang" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "'ts'" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "path" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "'env.d.ts'" }) + } + + @Test + fun tokenizesTypeOptionKeyValueInsideDecoratorArgs() { + val tokens = lex("# @type=string(startsWith=sk_, matches=test, maxLength=29, )") + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "startsWith" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "sk_" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "matches" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "test" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "maxLength" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "29" }) + } + + @Test + fun tokenizesSubsequentArgsConsistentlyWithoutClosingParen() { + val tokens = lex("# @type=string(startsWith=sk____, matches=test, maxLength=29, minLength=jifdpajaf") + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "startsWith" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "sk____" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "matches" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "test" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "maxLength" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "29" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "minLength" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "jifdpajaf" }) + } + + @Test + fun tokenizesSubsequentArgsConsistentlyWithClosingParen() { + val tokens = lex("# @type=string(startsWith=sk____, matches=test, maxLength=29, minLength=jifdpajaf)") + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "startsWith" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "sk____" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "matches" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "test" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "maxLength" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "29" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text == "minLength" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text == "jifdpajaf" }) + } + + @Test + fun keepsDecoratorArgKeyValueHighlightingWhenLexingStartsMidLine() { + val input = "# @type=string(startsWith=sk____, matches=test, maxLength=29, minLength=jifdpajaf)" + val midOffset = input.indexOf("matches") + val tokens = lexFromOffset(input, midOffset) + + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text.contains("matches") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text.contains("test") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text.contains("maxLength") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text.contains("29") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_KEY.toString() && it.text.contains("minLength") }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.DECORATOR_ARG_VALUE.toString() && it.text.contains("jifdpajaf") }) + } + + @Test + fun tokenizesAssignmentValueFunctionsAndReferences() { + val tokens = lex("""URL=if(eq(${'$'}ENV, "prod"), "https://api.example.com", "https://staging-api.example.com")""") + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.VALUE_FUNCTION.toString() && it.text == "if" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.VALUE_FUNCTION.toString() && it.text == "eq" }) + assertTrue(tokens.any { it.type == EnvSpecTokenTypes.VALUE_REFERENCE.toString() && it.text == "\$ENV" }) + } +} diff --git a/packages/vscode-plugin/src/completion-core.ts b/packages/vscode-plugin/src/completion-core.ts index c377cd49..cb540f69 100644 --- a/packages/vscode-plugin/src/completion-core.ts +++ b/packages/vscode-plugin/src/completion-core.ts @@ -5,7 +5,8 @@ type LineDocument = { lineAt(line: number): { text: string }; }; -const HEADER_SEPARATOR_PATTERN = /^\s*#\s*---+\s*$/; +const CONFIG_ITEM_PATTERN = /^\s*(?:export\s+)?[A-Za-z_][A-Za-z0-9_.-]*\s*=/; +const DIVIDER_PATTERN = /^\s*#\s*(?:---+|===+)(?:\s|$)/; const DECORATOR_PATTERN = /@([A-Za-z][\w-]*)/g; const INCOMPATIBLE_DECORATORS = new Map>([ ['required', new Set(['optional'])], @@ -14,6 +15,41 @@ const INCOMPATIBLE_DECORATORS = new Map>([ ['public', new Set(['sensitive'])], ]); +function stripInlineComment(value: string) { + let quote: '"' | '\'' | '' = ''; + + for (let i = 0; i < value.length; i += 1) { + const char = value[i]; + if (quote) { + if (char === quote) quote = ''; + continue; + } + + if (char === '"' || char === '\'') { + quote = char; + continue; + } + + if (char === '#' && (i === 0 || /\s/.test(value[i - 1]))) { + return value.slice(0, i).trimEnd(); + } + } + + return value.trim(); +} + +export function getDecoratorCommentPrefix(lineText: string) { + const match = lineText.match(/^\s*#\s*(@.*)$/); + if (!match) return undefined; + + const commentText = match[1]; + + if (/^@[A-Za-z]+:/.test(commentText)) return undefined; + if (/^@[A-Za-z]+\s+[^@#]/.test(commentText)) return undefined; + + return stripInlineComment(commentText); +} + function splitArgs(input: string) { const parts: Array = []; let current = ''; @@ -61,8 +97,16 @@ function splitArgs(input: string) { } export function isInHeader(document: LineDocument, lineNumber: number) { - for (let line = lineNumber; line >= 0; line -= 1) { - if (HEADER_SEPARATOR_PATTERN.test(document.lineAt(line).text)) return false; + for (let line = lineNumber + 1; line < document.lineCount; line += 1) { + const text = document.lineAt(line).text.trim(); + if (!text) break; + if (DIVIDER_PATTERN.test(text)) break; + if (CONFIG_ITEM_PATTERN.test(text)) return false; + if (!text.startsWith('#')) break; + } + + for (let line = 0; line < lineNumber; line += 1) { + if (CONFIG_ITEM_PATTERN.test(document.lineAt(line).text)) return false; } return true; } @@ -74,11 +118,30 @@ export function getExistingDecoratorNames( ) { const names = new Set(); - for (let line = lineNumber - 1; line >= 0; line -= 1) { - const text = document.lineAt(line).text.trim(); - if (!text.startsWith('#')) break; - for (const match of text.matchAll(DECORATOR_PATTERN)) { - names.add(match[1]); + if (isInHeader(document, lineNumber)) { + for (let line = 0; line < lineNumber; line += 1) { + const text = document.lineAt(line).text.trim(); + if (CONFIG_ITEM_PATTERN.test(text)) break; + if (!text.startsWith('#')) continue; + + const decoratorCommentPrefix = getDecoratorCommentPrefix(text); + if (!decoratorCommentPrefix) continue; + + for (const match of decoratorCommentPrefix.matchAll(DECORATOR_PATTERN)) { + names.add(match[1]); + } + } + } else { + for (let line = lineNumber - 1; line >= 0; line -= 1) { + const text = document.lineAt(line).text.trim(); + if (!text.startsWith('#')) break; + + const decoratorCommentPrefix = getDecoratorCommentPrefix(text); + if (!decoratorCommentPrefix) continue; + + for (const match of decoratorCommentPrefix.matchAll(DECORATOR_PATTERN)) { + names.add(match[1]); + } } } @@ -112,7 +175,10 @@ export function getEnumValuesFromPrecedingComments(document: LineDocument, lineN const text = document.lineAt(line).text.trim(); if (!text.startsWith('#')) break; - const match = text.match(/@type=enum\((.*)\)/); + const decoratorCommentPrefix = getDecoratorCommentPrefix(text); + if (!decoratorCommentPrefix) continue; + + const match = decoratorCommentPrefix.match(/@type=enum\((.*)\)/); if (match) return splitEnumArgs(match[1]); } diff --git a/packages/vscode-plugin/src/completion-provider.ts b/packages/vscode-plugin/src/completion-provider.ts index 6dc0f0ba..2d18c228 100644 --- a/packages/vscode-plugin/src/completion-provider.ts +++ b/packages/vscode-plugin/src/completion-provider.ts @@ -13,6 +13,7 @@ import { import { filterAvailableDecorators, + getDecoratorCommentPrefix, getEnumValuesFromPrecedingComments, getExistingDecoratorNames, getTypeOptionDataType, @@ -264,7 +265,7 @@ export function addCompletionProvider(context: ExtensionContext) { provideCompletionItems(document, position) { const linePrefix = document.lineAt(position.line).text.slice(0, position.character); const commentStart = linePrefix.indexOf('#'); - const commentPrefix = commentStart >= 0 ? linePrefix.slice(commentStart + 1) : ''; + const commentPrefix = commentStart >= 0 ? getDecoratorCommentPrefix(linePrefix) : undefined; const referenceContext = matchReference(linePrefix, position); if (referenceContext) { @@ -276,7 +277,7 @@ export function addCompletionProvider(context: ExtensionContext) { return createEnumValueItems(enumValueContext); } - if (commentStart >= 0) { + if (commentPrefix) { const existingDecoratorNames = getExistingDecoratorNames(document, position.line, commentPrefix); const typeOptionContext = matchTypeOption(commentPrefix, position); diff --git a/packages/vscode-plugin/src/diagnostics-core.ts b/packages/vscode-plugin/src/diagnostics-core.ts index ac39f4a8..1b5814cd 100644 --- a/packages/vscode-plugin/src/diagnostics-core.ts +++ b/packages/vscode-plugin/src/diagnostics-core.ts @@ -21,6 +21,7 @@ export type DecoratorOccurrence = { line: number; start: number; end: number; + isFunctionCall: boolean; }; export type CoreDiagnostic = { @@ -156,11 +157,26 @@ export function getPrecedingCommentBlock(document: LineDocument, lineNumber: num return lines; } +function getDecoratorCommentText(lineText: string) { + const match = lineText.match(/^\s*#\s*(@.*)$/); + if (!match) return undefined; + + const commentText = match[1]; + + if (/^@[A-Za-z]+:/.test(commentText)) return undefined; + if (/^@[A-Za-z]+\s+[^@#]/.test(commentText)) return undefined; + + return stripInlineComment(commentText); +} + export function getTypeInfoFromPrecedingComments(document: LineDocument, lineNumber: number) { const commentBlock = getPrecedingCommentBlock(document, lineNumber); for (let index = commentBlock.length - 1; index >= 0; index -= 1) { - const match = commentBlock[index].match(/@type=([A-Za-z][\w-]*)(?:\((.*)\))?/); + const decoratorComment = getDecoratorCommentText(commentBlock[index]); + if (!decoratorComment) continue; + + const match = decoratorComment.match(/@type=([A-Za-z][\w-]*)(?:\((.*)\))?/); if (!match) continue; if (match[1] === 'enum') { @@ -183,15 +199,20 @@ export function getTypeInfoFromPrecedingComments(document: LineDocument, lineNum export function getDecoratorOccurrences(lineText: string, lineNumber: number) { const occurrences: Array = []; + const decoratorComment = getDecoratorCommentText(lineText); + if (!decoratorComment) return occurrences; + const decoratorCommentStart = lineText.indexOf(decoratorComment); - for (const match of lineText.matchAll(DECORATOR_PATTERN)) { + for (const match of decoratorComment.matchAll(DECORATOR_PATTERN)) { const name = match[1]; - const start = match.index ?? 0; + const start = decoratorCommentStart + (match.index ?? 0); + const suffix = match[0].slice(name.length + 1); occurrences.push({ name, line: lineNumber, start, end: start + match[0].length, + isFunctionCall: suffix.startsWith('('), }); } @@ -208,7 +229,8 @@ export function createDecoratorDiagnostics(occurrences: Array= 1) { + const isRepeatableFunction = decorator?.isFunction ?? occurrence.isFunctionCall; + if (!isRepeatableFunction && count >= 1) { diagnostics.push({ line: occurrence.line, start: occurrence.start, diff --git a/packages/vscode-plugin/src/diagnostics-provider.ts b/packages/vscode-plugin/src/diagnostics-provider.ts index b727eb5d..7fbb5b83 100644 --- a/packages/vscode-plugin/src/diagnostics-provider.ts +++ b/packages/vscode-plugin/src/diagnostics-provider.ts @@ -24,7 +24,7 @@ import { } from './diagnostics-core'; import { createLineDocument } from './document-lines'; -const ENV_ASSIGNMENT_PATTERN = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/; +const ENV_ASSIGNMENT_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_.-]*)\s*=\s*(.*?)\s*$/; function toRange(diagnostic: CoreDiagnostic) { return new Range( @@ -33,7 +33,9 @@ function toRange(diagnostic: CoreDiagnostic) { ); } -function validateDocument(document: TextDocument) { +type DiagnosticsDocument = Pick; + +export function validateDocument(document: DiagnosticsDocument) { if (document.languageId !== LANG_ID) return []; const diagnostics: Array = []; @@ -41,6 +43,7 @@ function validateDocument(document: TextDocument) { Array.from({ length: document.lineCount }, (_, index) => document.lineAt(index).text), ); let decoratorBlock = [] as ReturnType; + let hasSeenConfigItem = false; const flushDecoratorBlock = () => { if (!decoratorBlock.length) return; @@ -60,6 +63,8 @@ function validateDocument(document: TextDocument) { if (trimmed.startsWith('#')) { decoratorBlock.push(...getDecoratorOccurrences(lineText, lineNumber)); + } else if (trimmed === '' && !hasSeenConfigItem) { + continue; } else { flushDecoratorBlock(); } @@ -67,6 +72,8 @@ function validateDocument(document: TextDocument) { const match = lineText.match(ENV_ASSIGNMENT_PATTERN); if (!match) continue; + hasSeenConfigItem = true; + const rawValue = stripInlineComment(match[2]); if (!rawValue) continue; if (isDynamicValue(rawValue)) continue; diff --git a/packages/vscode-plugin/test/completion-core.test.ts b/packages/vscode-plugin/test/completion-core.test.ts index cd900bd8..7d963891 100644 --- a/packages/vscode-plugin/test/completion-core.test.ts +++ b/packages/vscode-plugin/test/completion-core.test.ts @@ -2,25 +2,77 @@ import { describe, expect, it } from 'vitest'; import { filterAvailableDecorators, + getDecoratorCommentPrefix, getEnumValuesFromPrecedingComments, getExistingDecoratorNames, getTypeOptionDataType, isInHeader, } from '../src/completion-core'; import { createLineDocument } from '../src/document-lines'; -import { DATA_TYPES, ITEM_DECORATORS } from '../src/intellisense-catalog'; +import { DATA_TYPES, ITEM_DECORATORS, ROOT_DECORATORS } from '../src/intellisense-catalog'; describe('completion-core', () => { - it('detects root header vs item sections', () => { + it('treats divider-separated comments directly above the first item as item scope', () => { const document = createLineDocument([ '# @defaultRequired=false', '# ---', + '# @currentEnv=$APP_ENV', + 'APP_ENV=staging', '# @required', - 'APP_ENV=', + 'ITEM=', ]); expect(isInHeader(document, 0)).toBe(true); expect(isInHeader(document, 2)).toBe(false); + expect(isInHeader(document, 4)).toBe(false); + }); + + it('treats free-floating comment blocks before the first item as header', () => { + const document = createLineDocument([ + '# @defaultRequired=false', + '', + '# @currentEnv=$APP_ENV', + '', + '# @required', + ]); + + expect(isInHeader(document, 0)).toBe(true); + expect(isInHeader(document, 2)).toBe(true); + expect(isInHeader(document, 4)).toBe(true); + }); + + it('treats the comment block directly above the first item as item scope', () => { + const document = createLineDocument([ + '# @defaultRequired=false', + '# @generateTypes(lang=ts, path=./env.d.ts)', + '', + '# @required', + 'MY_VAR=', + ]); + + expect(isInHeader(document, 3)).toBe(false); + expect(getExistingDecoratorNames(document, 3, ' @required @')).toEqual(new Set(['required'])); + expect( + filterAvailableDecorators(ITEM_DECORATORS, getExistingDecoratorNames(document, 3, ' @required @')).map( + (decorator) => decorator.name, + ), + ).not.toContain('required'); + }); + + it('keeps divider-separated free-floating blocks before the first item in header scope', () => { + const document = createLineDocument([ + '# @defaultRequired=false', + '# @generateTypes(lang=ts, path=./env.d.ts)', + '# ---', + '# @', + ]); + + expect(isInHeader(document, 3)).toBe(true); + expect( + filterAvailableDecorators(ROOT_DECORATORS, getExistingDecoratorNames(document, 3, ' @')).map( + (decorator) => decorator.name, + ), + ).not.toContain('defaultRequired'); }); it('collects decorators already used in the current block', () => { @@ -34,6 +86,69 @@ describe('completion-core', () => { ).toEqual(new Set(['docs', 'required', 'type'])); }); + it('keeps root duplicate filtering across divider-less header blocks', () => { + const document = createLineDocument([ + '# @defaultRequired=false', + '', + '# @currentEnv=$APP_ENV', + '', + '# @', + ]); + + const existingDecoratorNames = getExistingDecoratorNames(document, 4, ' @'); + + expect(existingDecoratorNames).toEqual(new Set(['defaultRequired', 'currentEnv'])); + expect( + filterAvailableDecorators(ROOT_DECORATORS, existingDecoratorNames).map((decorator) => decorator.name), + ).not.toContain('defaultRequired'); + }); + + it('ends header scope after exported config items', () => { + const document = createLineDocument([ + '# @defaultRequired=false', + 'export APP_ENV=staging', + '# @', + ]); + + expect(isInHeader(document, 2)).toBe(false); + }); + + it('ends header scope after dotted and hyphenated config item keys', () => { + const dottedDocument = createLineDocument([ + '# @defaultRequired=false', + 'APP.ENV=staging', + '# @', + ]); + const hyphenDocument = createLineDocument([ + '# @defaultRequired=false', + 'APP-ENV=staging', + '# @', + ]); + + expect(isInHeader(dottedDocument, 2)).toBe(false); + expect(isInHeader(hyphenDocument, 2)).toBe(false); + }); + + it('ignores decorator-like text in regular comments', () => { + expect(getDecoratorCommentPrefix('# this @required is docs only')).toBeUndefined(); + expect(getDecoratorCommentPrefix('# @todo: follow up later')).toBeUndefined(); + expect(getDecoratorCommentPrefix('# @see docs for more info')).toBeUndefined(); + }); + + it('ignores decorator-like text in post-comments', () => { + expect(getDecoratorCommentPrefix('# @required # @optional')).toBe('@required'); + expect( + getExistingDecoratorNames( + createLineDocument([ + '# @required # @optional', + '# @', + ]), + 1, + ' @', + ), + ).toEqual(new Set(['required'])); + }); + it('filters duplicate and incompatible decorators but keeps repeatable ones', () => { const available = filterAvailableDecorators( ITEM_DECORATORS, diff --git a/packages/vscode-plugin/test/diagnostics-core.test.ts b/packages/vscode-plugin/test/diagnostics-core.test.ts index fd15a2d4..e3e292e9 100644 --- a/packages/vscode-plugin/test/diagnostics-core.test.ts +++ b/packages/vscode-plugin/test/diagnostics-core.test.ts @@ -13,6 +13,7 @@ describe('diagnostics-core', () => { const duplicates = createDecoratorDiagnostics([ ...getDecoratorOccurrences('# @required @required', 0), ...getDecoratorOccurrences('# @docs(https://a.com) @docs(https://b.com)', 1), + ...getDecoratorOccurrences('# @initOp(allowAppAuth=true) @initOp(token=$OP_TOKEN)', 2), ]); expect(duplicates.map((diagnostic) => diagnostic.message)).toContain( @@ -21,6 +22,9 @@ describe('diagnostics-core', () => { expect( duplicates.some((diagnostic) => diagnostic.message.includes('@docs')), ).toBe(false); + expect( + duplicates.some((diagnostic) => diagnostic.message.includes('@initOp')), + ).toBe(false); }); it('flags incompatible decorator pairs inline', () => { @@ -36,6 +40,27 @@ describe('diagnostics-core', () => { ); }); + it('ignores decorator-like text inside regular comments', () => { + const diagnostics = createDecoratorDiagnostics( + getDecoratorOccurrences('# this @required mention is just documentation', 0), + ); + + expect(diagnostics).toEqual([]); + }); + + it('ignores decorator-like text inside post-comments on decorator lines', () => { + const diagnostics = createDecoratorDiagnostics( + getDecoratorOccurrences('# @required # this @optional is commented', 0), + ); + + expect(diagnostics).toEqual([]); + }); + + it('ignores parser-style ignored decorator comments', () => { + expect(getDecoratorOccurrences('# @todo: revisit this later', 0)).toEqual([]); + expect(getDecoratorOccurrences('# @see docs for details', 0)).toEqual([]); + }); + it('reads type info from the comment block above an item', () => { const document = createLineDocument([ '# @required @type=url(prependHttps=true, allowedDomains="example.com,api.example.com")', @@ -52,6 +77,24 @@ describe('diagnostics-core', () => { }); }); + it('ignores type info inside regular comments above an item', () => { + const document = createLineDocument([ + '# mention @type=url(prependHttps=true) in docs only', + 'API_URL=example.com', + ]); + + expect(getTypeInfoFromPrecedingComments(document, 1)).toBeUndefined(); + }); + + it('ignores type info inside post-comments on decorator lines', () => { + const document = createLineDocument([ + '# @required # @type=url(prependHttps=true)', + 'API_URL=example.com', + ]); + + expect(getTypeInfoFromPrecedingComments(document, 1)).toBeUndefined(); + }); + it('validates enum values against the decorator list', () => { const typeInfo = { name: 'enum', diff --git a/packages/vscode-plugin/test/diagnostics-provider.test.ts b/packages/vscode-plugin/test/diagnostics-provider.test.ts new file mode 100644 index 00000000..1bae7f92 --- /dev/null +++ b/packages/vscode-plugin/test/diagnostics-provider.test.ts @@ -0,0 +1,64 @@ +import { + beforeAll, describe, expect, it, vi, +} from 'vitest'; + +vi.mock('vscode', () => ({ + Diagnostic: class { + range: unknown; + message: string; + severity: unknown; + + constructor(range: unknown, message: string, severity: unknown) { + this.range = range; + this.message = message; + this.severity = severity; + } + }, + DiagnosticSeverity: { Error: 0 }, + Disposable: class {}, + Position: class { + constructor(public line: number, public character: number) {} + }, + Range: class { + constructor(public start: unknown, public end: unknown) {} + }, + languages: { createDiagnosticCollection: vi.fn() }, + workspace: { + onDidOpenTextDocument: vi.fn(), + onDidChangeTextDocument: vi.fn(), + onDidCloseTextDocument: vi.fn(), + textDocuments: [], + }, +})); + +let validateDocument: typeof import('../src/diagnostics-provider').validateDocument; + +beforeAll(async () => { + ({ validateDocument } = await import('../src/diagnostics-provider')); +}); + +function createTestDocument(lines: Array) { + return { + languageId: 'env-spec', + lineCount: lines.length, + lineAt(line: number) { + return { text: lines[line] }; + }, + }; +} + +describe('diagnostics-provider', () => { + it('keeps the header scope across blank lines before the first config item', () => { + const diagnostics = validateDocument(createTestDocument([ + '# @defaultRequired=true', + '', + '# @defaultRequired=false', + '', + 'ITEM=', + ])); + + expect(diagnostics.map((diagnostic) => diagnostic.message)).toContain( + '@defaultRequired can only be used once in the same decorator block.', + ); + }); +}); From dc6aadd44381bb1b9e099ca01ec3269dd3947ceb Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:11:48 -0400 Subject: [PATCH 3/4] intellij-plugin: address automated review feedback (#474) * Initial plan * Implement all review feedback: paren tokens, decorator filtering, key patterns, .idea gitignore Co-authored-by: philmillman <3722211+philmillman@users.noreply.github.com> Agent-Logs-Url: https://github.com/dmno-dev/varlock/sessions/45f827c0-165e-457c-83dc-538993ffa1bd --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: philmillman <3722211+philmillman@users.noreply.github.com> --- .gitignore | 3 ++ .idea/.gitignore | 10 ------ .idea/codeStyles/Project.xml | 10 ------ .idea/codeStyles/codeStyleConfig.xml | 5 --- .idea/inspectionProfiles/Project_Default.xml | 6 ---- .idea/modules.xml | 8 ----- .idea/varlock.iml | 8 ----- .idea/vcs.xml | 6 ---- packages/intellij-plugin/README.md | 2 +- .../envspec/EnvSpecCompletionContributor.kt | 11 +++--- .../dmno/envspec/EnvSpecDiagnosticsCore.kt | 26 ++++++++++++-- .../dev/dmno/envspec/EnvSpecInspection.kt | 2 +- .../kotlin/dev/dmno/envspec/EnvSpecLexer.kt | 8 ++--- .../dmno/envspec/EnvSpecSyntaxHighlighter.kt | 2 ++ .../dev/dmno/envspec/EnvSpecTokenTypes.kt | 6 ++++ packages/vscode-plugin/src/completion-core.ts | 35 ++----------------- .../vscode-plugin/src/diagnostics-core.ts | 2 ++ 17 files changed, 52 insertions(+), 98 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/varlock.iml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index b523d384..6fd493e9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ framework-tests/.packed framework-tests/.test-projects .magent eslint-output.txt + +.idea/ +*.iml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index ab1f4164..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Ignored default folder with query files -/queries/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index dc3e940f..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 9b8317cd..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/varlock.iml b/.idea/varlock.iml deleted file mode 100644 index c956989b..00000000 --- a/.idea/varlock.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/packages/intellij-plugin/README.md b/packages/intellij-plugin/README.md index 1dd69a3a..036176c3 100644 --- a/packages/intellij-plugin/README.md +++ b/packages/intellij-plugin/README.md @@ -71,7 +71,7 @@ Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): ### Troubleshooting -**Build fails with "What went wrong: 25"** — You're using Java 25, which Gradle 8.x doesn't support. Use Java 17: +**Build fails with "What went wrong: 25"** — You're using Java 25, which isn't supported by the Gradle/toolchain used for this plugin. Use Java 17: ```bash # Homebrew (openjdk@17) diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt index 9aa8de25..086fe788 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt @@ -26,7 +26,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { } companion object { - private val ENV_KEY_PATTERN = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=") + private val ENV_KEY_PATTERN = Pattern.compile("^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_.-]*)\\s*=") private val KOTLIN_ESCAPED_DOLLAR_RE = Regex("\\$\\{'\\$'\\}") private val CHOICE_SNIPPET_RE = Regex("""\$\{\d+\|([^}]*)\|\}""") private val DEFAULT_SNIPPET_RE = Regex("""\$\{\d+:([^}]*)\}""") @@ -34,6 +34,10 @@ class EnvSpecCompletionContributor : CompletionContributor() { private val SIMPLE_TABSTOP_SNIPPET_RE = Regex("""\$\d+""") } + private fun getDecoratorCommentPrefix(linePrefix: String): String? { + return EnvSpecDiagnosticsCore.getDecoratorCommentText(linePrefix) + } + private fun doAddCompletions(params: CompletionParameters, result: CompletionResultSet) { val file = params.originalFile as? EnvSpecFile ?: return val document = params.editor.document @@ -41,8 +45,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { val line = document.getLineNumber(offset) val lineStart = document.getLineStartOffset(line) val linePrefix = document.getText(com.intellij.openapi.util.TextRange(lineStart, offset)) - val commentStart = linePrefix.indexOf('#') - val commentPrefix = if (commentStart >= 0) linePrefix.substring(commentStart + 1) else "" + val commentPrefix = getDecoratorCommentPrefix(linePrefix) val lineDocument = object : LineDocument { override val lineCount: Int get() = document.lineCount @@ -63,7 +66,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { return } - if (commentStart >= 0) { + if (commentPrefix != null) { val existingDecoratorNames = EnvSpecCompletionCore.getExistingDecoratorNames(lineDocument, line, commentPrefix) // Type option completion diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt index 5c15428b..1a3e7e3c 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt @@ -4,7 +4,10 @@ import java.net.InetAddress object EnvSpecDiagnosticsCore { + private val DECORATOR_LINE_PATTERN = Regex("""^\s*#\s*(@.*)$""") private val DECORATOR_PATTERN = Regex("@([A-Za-z][\\w-]*)(?:\\([^)]*\\)|=[^\\s#]+)?") + private val NON_DECORATOR_LABEL_RE = Regex("^@[A-Za-z]+:") + private val NON_DECORATOR_PROSE_RE = Regex("^@[A-Za-z]+\\s+[^@#]") private const val MAX_MATCHES_PATTERN_LENGTH = 200 private val INCOMPATIBLE_DECORATOR_PAIRS = listOf( listOf("required", "optional"), @@ -15,6 +18,20 @@ object EnvSpecDiagnosticsCore { data class DecoratorOccurrence(val name: String, val line: Int, val start: Int, val end: Int) data class CoreDiagnostic(val line: Int, val start: Int, val end: Int, val message: String) + fun getDecoratorCommentText(lineText: String): String? { + return getDecoratorCommentRange(lineText)?.first + } + + private fun getDecoratorCommentRange(lineText: String): Pair? { + val match = DECORATOR_LINE_PATTERN.find(lineText) ?: return null + val commentText = match.groupValues[1] + if (NON_DECORATOR_LABEL_RE.containsMatchIn(commentText)) return null + if (NON_DECORATOR_PROSE_RE.containsMatchIn(commentText)) return null + val stripped = stripInlineComment(commentText) + val startIndex = match.groups[1]!!.range.first + return stripped to startIndex + } + fun stripInlineComment(value: String): String { var quote: Char? = null for (i in value.indices) { @@ -107,7 +124,8 @@ object EnvSpecDiagnosticsCore { fun getTypeInfoFromPrecedingComments(document: LineDocument, lineNumber: Int): TypeInfo? { val commentBlock = getPrecedingCommentBlock(document, lineNumber) for (index in commentBlock.indices.reversed()) { - val match = Regex("@type=([A-Za-z][\\w-]*)(?:\\((.*)\\))?").find(commentBlock[index]) ?: continue + val decoratorText = getDecoratorCommentText(commentBlock[index]) ?: continue + val match = Regex("@type=([A-Za-z][\\w-]*)(?:\\((.*)\\))?").find(decoratorText) ?: continue return if (match.groupValues[1] == "enum") { TypeInfo("enum", splitEnumArgs(match.groupValues[2]), emptyMap()) } else { @@ -118,8 +136,10 @@ object EnvSpecDiagnosticsCore { } fun getDecoratorOccurrences(lineText: String, lineNumber: Int): List { - return DECORATOR_PATTERN.findAll(lineText).map { match -> - DecoratorOccurrence(match.groupValues[1], lineNumber, match.range.first, match.range.last + 1) + val (decoratorText, startIndex) = getDecoratorCommentRange(lineText) ?: return emptyList() + return DECORATOR_PATTERN.findAll(decoratorText).map { match -> + val absStart = startIndex + (match.range.first) + DecoratorOccurrence(match.groupValues[1], lineNumber, absStart, absStart + match.value.length) }.toList() } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt index 93f20994..6267858a 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt @@ -69,6 +69,6 @@ class EnvSpecInspection : LocalInspectionTool() { } companion object { - private val ENV_ASSIGNMENT = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*?)\\s*$") + private val ENV_ASSIGNMENT = Pattern.compile("^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_.-]*)\\s*=\\s*(.*?)\\s*$") } } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt index 23e0c5fc..45a66a9e 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt @@ -226,13 +226,13 @@ class EnvSpecLexer : LexerBase() { queue.add(QueuedToken(start + i, start + valueEnd, EnvSpecTokenTypes.DECORATOR_VALUE)) i = valueEnd if (i < text.length && text[i] == '(') { - queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS)) + queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.PAREN_OPEN)) val close = findClosingParen(text, i) if (close > i + 1) { enqueueDecoratorArgsTokens(start + i + 1, text.substring(i + 1, close)) } if (close < text.length) { - queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.EQUALS)) + queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.PAREN_CLOSE)) i = close + 1 } else { i = text.length @@ -251,13 +251,13 @@ class EnvSpecLexer : LexerBase() { } if (i < text.length && text[i] == '(') { - queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS)) + queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.PAREN_OPEN)) val close = findClosingParen(text, i) if (close > i + 1) { enqueueDecoratorArgsTokens(start + i + 1, text.substring(i + 1, close)) } if (close < text.length) { - queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.EQUALS)) + queue.add(QueuedToken(start + close, start + close + 1, EnvSpecTokenTypes.PAREN_CLOSE)) i = close + 1 } else { i = text.length diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt index b2022a4b..7e0e7ba5 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt @@ -24,6 +24,8 @@ class EnvSpecSyntaxHighlighter : SyntaxHighlighterBase() { EnvSpecTokenTypes.EXPORT_KEYWORD -> KEYWORD_KEYS EnvSpecTokenTypes.ENV_KEY -> INSTANCE_FIELD_KEYS EnvSpecTokenTypes.EQUALS -> OPERATION_SIGN_KEYS + EnvSpecTokenTypes.PAREN_OPEN -> OPERATION_SIGN_KEYS + EnvSpecTokenTypes.PAREN_CLOSE -> OPERATION_SIGN_KEYS EnvSpecTokenTypes.ENV_VALUE -> STRING_KEYS EnvSpecTokenTypes.VALUE_FUNCTION -> FUNCTION_CALL_KEYS EnvSpecTokenTypes.VALUE_REFERENCE -> VALUE_REFERENCE_KEYS diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt index 8ed13475..77a77fdb 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt @@ -43,6 +43,12 @@ object EnvSpecTokenTypes { @JvmField val EQUALS: IElementType = object : IElementType("ENV_SPEC_EQUALS", EnvSpecLanguage) {} + @JvmField + val PAREN_OPEN: IElementType = object : IElementType("ENV_SPEC_PAREN_OPEN", EnvSpecLanguage) {} + + @JvmField + val PAREN_CLOSE: IElementType = object : IElementType("ENV_SPEC_PAREN_CLOSE", EnvSpecLanguage) {} + @JvmField val ENV_VALUE: IElementType = object : IElementType("ENV_SPEC_VALUE", EnvSpecLanguage) {} diff --git a/packages/vscode-plugin/src/completion-core.ts b/packages/vscode-plugin/src/completion-core.ts index cb540f69..ad9a4b7d 100644 --- a/packages/vscode-plugin/src/completion-core.ts +++ b/packages/vscode-plugin/src/completion-core.ts @@ -1,4 +1,5 @@ import type { DataTypeInfo, DecoratorInfo } from './intellisense-catalog'; +import { getDecoratorCommentText } from './diagnostics-core'; type LineDocument = { lineCount: number; @@ -15,39 +16,9 @@ const INCOMPATIBLE_DECORATORS = new Map>([ ['public', new Set(['sensitive'])], ]); -function stripInlineComment(value: string) { - let quote: '"' | '\'' | '' = ''; - - for (let i = 0; i < value.length; i += 1) { - const char = value[i]; - if (quote) { - if (char === quote) quote = ''; - continue; - } - - if (char === '"' || char === '\'') { - quote = char; - continue; - } - - if (char === '#' && (i === 0 || /\s/.test(value[i - 1]))) { - return value.slice(0, i).trimEnd(); - } - } - - return value.trim(); -} - +/** Thin wrapper kept for API compatibility with existing callers and tests. */ export function getDecoratorCommentPrefix(lineText: string) { - const match = lineText.match(/^\s*#\s*(@.*)$/); - if (!match) return undefined; - - const commentText = match[1]; - - if (/^@[A-Za-z]+:/.test(commentText)) return undefined; - if (/^@[A-Za-z]+\s+[^@#]/.test(commentText)) return undefined; - - return stripInlineComment(commentText); + return getDecoratorCommentText(lineText); } function splitArgs(input: string) { diff --git a/packages/vscode-plugin/src/diagnostics-core.ts b/packages/vscode-plugin/src/diagnostics-core.ts index 1b5814cd..e7b1a198 100644 --- a/packages/vscode-plugin/src/diagnostics-core.ts +++ b/packages/vscode-plugin/src/diagnostics-core.ts @@ -169,6 +169,8 @@ function getDecoratorCommentText(lineText: string) { return stripInlineComment(commentText); } +export { getDecoratorCommentText }; + export function getTypeInfoFromPrecedingComments(document: LineDocument, lineNumber: number) { const commentBlock = getPrecedingCommentBlock(document, lineNumber); From 9fd3f9688a5119513d1156f67059e093c13881ab Mon Sep 17 00:00:00 2001 From: philmillman Date: Tue, 24 Mar 2026 15:58:54 -0400 Subject: [PATCH 4/4] add release automation (keep manual for now) --- .github/config/labeler.yaml | 3 + .github/workflows/extensions-release.yaml | 97 +++++++++++++++++++ packages/intellij-plugin/.env.schema | 23 +++++ packages/intellij-plugin/README.md | 45 +++++++++ packages/intellij-plugin/build.gradle.kts | 21 +++- .../envspec/EnvSpecCompletionContributor.kt | 1 + .../dmno/envspec/EnvSpecDiagnosticsCore.kt | 4 +- 7 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/extensions-release.yaml create mode 100644 packages/intellij-plugin/.env.schema diff --git a/.github/config/labeler.yaml b/.github/config/labeler.yaml index ffc5e6a7..add870e6 100644 --- a/.github/config/labeler.yaml +++ b/.github/config/labeler.yaml @@ -10,6 +10,9 @@ "core:vscode-plugin": - changed-files: - any-glob-to-any-file: 'packages/vscode-plugin/**' +"core:intellij-plugin": +- changed-files: + - any-glob-to-any-file: 'packages/intellij-plugin/**' "core:website": - changed-files: - any-glob-to-any-file: 'packages/varlock-website/**' diff --git a/.github/workflows/extensions-release.yaml b/.github/workflows/extensions-release.yaml new file mode 100644 index 00000000..39147f2f --- /dev/null +++ b/.github/workflows/extensions-release.yaml @@ -0,0 +1,97 @@ +name: IntelliJ plugin release + +on: + workflow_dispatch: + inputs: + ref: + description: Git ref to build (branch, tag, or full SHA) + required: true + default: main + type: string + publish: + description: Run JetBrains Marketplace publish (validate + build always run) + required: false + default: false + type: boolean + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + validate-intellij: + name: Validate IntelliJ plugin + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/intellij-plugin + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.inputs.ref }} + - name: Load plugin env vars (varlock) + uses: dmno-dev/varlock-action@v1.0.1 + with: + working-directory: packages/intellij-plugin + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Run IntelliJ plugin tests + run: ./gradlew test + - name: Verify plugin compatibility (JetBrains Plugin Verifier) + run: ./gradlew verifyPlugin + + build-artifacts: + name: Build IntelliJ plugin artifact + runs-on: ubuntu-latest + needs: [validate-intellij] + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.inputs.ref }} + - name: Load plugin env vars (varlock) + uses: dmno-dev/varlock-action@v1.0.1 + with: + working-directory: packages/intellij-plugin + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + - name: Build IntelliJ plugin zip + working-directory: packages/intellij-plugin + run: chmod +x gradlew && ./gradlew buildPlugin + - name: Upload IntelliJ artifact + uses: actions/upload-artifact@v4 + with: + name: intellij-plugin-zip + path: packages/intellij-plugin/build/distributions/*.zip + if-no-files-found: error + + publish-intellij: + name: Publish IntelliJ plugin + runs-on: ubuntu-latest + if: github.event.inputs.publish == 'true' + needs: [build-artifacts] + defaults: + run: + working-directory: packages/intellij-plugin + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.inputs.ref }} + - name: Load plugin env vars (varlock) + uses: dmno-dev/varlock-action@v1.0.1 + with: + working-directory: packages/intellij-plugin + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Publish IntelliJ plugin + run: ./gradlew publishPlugin diff --git a/packages/intellij-plugin/.env.schema b/packages/intellij-plugin/.env.schema new file mode 100644 index 00000000..67eaedf0 --- /dev/null +++ b/packages/intellij-plugin/.env.schema @@ -0,0 +1,23 @@ +# This .env file uses https://varlock.dev +# @defaultRequired=true @defaultSensitive=true +# @currentEnv=$VARLOCK_ENV +# @plugin(@varlock/1password-plugin) +# @initOp(token=$OP_CI_TOKEN, allowAppAuth=true) +# --- + +# OP Token, only needed for releases in CI environments. +# @type=opServiceAccountToken @sensitive +# @required=eq($VARLOCK_PLATFORM, "GitHub Actions") +OP_CI_TOKEN= + +# JetBrains Marketplace publish token used by `publishPlugin`. +JETBRAINS_MARKETPLACE_TOKEN=op("op://VarlockCI/Jetbrains Marketplace Publishing/JETBRAINS_MARKETPLACE_TOKEN") + +# Plugin signing certificate chain (PEM). +JETBRAINS_CERTIFICATE_CHAIN=op("op://VarlockCI/Jetbrains Marketplace Publishing/chain.crt") + +# Plugin signing private key (PEM). +JETBRAINS_PRIVATE_KEY=op("op://VarlockCI/Jetbrains Marketplace Publishing/private.pem") + +# Password for the signing private key. +JETBRAINS_PRIVATE_KEY_PASSWORD=op("op://VarlockCI/Jetbrains Marketplace Publishing/JETBRAINS_PRIVATE_KEY_PASSWORD") diff --git a/packages/intellij-plugin/README.md b/packages/intellij-plugin/README.md index 036176c3..dab7b9d6 100644 --- a/packages/intellij-plugin/README.md +++ b/packages/intellij-plugin/README.md @@ -51,6 +51,13 @@ Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): - `.env` - `.env.*` (e.g. `.env.schema`, `.env.local`, `.env.example`) +## JetBrains IDE compatibility + +This plugin targets the IntelliJ Platform (`com.intellij.modules.platform`), so it is installable in most JetBrains IDEs that support plugins and `.env` workflows (IntelliJ IDEA, WebStorm, PyCharm, PhpStorm, GoLand, RubyMine, CLion, etc.), subject to Marketplace build compatibility. + +- Compatibility range is defined in `build.gradle.kts` via `sinceBuild` / `untilBuild`. +- CI release validation runs JetBrains Plugin Verifier (`./gradlew verifyPlugin`) to catch cross-IDE compatibility issues before publishing. + ## Requirements - IntelliJ IDEA 2024.3+ or WebStorm 2024.3+ @@ -69,6 +76,44 @@ Inspired by the [VS Code / Open VSX extension](../../vscode-plugin): ./gradlew test ``` +## Publishing + +### CI (GitHub Actions) + +Workflow: [`.github/workflows/extensions-release.yaml`](../../.github/workflows/extensions-release.yaml) (**IntelliJ plugin release**). + +Runs only via **Actions → IntelliJ plugin release → Run workflow** (no automatic runs on merge). + +| Phase | Behavior | +| --- | --- | +| **Always** | Check out the **ref** you specify, run tests + Plugin Verifier, build the ZIP, upload it as a workflow artifact. | +| **Optional** | Enable **publish** to run `publishPlugin` to JetBrains Marketplace after a successful build. | + +Workflow inputs: + +| Input | Description | +| --- | --- | +| **ref** | Git ref to build: branch name, tag, or full commit SHA. Default: `main`. | +| **publish** | If enabled, runs the Marketplace publish job after a successful build. If disabled, CI still validates and uploads the ZIP artifact only. Default: off. | + +Secrets and varlock-loaded env for CI match local publishing (see `.env.schema`). + +### Local / manual Gradle + +Publish to JetBrains Marketplace: + +```bash +JETBRAINS_MARKETPLACE_TOKEN="" \ +JETBRAINS_CERTIFICATE_CHAIN="" \ +JETBRAINS_PRIVATE_KEY="" \ +JETBRAINS_PRIVATE_KEY_PASSWORD="" \ +./gradlew publishPlugin +``` + +- `publishPlugin` is provided by the IntelliJ Platform Gradle plugin. +- Signing is configured via `JETBRAINS_CERTIFICATE_CHAIN`, `JETBRAINS_PRIVATE_KEY`, and `JETBRAINS_PRIVATE_KEY_PASSWORD`. +- Required publish/signing env vars are documented in `packages/intellij-plugin/.env.schema`. + ### Troubleshooting **Build fails with "What went wrong: 25"** — You're using Java 25, which isn't supported by the Gradle/toolchain used for this plugin. Use Java 17: diff --git a/packages/intellij-plugin/build.gradle.kts b/packages/intellij-plugin/build.gradle.kts index 7ee80f1f..86cee952 100644 --- a/packages/intellij-plugin/build.gradle.kts +++ b/packages/intellij-plugin/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "dev.dmno" -version = "0.1.0" +version = "0.1.2" repositories { mavenCentral() @@ -43,11 +43,30 @@ intellijPlatform { pluginConfiguration { name.set("Env Spec Language") description.set("Adds syntax highlighting and IntelliSense for @env-spec enabled .env files") + ideaVersion { + // 243 = 2024.3 platform line. Keep this explicit so Marketplace compatibility is predictable. + sinceBuild.set("243") + // Allow current and near-future IDE lines; tighten if verifier starts flagging breakage. + untilBuild.set("251.*") + } vendor { name.set("dmno-dev") url.set("https://varlock.dev") } } + pluginVerification { + ides { + recommended() + } + } + signing { + certificateChain.set(providers.environmentVariable("JETBRAINS_CERTIFICATE_CHAIN")) + privateKey.set(providers.environmentVariable("JETBRAINS_PRIVATE_KEY")) + password.set(providers.environmentVariable("JETBRAINS_PRIVATE_KEY_PASSWORD")) + } + publishing { + token.set(providers.environmentVariable("JETBRAINS_MARKETPLACE_TOKEN")) + } } kotlin { diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt index 086fe788..c1de9f58 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt @@ -112,6 +112,7 @@ class EnvSpecCompletionContributor : CompletionContributor() { private data class ReplaceRange(val line: Int, val start: Int, val end: Int) + @Deprecated("IntelliJ still routes auto-popup through this API; TypedHandlerDelegate-only migration broke the typing pipeline.") override fun invokeAutoPopup(position: com.intellij.psi.PsiElement, typeChar: Char): Boolean { return typeChar == '@' || typeChar == '$' || typeChar == '=' || typeChar == ',' } diff --git a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt index 1a3e7e3c..7966aa45 100644 --- a/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt +++ b/packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt @@ -1,6 +1,7 @@ package dev.dmno.envspec import java.net.InetAddress +import java.net.URI object EnvSpecDiagnosticsCore { @@ -211,7 +212,8 @@ object EnvSpecDiagnosticsCore { if (prependHttps == true && hasProtocol) return "URL should omit the protocol when prependHttps=true." if (prependHttps != true && !hasProtocol) return "URL must include a protocol unless prependHttps=true." return try { - val url = java.net.URL(if (prependHttps == true) "https://$value" else value) + val spec = if (prependHttps == true) "https://$value" else value + val url = URI.create(spec).toURL() val allowedDomains = (options["allowedDomains"] as? String)?.let { splitEnumArgs(it) } ?: emptyList() if (allowedDomains.isNotEmpty() && !allowedDomains.contains(url.host.lowercase())) { "URL host must be one of: ${allowedDomains.joinToString(", ")}."