diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..21b5ac31 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm test + + - name: Run lint + run: npm run lint + + deno: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Deno + uses: denoland/setup-deno@v1 + with: + deno-version: v2.2.6 + + - name: Cache dependencies + run: deno cache source/cli.tsx + + - name: Run tests + run: deno test --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys + + - name: Run lint + run: deno lint + + - name: Run format check + run: deno fmt --check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..7d568aba --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,92 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Deno + uses: denoland/setup-deno@v1 + with: + deno-version: v2.2.6 + + - name: Build for macOS (arm64) + run: | + deno compile --target aarch64-apple-darwin \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output permit-cli-macos-arm64 source/cli.tsx + + - name: Build for macOS (x64) + run: | + deno compile --target x86_64-apple-darwin \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output permit-cli-macos-x64 source/cli.tsx + + - name: Build for Linux (x64) + run: | + deno compile --target x86_64-unknown-linux-gnu \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output permit-cli-linux-x64 source/cli.tsx + + - name: Build for Windows (x64) + run: | + deno compile --target x86_64-pc-windows-msvc \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output permit-cli-windows-x64.exe source/cli.tsx + + - name: Install create-dmg + run: | + brew install create-dmg + + - name: Create DMG for macOS (arm64) + run: | + mkdir -p dmg/arm64 + cp permit-cli-macos-arm64 dmg/arm64/permit + create-dmg \ + --volname "Permit CLI" \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --icon "permit" 200 190 \ + --hide-extension "permit" \ + --app-drop-link 600 185 \ + "permit-cli-macos-arm64.dmg" \ + "dmg/arm64/" + + - name: Create DMG for macOS (x64) + run: | + mkdir -p dmg/x64 + cp permit-cli-macos-x64 dmg/x64/permit + create-dmg \ + --volname "Permit CLI" \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --icon "permit" 200 190 \ + --hide-extension "permit" \ + --app-drop-link 600 185 \ + "permit-cli-macos-x64.dmg" \ + "dmg/x64/" + + - name: Create Release + id: create_release + uses: softprops/action-gh-release@v1 + with: + files: | + permit-cli-macos-arm64 + permit-cli-macos-x64 + permit-cli-linux-x64 + permit-cli-windows-x64.exe + permit-cli-macos-arm64.dmg + permit-cli-macos-x64.dmg + draft: false + prerelease: false + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index f60f1c2b..87829be0 100644 --- a/.gitignore +++ b/.gitignore @@ -183,4 +183,9 @@ dist .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz -.pnp.* \ No newline at end of file +.pnp.* + +# Deno build artifacts +permit-cli +permit-cli.exe +dist/ \ No newline at end of file diff --git a/README.md b/README.md index 426e461c..ef575e25 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Permit CLI [![test](https://github.com/permitio/permit-cli/actions/workflows/node.js.yml/badge.svg)](https://github.com/vadimdemedes/pastel/actions/workflows/node.js.yml) [![Join our Slack!](https://img.shields.io/badge/Slack%20Community-4A154B?logo=slack&logoColor=white)](https://io.permit.io/cli-slack) ![Early Stage Development](https://img.shields.io/badge/⚠️_Early_Stage_Development-2B1400) ![Follow us on LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white) +# Permit CLI [![test](https://github.com/permitio/permit-cli/actions/workflows/node.js.yml/badge.svg)](https://github.com/permitio/permit-cli/actions/workflows/node.js.yml) [![Join our Slack!](https://img.shields.io/badge/Slack%20Community-4A154B?logo=slack&logoColor=white)](https://io.permit.io/cli-slack) ![Early Stage Development](https://img.shields.io/badge/⚠️_Early_Stage_Development-2B1400) ![Follow us on LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)

@@ -15,12 +15,35 @@ The **Permit CLI** is an open-source command-line utility that empowers develope ## Installation -Permit CLI is now available only via the `npm` and requires a [Node.js installation](https://nodejs.org/en/download) to run +### Quick Install (All Platforms) -```console -npm install -g @permitio/cli +```bash +# Using curl +curl -fsSL https://raw.githubusercontent.com/permitio/permit-cli/main/install.sh | sh +``` + +### Windows + +```powershell +# Using PowerShell +Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/permitio/permit-cli/main/install.ps1')) +``` + +### macOS + +```bash +# Using Homebrew +brew tap permitio/permit +brew install permit ``` +### Manual Installation + +1. Download the binary for your platform from our [releases page](https://github.com/permitio/permit-cli/releases) +2. Rename it to `permit` (or `permit.exe` on Windows) +3. Move it to a directory in your PATH +4. Make it executable (Unix-like systems only): `chmod +x permit` + ## Usage All the commands in the CLI are available via the `permit` command in the following convention: @@ -92,7 +115,7 @@ This command will log you out from your Permit account and remove the stored key #### Example ```bash -permit logout +$ permit logout ``` --- @@ -144,7 +167,7 @@ Use this command to perform an authorization check against the PDP. The command #### Example ```bash -$ permit pdp check --user eventHandler --action update --resource Widget:dashboard-1-widget +permit pdp check --user eventHandler --action update --resource Widget:dashboard-1-widget ``` ### `pdp stats` @@ -162,7 +185,7 @@ Use this command to view statistics about your PDP's performance and usage. This #### Example ```bash -$ permit pdp stats +permit pdp stats ``` --- @@ -187,7 +210,7 @@ Developers and CI pipelines can use this command to enable secure blue-green dep #### Example ```bash -$ permit env copy --key permit_key_.......... --from staging --to production --conflict-strategy overwrite +permit env copy --key permit_key_.......... --from staging --to production --conflict-strategy overwrite ``` ### `env create` @@ -206,13 +229,13 @@ This command creates a new environment in a specified project. This is useful fo #### Example ```bash -$ permit env create --key permit_key_.......... --name "Staging" --description "Staging environment for testing" +permit env create --key permit_key_.......... --name "Staging" --description "Staging environment for testing" ``` **You can also create a complex environment with all options:** ```bash -$ permit env create --apiKey permit_key_.......... --name "Development" --envKey "dev" --description "Dev environment" --customBranchName "dev-branch" --jwks '{"ttl": 3600}' --settings '{"debug": true}' +permit env create --api-key permit_key_.......... --name "Development" --env-key "dev" --description "Dev environment" --custom-branch-name "dev-branch" --jwks '{"ttl": 3600}' --settings '{"debug": true}' ``` ### `env delete` @@ -228,13 +251,13 @@ This command deletes an existing environment. Use with caution as this operation #### Example ```bash -$ permit env delete --key permit_key_.......... --environmentId env_456 +permit env delete --key permit_key_.......... --environment-id env_456 ``` **Or to force deletion without confirmation:** ```bash -$ permit env delete --key permit_key_.......... --environmentId env_456 --force +permit env delete --key permit_key_.......... --environment-id env_456 --force ``` > **Note:** If you've authenticated via `permit login`, the commands will use your current project context automatically. @@ -256,7 +279,7 @@ This command can run in the CI after creating a new environment for development #### Example ```bash -$ permit env member --key permit_key_.......... --environment staging --project my-project --email gabriel@permit.io --role Owner +permit env member --key permit_key_.......... --environment staging --project my-project --email gabriel@permit.io --role Owner ``` ### `env select` @@ -270,31 +293,30 @@ This command will let you select a different active Permit.io environment. This #### Example ```bash -$ permit env select --key permit_key_......... +permit env select --key permit_key_......... ``` ### `env export terraform` This command exports your Permit environment configuration as a Terraform HCL file. This is useful for users who want to start working with Terraform after configuring their Permit settings through the UI or API. The command export all environment content (resources, roles, user sets, resource sets, condition sets) in the Permit Terraform provider format. -Options +#### Options - `--key ` (Optional) - a Permit API key to authenticate the operation. If not provided, the command will use the AuthProvider to get the API key you logged in with. - -- `--file ` (Optional) - a file path where the exported HCL should be saved. If not provided, the output will be printed to the console. +- `--file ` (Optional) - the file to export the configuration to (will prompt if not provided) ### Example ### Using the permit key ```bash -$ permit env export terraform --key permit_key_.......... --file permit-config.tf +permit env export terraform --key permit_key_.......... --file permit-config.tf ``` ### With login session ```bash -$ permit env export terraform --file permit-config.tf +permit env export terraform --file permit-config.tf ``` ### output configuration to console @@ -318,7 +340,7 @@ Use this command to list all the available policy templates to apply to your env #### Example ```bash -$ permit env template list +permit env template list ``` ### `env template apply` @@ -335,7 +357,7 @@ The command is using the Terraform provider to apply the template, but it's not #### Example ```bash -$ permit env template apply --template my-template +permit env template apply --template my-template ``` --- @@ -356,7 +378,7 @@ This command will print the available policies of an active OPA instance. This i #### Example ```bash -$ permit opa policy --server-url http://localhost:8181 --api-key permit_key_.......... +permit opa policy --server-url http://localhost:8181 --api-key permit_key_.......... ``` --- diff --git a/build.sh b/build.sh new file mode 100644 index 00000000..d8af1207 --- /dev/null +++ b/build.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Create build directory +mkdir -p dist + +# Build for macOS (arm64) +echo "Building for macOS (arm64)..." +deno compile \ + --target aarch64-apple-darwin \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output dist/permit-cli-macos-arm64 source/cli.tsx + +# Build for macOS (x64) +echo "Building for macOS (x64)..." +deno compile \ + --target x86_64-apple-darwin \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output dist/permit-cli-macos-x64 source/cli.tsx + +# Build for Linux (x64) +echo "Building for Linux (x64)..." +deno compile \ + --target x86_64-unknown-linux-gnu \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output dist/permit-cli-linux-x64 source/cli.tsx + +# Build for Windows (x64) +echo "Building for Windows (x64)..." +deno compile \ + --target x86_64-pc-windows-msvc \ + --allow-read --allow-write --allow-net --allow-env --allow-run --allow-sys \ + --output dist/permit-cli-windows-x64.exe source/cli.tsx + +# Create zip archives +echo "Creating zip archives..." +cd dist +zip permit-cli-macos-arm64.zip permit-cli-macos-arm64 +zip permit-cli-macos-x64.zip permit-cli-macos-x64 +zip permit-cli-linux-x64.zip permit-cli-linux-x64 +zip permit-cli-windows-x64.zip permit-cli-windows-x64.exe +cd .. + +# Build npm package +echo "Building npm package..." +npm run build + +echo "Build complete! Check the dist directory for the compiled binaries and zip files." \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 13c158a2..5a5f7a59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,6 @@ "ink-select-input": "^6.0.0", "ink-spinner": "^5.0.0", "ink-text-input": "^6.0.0", - "keytar": "^7.9.0", "micro-key-producer": "^0.7.2", "open": "^10.1.0", "openapi-fetch": "^0.13.4", @@ -60,6 +59,7 @@ "ink-testing-library": "^4.0.0", "openapi-typescript": "^7.6.1", "parser": "^0.1.4", + "pkg": "^5.8.1", "prettier": "^3.3.3", "rimraf": "^6.0.1", "ts-node": "^10.9.1", @@ -4060,6 +4060,16 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -4284,6 +4294,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -4295,6 +4306,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -4319,6 +4331,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -4650,6 +4663,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, "license": "ISC" }, "node_modules/ci-info": { @@ -4806,6 +4820,107 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/code-excerpt": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", @@ -5219,6 +5334,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -5277,6 +5393,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -5412,6 +5529,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -7130,6 +7248,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -7519,12 +7638,80 @@ "node": ">=0.10.0" } }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/from2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, "license": "MIT" }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7614,6 +7801,16 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-east-asian-width": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", @@ -7689,6 +7886,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, "license": "MIT" }, "node_modules/glob": { @@ -7944,6 +8142,16 @@ "uglify-js": "^3.1.4" } }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -8330,6 +8538,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, "license": "ISC" }, "node_modules/ink": { @@ -8818,6 +9027,23 @@ "node": ">= 0.4" } }, + "node_modules/into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/irregular-plurals": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", @@ -9732,6 +9958,19 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -9748,17 +9987,6 @@ "node": ">=4.0" } }, - "node_modules/keytar": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", - "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^4.3.0", - "prebuild-install": "^7.0.1" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -10219,6 +10447,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -10303,6 +10532,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, "license": "MIT" }, "node_modules/module-details-from-path": { @@ -10327,6 +10557,46 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + } + }, + "node_modules/multistream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/nan": { "version": "2.22.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", @@ -10428,6 +10698,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -10446,6 +10717,7 @@ "version": "3.71.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -10454,34 +10726,74 @@ "node": ">=10" } }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" + "whatwg-url": "^5.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/normalize-path": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", @@ -10872,6 +11184,16 @@ "node": ">= 0.8.0" } }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11235,6 +11557,312 @@ "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", "license": "MIT" }, + "node_modules/pkg": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.8.1.tgz", + "integrity": "sha512-CjBWtFStCfIiT4Bde9QpJy0KeH19jCfwZRJqHFDFXfhUklCx8JoFmMj3wgnEYIwGmZVNkhsStPHEOnrtrQhEXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/generator": "7.18.2", + "@babel/parser": "7.18.4", + "@babel/types": "7.19.0", + "chalk": "^4.1.2", + "fs-extra": "^9.1.0", + "globby": "^11.1.0", + "into-stream": "^6.0.0", + "is-core-module": "2.9.0", + "minimist": "^1.2.6", + "multistream": "^4.1.0", + "pkg-fetch": "3.4.2", + "prebuild-install": "7.1.1", + "resolve": "^1.22.0", + "stream-meter": "^1.0.4" + }, + "bin": { + "pkg": "lib-es5/bin.js" + }, + "peerDependencies": { + "node-notifier": ">=9.0.1" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/pkg-fetch": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.4.2.tgz", + "integrity": "sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "fs-extra": "^9.1.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.6", + "progress": "^2.0.3", + "semver": "^7.3.5", + "tar-fs": "^2.1.1", + "yargs": "^16.2.0" + }, + "bin": { + "pkg-fetch": "lib-es5/bin.js" + } + }, + "node_modules/pkg-fetch/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/pkg-fetch/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pkg-fetch/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/pkg-fetch/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-fetch/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg/node_modules/@babel/generator": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", + "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.2", + "@jridgewell/gen-mapping": "^0.3.0", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/pkg/node_modules/@babel/parser": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", + "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pkg/node_modules/@babel/types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", + "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/pkg/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pkg/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/pkg/node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pkg/node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg/node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pkg/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pkg/node_modules/resolve/node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pkg/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/plur": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", @@ -11307,32 +11935,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11402,6 +12004,16 @@ "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==", "license": "MIT" }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -11502,6 +12114,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -11517,6 +12130,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12142,6 +12756,16 @@ "node": ">=0.10" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -12719,6 +13343,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, "funding": [ { "type": "github", @@ -12739,6 +13364,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, "funding": [ { "type": "github", @@ -13118,6 +13744,56 @@ "node": ">= 0.4" } }, + "node_modules/stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.1.4" + } + }, + "node_modules/stream-meter/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-meter/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stream-meter/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-meter/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -13496,6 +14172,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -13508,6 +14185,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, "license": "MIT", "dependencies": { "bl": "^4.0.3", @@ -13524,6 +14202,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -13705,6 +14384,16 @@ "optional": true, "peer": true }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -13922,6 +14611,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -14179,6 +14869,16 @@ "node": ">=0.10.0" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -14949,6 +15649,16 @@ "optional": true, "peer": true }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -14962,6 +15672,25 @@ "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", "dev": true }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", @@ -14971,6 +15700,71 @@ "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index f7318a82..e812cf4f 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,48 @@ { - "name": "@permitio/cli", + "name": "permit-cli", "version": "0.1.2", + "description": "Developer swiss army knife for fine-grained authorization", + "main": "dist/cli.js", "license": "MIT", "bin": { - "permit": "dist/cli.js" + "permit": "./bin/cli.js" }, "type": "module", "engines": { "node": ">=22" }, "scripts": { - "build": "tsc", - "postbuild": "rimraf dist/commands/env/export/templates && cpx 'source/commands/env/export/templates/*.hcl' 'dist/commands/env/export/templates'", - "predev": "cpx 'source/commands/env/export/templates/*.hcl' 'dist/commands/env/export/templates'", - "dev": " NODE_NO_WARNINGS=1 tsc --watch", - "lint": "prettier --check . && eslint \"source/**/*.{js,ts,tsx}\"", - "lint:fix": "eslint \"source/**/*.{js,ts,tsx}\" --fix", - "test": "prettier --check ./source && vitest run --coverage", - "simple-check": "npx tsx ./source/cli.tsx pdp check -u filip@permit.io -a create -r task", - "test:ts": "tsc --noEmit" + "build": "tsup", + "dev": "tsup --watch", + "start": "node dist/cli.js", + "test": "vitest", + "test:watch": "vitest watch", + "test:coverage": "vitest run --coverage", + "lint": "eslint . --ext .ts,.tsx", + "format": "prettier --write .", + "prepare": "husky install", + "postinstall": "node scripts/postinstall.js", + "prepublishOnly": "npm run build", + "release": "npm run build && npm publish", + "create-release": "node scripts/create-release.js" }, "files": [ - "dist" + "bin/", + "dist/", + "install.sh", + "install.ps1" ], + "pkg": { + "targets": [ + "node18-macos-x64", + "node18-linux-x64", + "node18-win-x64" + ], + "outputPath": "bin", + "assets": [ + "dist/commands/env/export/templates/**/*" + ] + }, "dependencies": { "@scaleway/random-name": "^5.1.1", "cli-table": "^0.3.11", @@ -38,7 +58,6 @@ "ink-select-input": "^6.0.0", "ink-spinner": "^5.0.0", "ink-text-input": "^6.0.0", - "keytar": "^7.9.0", "micro-key-producer": "^0.7.2", "open": "^10.1.0", "openapi-fetch": "^0.13.4", @@ -72,6 +91,7 @@ "ink-testing-library": "^4.0.0", "openapi-typescript": "^7.6.1", "parser": "^0.1.4", + "pkg": "^5.8.1", "prettier": "^3.3.3", "rimraf": "^6.0.1", "ts-node": "^10.9.1", diff --git a/source/commands/_app.tsx b/source/commands/_app.tsx new file mode 100644 index 00000000..1dbd548b --- /dev/null +++ b/source/commands/_app.tsx @@ -0,0 +1,8 @@ +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default { + commands: join(__dirname, 'commands'), +}; diff --git a/source/commands/env/export/generators/RelationGenerator.ts b/source/commands/env/export/generators/RelationGenerator.ts index aa6e0ad0..2a8b5fed 100644 --- a/source/commands/env/export/generators/RelationGenerator.ts +++ b/source/commands/env/export/generators/RelationGenerator.ts @@ -5,27 +5,30 @@ import Handlebars from 'handlebars'; import { readFileSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; -import { RelationRead, ResourceRead } from 'permitio/build/main/openapi/types'; -import he from 'he'; -const currentFilePath = fileURLToPath(import.meta.url); -const currentDirPath = dirname(currentFilePath); +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); -// Helper function to unescape HTML entities using the he library -function unescapeHtml(text: string | undefined): string { - if (!text) return ''; - return he.decode(text); +interface RelationRead { + key: string; + name: string; + description?: string; + subject_resource: string; + object_resource: string; } -interface RelationData { - relation_id: string; +interface ResourceRead { + key: string; name: string; + description?: string; +} + +interface RelationData { key: string; + name: string; description?: string; subject_resource: string; object_resource: string; - subject_resource_ref: string; - object_resource_ref: string; dependencies: string[]; } @@ -38,7 +41,23 @@ export class RelationGenerator implements HCLGenerator { private permit: Permit, private warningCollector: WarningCollector, ) { - const templatePath = join(currentDirPath, '../templates/relation.hcl'); + // Register a simple helper that creates extremely safe descriptions for HCL + Handlebars.registerHelper('formatDescription', function (text) { + if (!text) return ''; + + // First, normalize the string to remove any non-basic characters + const sanitized = text + // Replace non-alphanumeric, non-basic punctuation with spaces + .replace(/[^\w\s.,!?()-]/g, ' ') + // Collapse multiple spaces into one + .replace(/\s+/g, ' ') + // Trim spaces + .trim(); + + return sanitized; + }); + + const templatePath = join(__dirname, '../templates/relation.hcl'); const templateContent = readFileSync(templatePath, 'utf-8'); this.template = Handlebars.compile(templateContent); } @@ -122,15 +141,11 @@ export class RelationGenerator implements HCLGenerator { // Store the relation with its Terraform resource name relations.push({ - relation_id: relationId, - name: unescapeHtml(relation.name) || relation.key, key: relation.key, - description: unescapeHtml(relation.description), + name: relation.name, + description: relation.description, subject_resource: safeSubjectResource, object_resource: safeObjectResource, - // Reference to the resource's key property for Terraform - subject_resource_ref: `permitio_resource.${safeSubjectResource}.key`, - object_resource_ref: `permitio_resource.${safeObjectResource}.key`, dependencies: [ `permitio_resource.${safeObjectResource}`, `permitio_resource.${safeSubjectResource}`, diff --git a/source/commands/index.tsx b/source/commands/index.tsx index b072336f..a03e2617 100644 --- a/source/commands/index.tsx +++ b/source/commands/index.tsx @@ -3,10 +3,15 @@ import Gradient from 'ink-gradient'; import { Text, Box, Newline } from 'ink'; import { AuthProvider } from '../components/AuthProvider.js'; import EnvironmentInfo from '../components/EnvironmentInfo.js'; +import { argv } from 'node:process'; export default function Index() { + const args = argv.slice(2); + const command = args[0] || ''; + const skipLogin = command !== 'login'; + return ( - + Permit CLI is a diff --git a/source/components/api/PermitUsersListComponent.tsx b/source/components/api/PermitUsersListComponent.tsx index f7ccac2a..b24e11f8 100644 --- a/source/components/api/PermitUsersListComponent.tsx +++ b/source/components/api/PermitUsersListComponent.tsx @@ -139,7 +139,6 @@ export default function PermitUsersListComponent({ options }: Props) { 'tenant', 'roles', ]} - headersHexColor={'#89CFF0'} /> )} diff --git a/source/components/pdp/PDPStatComponent.tsx b/source/components/pdp/PDPStatComponent.tsx index 15c468d0..4780dd23 100644 --- a/source/components/pdp/PDPStatComponent.tsx +++ b/source/components/pdp/PDPStatComponent.tsx @@ -69,7 +69,6 @@ export default function PDPStatComponent({ options }: PDPStatsProps) { )} diff --git a/source/components/ui/Table.tsx b/source/components/ui/Table.tsx index 75c4650b..6c11cc4a 100644 --- a/source/components/ui/Table.tsx +++ b/source/components/ui/Table.tsx @@ -1,25 +1,17 @@ import { useEffect, useState } from 'react'; -import Table from 'cli-table'; -import chalk from 'chalk'; import { Text } from 'ink'; import React from 'react'; const TableComponent = ({ data, headers, - headersHexColor, }: { data: object[]; headers: string[]; - headersHexColor: string; }) => { - const [table, setTable] = useState({}); + const [tableString, setTableString] = useState(''); useEffect(() => { - /* - * Build the object bases on the headers string array, the headers for now must - * be the key of the original object - maybe decouple that in the future - */ // eslint-disable-next-line @typescript-eslint/no-explicit-any let updatedRows = data.map((item: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -27,38 +19,48 @@ const TableComponent = ({ headers.map((header: string) => { row[header] = item[header]; }); - return row; }); - /* Build the table cli object, generate the headers,column width and color. */ - /* Calculate column width based on header and content length */ - const columnWidthArray = headers.map((header: string) => { - if (typeof updatedRows?.[0]?.[header] === 'string') { - if (header.length > updatedRows?.[0][header].length) { - return header.length * 2; - } - return Math.floor(updatedRows?.[0][header].length * 1.5); - } - return 8; + // Calculate column widths + const columnWidths = headers.map(header => { + const headerWidth = header.length; + const contentWidth = Math.max( + ...updatedRows.map(row => String(row[header] ?? 'Empty').length), + ); + return Math.max(headerWidth, contentWidth) + 2; + }); + + // Build table string + let tableStr = ''; + + // Headers + headers.forEach((header, i) => { + tableStr += header.padEnd(columnWidths[i] ?? 10); }); + tableStr += '\n'; - var table = new Table({ - head: headers.map(item => chalk.hex(headersHexColor)(item)), - colWidths: columnWidthArray, + // Separator + headers.forEach((_, i) => { + tableStr += '-'.repeat(columnWidths[i] ?? 10); }); - /* Add the rows to the table object */ - updatedRows.map((item: object) => { - let values = Object.values(item); - table.push(values.map(item => item ?? 'Empty')); + tableStr += '\n'; + + // Rows + updatedRows.forEach(row => { + headers.forEach((header, i) => { + const value = row[header] ?? 'Empty'; + tableStr += String(value).padEnd(columnWidths[i] ?? 10); + }); + tableStr += '\n'; }); - setTable(table); - }, [data, headers, headersHexColor]); + setTableString(tableStr); + }, [data, headers]); return ( <> - {table.toString()} + {tableString} ); }; diff --git a/source/lib/auth.ts b/source/lib/auth.ts index f1d352e8..7f316939 100644 --- a/source/lib/auth.ts +++ b/source/lib/auth.ts @@ -1,7 +1,8 @@ import { createHash, randomBytes } from 'node:crypto'; -import * as http from 'node:http'; +import { IncomingMessage, ServerResponse, createServer } from 'node:http'; import open from 'open'; -import * as pkg from 'keytar'; +import { join } from 'node:path'; +import { homedir } from 'node:os'; import { AUTH_API_URL, AUTH_PERMIT_DOMAIN, @@ -12,11 +13,47 @@ import { KEYSTORE_PERMIT_SERVICE_NAME, AUTH_PERMIT_URL, } from '../config.js'; -import { URL, URLSearchParams } from 'url'; -import { setTimeout } from 'timers'; -import { Buffer } from 'buffer'; +import { URL, URLSearchParams } from 'node:url'; +import { setTimeout } from 'node:timers'; +import { Buffer } from 'node:buffer'; +import process from 'node:process'; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'; + +const TOKEN_FILE = join(homedir(), '.permit', 'token'); +const KEY_FILE = join(homedir(), '.permit', 'key'); + +// Ensure .permit directory exists +if (!existsSync(join(homedir(), '.permit'))) { + mkdirSync(join(homedir(), '.permit'), { recursive: true }); +} -const { setPassword, getPassword, deletePassword } = pkg.default; +// Generate or load encryption key +const encryptionKey: Uint8Array = existsSync(KEY_FILE) + ? new Uint8Array(readFileSync(KEY_FILE)) + : (() => { + const key = new Uint8Array(randomBytes(32)); + writeFileSync(KEY_FILE, key); + return key; + })(); + +// Simple XOR encryption (for demonstration, in production use proper encryption) +function encrypt(text: string): string { + const textBytes = new TextEncoder().encode(text); + const encrypted = new Uint8Array(textBytes.length); + for (let i = 0; i < textBytes.length; i++) { + encrypted[i] = textBytes[i]! ^ encryptionKey[i % encryptionKey.length]!; + } + return Buffer.from(encrypted).toString('base64'); +} + +function decrypt(encrypted: string): string { + const encryptedBytes = new Uint8Array(Buffer.from(encrypted, 'base64')); + const decrypted = new Uint8Array(encryptedBytes.length); + for (let i = 0; i < encryptedBytes.length; i++) { + decrypted[i] = encryptedBytes[i]! ^ encryptionKey[i % encryptionKey.length]!; + } + return new TextDecoder().decode(decrypted); +} export enum TokenType { APIToken = 'APIToken', @@ -29,7 +66,6 @@ export const tokenType = (token: string): TokenType => { return TokenType.APIToken; } - // TBD add a better JWT validation/verification if (token.split('.').length === 3) { return TokenType.AccessToken; } @@ -44,11 +80,7 @@ export const saveAuthToken = async (token: string): Promise => { return 'Invalid auth token'; } - await setPassword( - KEYSTORE_PERMIT_SERVICE_NAME, - DEFAULT_PERMIT_KEYSTORE_ACCOUNT, - token, - ); + writeFileSync(TOKEN_FILE, encrypt(token)); return ''; } catch (error) { return error instanceof Error ? error.message : String(error); @@ -56,61 +88,59 @@ export const saveAuthToken = async (token: string): Promise => { }; export const loadAuthToken = async (): Promise => { - const token = await getPassword( - KEYSTORE_PERMIT_SERVICE_NAME, - DEFAULT_PERMIT_KEYSTORE_ACCOUNT, - ); - if (!token) { + if (!existsSync(TOKEN_FILE)) { throw new Error( 'No token found, use `permit login` command to get an auth token', ); } - return token; + const encrypted = readFileSync(TOKEN_FILE, 'utf8'); + return decrypt(encrypted); }; export const cleanAuthToken = async () => { - await deletePassword( - KEYSTORE_PERMIT_SERVICE_NAME, - DEFAULT_PERMIT_KEYSTORE_ACCOUNT, - ); + if (existsSync(TOKEN_FILE)) { + writeFileSync(TOKEN_FILE, ''); + } }; export const authCallbackServer = async (verifier: string): Promise => { return new Promise(resolve => { // Define the server logic - const server = http.createServer(async (request, res) => { - // Get the authorization code from the query string - const url = new URL(request.url!, `http://${request.headers.host}`); - if (!url.searchParams.has('code')) { - // TBD add better error handling for error callbacks + const server = createServer( + async (request: IncomingMessage, res: ServerResponse) => { + // Get the authorization code from the query string + const url = new URL(request.url!, `http://${request.headers.host}`); + if (!url.searchParams.has('code')) { + // TBD add better error handling for error callbacks + res.statusCode = 200; // Set the response status code + res.setHeader('Content-Type', 'text/plain'); // Set the content type + res.end('Authorization code not found in query string\n'); // Send the response + return; + } + + const code = url.searchParams.get('code'); + // Send the response + const data = await fetch(`${AUTH_PERMIT_URL}/oauth/token`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + grant_type: 'authorization_code', + client_id: 'Pt7rWJ4BYlpELNIdLg6Ciz7KQ2C068C1', + code_verifier: verifier, + code, + redirect_uri: AUTH_REDIRECT_URI, + }), + }).then(async response => response.json()); res.statusCode = 200; // Set the response status code res.setHeader('Content-Type', 'text/plain'); // Set the content type - res.end('Authorization code not found in query string\n'); // Send the response - return; - } - - const code = url.searchParams.get('code'); - // Send the response - const data = await fetch(`${AUTH_PERMIT_URL}/oauth/token`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - grant_type: 'authorization_code', - client_id: 'Pt7rWJ4BYlpELNIdLg6Ciz7KQ2C068C1', - code_verifier: verifier, - code, - redirect_uri: AUTH_REDIRECT_URI, - }), - }).then(async response => response.json()); - res.statusCode = 200; // Set the response status code - res.setHeader('Content-Type', 'text/plain'); // Set the content type - res.end('You can close this page now\n'); // Send the response - server.close(); // Close the server - resolve(data.access_token as string); // Resolve the promise - }); + res.end('You can close this page now\n'); // Send the response + server.close(); // Close the server + resolve(data.access_token as string); // Resolve the promise + }, + ); // Specify the port and host // Start the server and listen on the specified port diff --git a/source/lib/env/template/utils.ts b/source/lib/env/template/utils.ts index fc40527a..8a167295 100644 --- a/source/lib/env/template/utils.ts +++ b/source/lib/env/template/utils.ts @@ -1,8 +1,8 @@ -import * as fs from 'fs'; -import * as path from 'path'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; import { TERRAFORM_PERMIT_URL } from '../../../config.js'; -import { exec } from 'child_process'; -import { fileURLToPath } from 'url'; +import { exec } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; // Manually define __dirname const __filename = fileURLToPath(import.meta.url); diff --git a/tsconfig.json b/tsconfig.json index 9414ff4a..68032b2f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,19 @@ { "extends": "@sindresorhus/tsconfig", "compilerOptions": { - "jsx": "react", - "moduleResolution": "node16", - "module": "Node16", - "outDir": "dist", - "noUncheckedIndexedAccess": true, - "strict": true + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "outDir": "./dist", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "noUnusedParameters": false, + "noUnusedLocals": false, + "jsx": "react-jsx" }, - "include": ["source", "tests/components/APISyncUserComponent.test.tsx"], - "exclude": ["node_modules", "source/lib/api"] + "include": ["source/**/*"], + "exclude": ["node_modules", "dist"] }