From 4096b0dd270d9668960eba5b2d493b20992d9d96 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:26:47 -0700 Subject: [PATCH 01/81] @atsaloli has signed the CLA in withfig/autocomplete#2128 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index f1ddccc791ba..a5211c6f958a 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -935,6 +935,14 @@ "created_at": "2023-10-14T16:05:58Z", "repoId": 299482335, "pullRequestNo": 2122 + }, + { + "name": "atsaloli", + "id": 508704, + "comment_id": 1767452941, + "created_at": "2023-10-18T01:25:41Z", + "repoId": 299482335, + "pullRequestNo": 2128 } ] } \ No newline at end of file From 64b593ab230528d9dbfd217369fa7806c266ba4b Mon Sep 17 00:00:00 2001 From: Grant Gurvis Date: Wed, 18 Oct 2023 13:43:15 -0700 Subject: [PATCH 02/81] fix: svn lint --- src/svn.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/svn.ts b/src/svn.ts index ae7e9c0b002f..8300136dddd0 100644 --- a/src/svn.ts +++ b/src/svn.ts @@ -252,7 +252,6 @@ const completionSpec: Fig.Spec = { args: { name: "repository", description: "The repository you want to checkout", - isOptional: false, }, }, { From a76f4fcd4534441a715d3c9edd2aa78408f81082 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Wed, 18 Oct 2023 20:44:58 +0000 Subject: [PATCH 03/81] ci: version bump to 2.638.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d99bf7f901a..f0825b4f30f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.0", + "version": "2.638.1", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 57aa50d054e9e4d6f1d415657d4fc01b127cffb6 Mon Sep 17 00:00:00 2001 From: Eric Luce <37158449+eluce2@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:01:57 -0500 Subject: [PATCH 04/81] Supabase (#2130) --- src/supabase.ts | 153 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/src/supabase.ts b/src/supabase.ts index ca2876b91457..e6145dbd255e 100644 --- a/src/supabase.ts +++ b/src/supabase.ts @@ -87,6 +87,66 @@ const completionSpec: Fig.Spec = { }, ], }, + { + name: "dump", + description: "Dumps data or schemas from the remote database", + options: [ + { + name: "--data-only", + description: "Dumps only data records", + }, + { + name: "--db-url", + description: + "Dumps from the database specified by the connection string (must be percent-encoded)", + args: { name: "string" }, + }, + { + name: "--dry-run", + description: "Prints the pg_dump script that would be executed", + }, + { + name: ["--file", "-f"], + description: "File path to save the dumped contents", + args: { name: "string", template: "filepaths" }, + }, + { + name: ["-h", "--help"], + description: "Help for dump", + }, + { + name: "--keep-comments", + description: "Keeps commented lines from pg_dump output", + }, + { + name: "--linked", + description: "Dumps from the linked project. (default true)", + }, + { + name: "--local", + description: "Dumps from the local database", + }, + { + name: ["--password", "-p"], + description: "Password to your remote Postgres database", + args: { name: "string" }, + }, + { + name: "--role-only", + description: "Dumps only cluster roles", + }, + { + name: ["--schema", "-s"], + description: + "Comma separated list of schema to include. (default all)", + args: { name: "string" }, + }, + { + name: "--use-copy", + description: "Uses copy statements in place of inserts", + }, + ], + }, { name: "lint", description: "Checks local database for typing error", @@ -104,6 +164,7 @@ const completionSpec: Fig.Spec = { }, ], }, + { name: "pull", description: "Pull schema from the remote database" }, { name: "push", description: "Push new migrations to the remote database", @@ -259,9 +320,99 @@ const completionSpec: Fig.Spec = { description: "Password to your remote Postgres database", args: { name: "password" }, }, + { + name: "--local", + description: "Lists migrations applied to the local database", + }, + { + name: "--linked", + description: + "Lists migrations applied to the linked project (default true)", + }, + { + name: "--db-url", + description: "Database URL to connect to", + args: { name: "string" }, + }, + ], + }, + { + name: "new", + description: "Create an empty migration script", + args: { name: "migration name" }, + }, + { + name: "repair", + description: "Repair the migration history table", + args: { name: "version" }, + options: [ + { + name: "--status", + description: "Version status to update", + priority: 100, + args: { + name: "status", + suggestions: [{ name: "applied" }, { name: "reverted" }], + }, + }, + { + name: ["--password", "-p"], + description: "Password to your remote Postgres database", + args: { name: "password" }, + }, + { + name: "--local", + description: + "Repairs the migration history of the local database", + }, + { + name: "--linked", + description: + "Repairs the migration history of the linked project (default true)", + }, + { + name: "--db-url", + description: "Database URL to connect to", + args: { name: "string" }, + }, ], }, - { name: "new", description: "Create an empty migration script" }, + { + name: "squash", + description: "Squash migrations to a single file", + + options: [ + { + name: ["--password", "-p"], + description: "Password to your remote Postgres database", + args: { name: "password" }, + }, + { + name: "--local", + description: + "Squashes the migration history of the local database", + }, + { + name: "--version", + description: "Squash up to the specified version", + args: { name: "string" }, + }, + { + name: "--linked", + description: + "Squashes the migration history of the linked project (default true)", + }, + { + name: "--db-url", + description: "Database URL to connect to", + args: { name: "string" }, + }, + ], + }, + { + name: "up", + description: "Apply pending migrations to local database", + }, ], }, { From f1e840a472792ba82a0a97c12cbf171e5a6a04e7 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Wed, 18 Oct 2023 21:04:07 +0000 Subject: [PATCH 05/81] ci: version bump to 2.638.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0825b4f30f1..c006a52612b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.1", + "version": "2.638.2", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 9c96662a41ca3b3ef485bbd701f26109b8a95582 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Wed, 18 Oct 2023 15:55:08 -0700 Subject: [PATCH 06/81] @gnosticdev has signed the CLA in withfig/autocomplete#2132 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index a5211c6f958a..b0e1d38ecb49 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -943,6 +943,14 @@ "created_at": "2023-10-18T01:25:41Z", "repoId": 299482335, "pullRequestNo": 2128 + }, + { + "name": "gnosticdev", + "id": 64601257, + "comment_id": 1769526628, + "created_at": "2023-10-18T22:54:52Z", + "repoId": 299482335, + "pullRequestNo": 2132 } ] } \ No newline at end of file From b6e2b5a45af2b3944d52ce484f50ce02ea6ae321 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Thu, 19 Oct 2023 05:31:15 -0700 Subject: [PATCH 07/81] @kanersps has signed the CLA in withfig/autocomplete#2143 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index b0e1d38ecb49..d5bb1b6967b6 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -951,6 +951,14 @@ "created_at": "2023-10-18T22:54:52Z", "repoId": 299482335, "pullRequestNo": 2132 + }, + { + "name": "kanersps", + "id": 12296463, + "comment_id": 1770880076, + "created_at": "2023-10-19T12:31:02Z", + "repoId": 299482335, + "pullRequestNo": 2143 } ] } \ No newline at end of file From b0c91475e3302bf4bda6a82364d3a0e7e9d99b2d Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:01:12 -0700 Subject: [PATCH 08/81] @toddlerer has signed the CLA in withfig/autocomplete#2144 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index d5bb1b6967b6..a39551ea49c7 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -959,6 +959,14 @@ "created_at": "2023-10-19T12:31:02Z", "repoId": 299482335, "pullRequestNo": 2143 + }, + { + "name": "toddlerer", + "id": 74579078, + "comment_id": 1771549933, + "created_at": "2023-10-19T19:00:58Z", + "repoId": 299482335, + "pullRequestNo": 2144 } ] } \ No newline at end of file From f376ec1025f4c622e970d5d9bf556621129709f7 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:12:13 -0700 Subject: [PATCH 09/81] @andvvo has signed the CLA in withfig/autocomplete#2145 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index a39551ea49c7..7db5c8a95e65 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -967,6 +967,14 @@ "created_at": "2023-10-19T19:00:58Z", "repoId": 299482335, "pullRequestNo": 2144 + }, + { + "name": "andvvo", + "id": 121371226, + "comment_id": 1774213257, + "created_at": "2023-10-22T22:11:52Z", + "repoId": 299482335, + "pullRequestNo": 2145 } ] } \ No newline at end of file From 8a2a51576181152d8d1c8e07d139523a0f3f00e3 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:12:57 -0700 Subject: [PATCH 10/81] @duanhash has signed the CLA in withfig/autocomplete#2145 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 7db5c8a95e65..2192c6fc5789 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -975,6 +975,14 @@ "created_at": "2023-10-22T22:11:52Z", "repoId": 299482335, "pullRequestNo": 2145 + }, + { + "name": "duanhash", + "id": 122394349, + "comment_id": 1774213479, + "created_at": "2023-10-22T22:12:41Z", + "repoId": 299482335, + "pullRequestNo": 2145 } ] } \ No newline at end of file From 2cee27ff6d1462102d01ac278a0bc29e916e959b Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:13:15 -0700 Subject: [PATCH 11/81] @ObtuseGooose has signed the CLA in withfig/autocomplete#2145 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 2192c6fc5789..2570d22a13af 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -983,6 +983,14 @@ "created_at": "2023-10-22T22:12:41Z", "repoId": 299482335, "pullRequestNo": 2145 + }, + { + "name": "ObtuseGooose", + "id": 111467638, + "comment_id": 1774213550, + "created_at": "2023-10-22T22:12:58Z", + "repoId": 299482335, + "pullRequestNo": 2145 } ] } \ No newline at end of file From e13c1841b6ad291e7e924c20ef0bfb1460bf1314 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sun, 22 Oct 2023 18:12:13 -0700 Subject: [PATCH 12/81] @cpendery has signed the CLA in withfig/autocomplete#2146 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 2570d22a13af..5617686eaad6 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -991,6 +991,14 @@ "created_at": "2023-10-22T22:12:58Z", "repoId": 299482335, "pullRequestNo": 2145 + }, + { + "name": "cpendery", + "id": 35637443, + "comment_id": 1774273391, + "created_at": "2023-10-23T01:11:57Z", + "repoId": 299482335, + "pullRequestNo": 2146 } ] } \ No newline at end of file From 74e0ed5442e4b2bcb4a54431a615032ebb5cf484 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Thu, 26 Oct 2023 10:33:17 -0700 Subject: [PATCH 13/81] @DarkMatter-999 has signed the CLA in withfig/autocomplete#2151 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 5617686eaad6..e3f388bbe46b 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -999,6 +999,14 @@ "created_at": "2023-10-23T01:11:57Z", "repoId": 299482335, "pullRequestNo": 2146 + }, + { + "name": "DarkMatter-999", + "id": 74810454, + "comment_id": 1781548025, + "created_at": "2023-10-26T17:33:01Z", + "repoId": 299482335, + "pullRequestNo": 2151 } ] } \ No newline at end of file From 8af4bbe473bd8c8e87f0c7c1c36a5965f338a3c2 Mon Sep 17 00:00:00 2001 From: Brendan Falk Date: Thu, 26 Oct 2023 13:50:57 -0700 Subject: [PATCH 14/81] add fuzzy search to ls and remove cd folder preview --- src/cd.ts | 6 +++--- src/ls.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cd.ts b/src/cd.ts index 6f5bece56730..37cad99ec934 100644 --- a/src/cd.ts +++ b/src/cd.ts @@ -6,9 +6,9 @@ const completionSpec: Fig.Spec = { args: { generators: filepaths({ showFolders: "only", - editFolderSuggestions: { - previewComponent: "cd/folderPreview", - }, + // editFolderSuggestions: { + // previewComponent: "cd/folderPreview", + // }, }), filterStrategy: "fuzzy", // Add an additional hidden suggestion so users can execute on it if they want to diff --git a/src/ls.ts b/src/ls.ts index a9462780df8c..91afc0b75ed9 100644 --- a/src/ls.ts +++ b/src/ls.ts @@ -4,6 +4,7 @@ const completionSpec: Fig.Spec = { args: { isVariadic: true, template: ["filepaths", "folders"], + filterStrategy: "fuzzy", }, options: [ { From d31444c0380b05059919b300909735541de4b309 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Thu, 26 Oct 2023 20:52:57 +0000 Subject: [PATCH 15/81] ci: version bump to 2.638.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c006a52612b5..89cf40dc117f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.2", + "version": "2.638.3", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 3b88511321dfce8f37d7c7b898382e2cce3b3cba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:33:45 -0700 Subject: [PATCH 16/81] build(deps-dev): bump @types/react-dom from 18.2.11 to 18.2.14 (#2149) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index fcf45401cb9d..a2b2f5f746ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1432,11 +1432,11 @@ __metadata: linkType: hard "@types/react-dom@npm:^18.2.8": - version: 18.2.11 - resolution: "@types/react-dom@npm:18.2.11" + version: 18.2.14 + resolution: "@types/react-dom@npm:18.2.14" dependencies: "@types/react": "*" - checksum: 70dbdd2f8836a797ab8a3771c773f51023aab187d4d88ed3733bb3f2cbc2146057788a0095a03637101aeab9a48fce0ea369f96a35fc07e785ef53b8ab870885 + checksum: 890289c70d1966c168037637c09cacefe6205bdd27a33252144a6b432595a2943775ac1a1accac0beddaeb67f8fdf721e076acb1adc990b08e51c3d9fd4e780c languageName: node linkType: hard From 49167db0ab4205875d8232749d0c0259a1da42f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:33:54 -0700 Subject: [PATCH 17/81] build(deps): bump actions/setup-node from 3 to 4 (#2150) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/danger.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/typecheck.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index ad73b233e341..c9e45192ff94 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.x - run: yarn install --no-immutable diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cd703febcb19..d820bce35770 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.x - run: yarn install --no-immutable diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 2912d1c90940..7f2fb3bd8044 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 14.x - run: yarn install --no-immutable From e57fdeabf9d86d193eb731f59bfa1408f65de4be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:34:09 -0700 Subject: [PATCH 18/81] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.7.3 to 6.8.0 (#2148) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 177 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 130 insertions(+), 47 deletions(-) diff --git a/yarn.lock b/yarn.lock index a2b2f5f746ad..112dd4bf8072 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1482,15 +1482,15 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.23.0": - version: 5.59.7 - resolution: "@typescript-eslint/eslint-plugin@npm:5.59.7" + version: 5.62.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.59.7 - "@typescript-eslint/type-utils": 5.59.7 - "@typescript-eslint/utils": 5.59.7 + "@typescript-eslint/scope-manager": 5.62.0 + "@typescript-eslint/type-utils": 5.62.0 + "@typescript-eslint/utils": 5.62.0 debug: ^4.3.4 - grapheme-splitter: ^1.0.4 + graphemer: ^1.4.0 ignore: ^5.2.0 natural-compare-lite: ^1.4.0 semver: ^7.3.7 @@ -1501,19 +1501,19 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10d28bac7a5af9e41767be0bb9c270ee3dcdfeaa38d1b036c6822e7260b88821c460699ba943664eb1ef272d00de6a81b99d7d955332044ea87b624e7ead84a1 + checksum: fc104b389c768f9fa7d45a48c86d5c1ad522c1d0512943e782a56b1e3096b2cbcc1eea3fcc590647bf0658eef61aac35120a9c6daf979bf629ad2956deb516a1 languageName: node linkType: hard "@typescript-eslint/eslint-plugin@npm:^6.7.3": - version: 6.7.3 - resolution: "@typescript-eslint/eslint-plugin@npm:6.7.3" + version: 6.8.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.8.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.7.3 - "@typescript-eslint/type-utils": 6.7.3 - "@typescript-eslint/utils": 6.7.3 - "@typescript-eslint/visitor-keys": 6.7.3 + "@typescript-eslint/scope-manager": 6.8.0 + "@typescript-eslint/type-utils": 6.8.0 + "@typescript-eslint/utils": 6.8.0 + "@typescript-eslint/visitor-keys": 6.8.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -1526,7 +1526,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ac2790882199047abc59c0407a862f3339645623d03ea0aae5a73fd4bac6abfb753afcf9f23fd51cd1d5aa73f132ef94e2850774c4b2a3d99ebb83030b09429c + checksum: c36ccf606ebcaff8263c4ffa3b4cda58c6f93474b9eea9906e51be2fef8596977a245cc13770b21c6bfd38ccf45a3cf3613d5f4499429f62ec80afe15ae345bd languageName: node linkType: hard @@ -1575,6 +1575,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/scope-manager@npm:5.62.0" + dependencies: + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/visitor-keys": 5.62.0 + checksum: 6062d6b797fe1ce4d275bb0d17204c827494af59b5eaf09d8a78cdd39dadddb31074dded4297aaf5d0f839016d601032857698b0e4516c86a41207de606e9573 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/scope-manager@npm:6.7.3" @@ -1585,12 +1595,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/type-utils@npm:5.59.7" +"@typescript-eslint/scope-manager@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/scope-manager@npm:6.8.0" dependencies: - "@typescript-eslint/typescript-estree": 5.59.7 - "@typescript-eslint/utils": 5.59.7 + "@typescript-eslint/types": 6.8.0 + "@typescript-eslint/visitor-keys": 6.8.0 + checksum: b6cf2803531d1c14b56c30fd3cd807b80e17fe48d0da8e5aa9ae50915407ed732c7e2a7ac8030b7cf8ed07b8e481a1138d76bf05b727837a0e016280c2f6873b + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/type-utils@npm:5.62.0" + dependencies: + "@typescript-eslint/typescript-estree": 5.62.0 + "@typescript-eslint/utils": 5.62.0 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -1598,16 +1618,16 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9cbeffad27b145b478e4cbbab2b44c5b246a9b922f01fd06d401ea4c41a4fa6dc8ba75d13a6409b3b4474ccaf2018770a4c6c599172e22ec2004110e00f4e721 + checksum: fc41eece5f315dfda14320be0da78d3a971d650ea41300be7196934b9715f3fe1120a80207551eb71d39568275dbbcf359bde540d1ca1439d8be15e9885d2739 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.7.3": - version: 6.7.3 - resolution: "@typescript-eslint/type-utils@npm:6.7.3" +"@typescript-eslint/type-utils@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/type-utils@npm:6.8.0" dependencies: - "@typescript-eslint/typescript-estree": 6.7.3 - "@typescript-eslint/utils": 6.7.3 + "@typescript-eslint/typescript-estree": 6.8.0 + "@typescript-eslint/utils": 6.8.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -1615,7 +1635,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f30a5ab4f88f76457810d72e3ada79fefd94dbbb456069ac004bd7601c9b7f15689b906b66cd849c230f30ae65f6f7039fb169609177ab545b34bacab64f015e + checksum: 9b7d56904dc1a5719ef79eb1b7989d6fad10c71fb07ec3e66cf69b8c8dc5383d644ab122d4701bc4960fb7c99cc08aee4e645db3e4675d488d5779197e15dfda languageName: node linkType: hard @@ -1626,6 +1646,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/types@npm:5.62.0" + checksum: 48c87117383d1864766486f24de34086155532b070f6264e09d0e6139449270f8a9559cfef3c56d16e3bcfb52d83d42105d61b36743626399c7c2b5e0ac3b670 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/types@npm:6.7.3" @@ -1633,6 +1660,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/types@npm:6.8.0" + checksum: 1fcd85f6d575116d51c6ee757ed37610ae5e7e4296a29f93c9c6949f6cd16d24550eb7fc5bae7a43119cc08e13836f69a7ae7c54ebba6c95aef96b34d3bfb7f7 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.59.7": version: 5.59.7 resolution: "@typescript-eslint/typescript-estree@npm:5.59.7" @@ -1651,6 +1685,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" + dependencies: + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/visitor-keys": 5.62.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 3624520abb5807ed8f57b1197e61c7b1ed770c56dfcaca66372d584ff50175225798bccb701f7ef129d62c5989070e1ee3a0aa2d84e56d9524dcf011a2bb1a52 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/typescript-estree@npm:6.7.3" @@ -1669,38 +1721,56 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.59.7": - version: 5.59.7 - resolution: "@typescript-eslint/utils@npm:5.59.7" +"@typescript-eslint/typescript-estree@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.8.0" + dependencies: + "@typescript-eslint/types": 6.8.0 + "@typescript-eslint/visitor-keys": 6.8.0 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.5.4 + ts-api-utils: ^1.0.1 + peerDependenciesMeta: + typescript: + optional: true + checksum: 388db7f33ef1bc0e7b960c0bce9c744c2e32c66c7ab8dfae73d8533958202ad6f31663b0010f79c45b5ff93159c67f45b00693d73b9da2472b17156dfd26b4a8 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/utils@npm:5.62.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.59.7 - "@typescript-eslint/types": 5.59.7 - "@typescript-eslint/typescript-estree": 5.59.7 + "@typescript-eslint/scope-manager": 5.62.0 + "@typescript-eslint/types": 5.62.0 + "@typescript-eslint/typescript-estree": 5.62.0 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: d8682700187ca94cc6441480cb6b87d0514a9748103c15dd93206c5b1c6fefa59063662f27a4103e16abbcfb654a61d479bc55af8f23d96f342431b87f31bb4e + checksum: ee9398c8c5db6d1da09463ca7bf36ed134361e20131ea354b2da16a5fdb6df9ba70c62a388d19f6eebb421af1786dbbd79ba95ddd6ab287324fc171c3e28d931 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.7.3": - version: 6.7.3 - resolution: "@typescript-eslint/utils@npm:6.7.3" +"@typescript-eslint/utils@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/utils@npm:6.8.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.7.3 - "@typescript-eslint/types": 6.7.3 - "@typescript-eslint/typescript-estree": 6.7.3 + "@typescript-eslint/scope-manager": 6.8.0 + "@typescript-eslint/types": 6.8.0 + "@typescript-eslint/typescript-estree": 6.8.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 685b7c9fa95ad085f30e26431dc41b3059a42a16925defe2a94b32fb46974bfc168000de7d4d9ad4a1d0568a983f9d3c01ea6bc6cfa9a798e482719af9e9165b + checksum: 6d9f90db504502a9aa10e834830c3ffa25483757414670acc6141a3ebef9171a57688a3a179febf35a0e1e0b322f37228d9537bf1b279f1af7fc97888b873bc3 languageName: node linkType: hard @@ -1714,6 +1784,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" + dependencies: + "@typescript-eslint/types": 5.62.0 + eslint-visitor-keys: ^3.3.0 + checksum: 976b05d103fe8335bef5c93ad3f76d781e3ce50329c0243ee0f00c0fcfb186c81df50e64bfdd34970148113f8ade90887f53e3c4938183afba830b4ba8e30a35 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/visitor-keys@npm:6.7.3" @@ -1724,6 +1804,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:6.8.0": + version: 6.8.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.8.0" + dependencies: + "@typescript-eslint/types": 6.8.0 + eslint-visitor-keys: ^3.4.1 + checksum: 710d9067b85d7715a400ae625c083c41733abb891d7b35108de083913980f9642e79d27689599fa39915f0fecae16dbfc30367007fccc838ccd917943660de22 + languageName: node + linkType: hard + "@vitejs/plugin-react@npm:^4.1.0": version: 4.1.0 resolution: "@vitejs/plugin-react@npm:4.1.0" @@ -4292,13 +4382,6 @@ __metadata: languageName: node linkType: hard -"grapheme-splitter@npm:^1.0.4": - version: 1.0.4 - resolution: "grapheme-splitter@npm:1.0.4" - checksum: 0c22ec54dee1b05cd480f78cf14f732cb5b108edc073572c4ec205df4cd63f30f8db8025afc5debc8835a8ddeacf648a1c7992fe3dcd6ad38f9a476d84906620 - languageName: node - linkType: hard - "graphemer@npm:^1.4.0": version: 1.4.0 resolution: "graphemer@npm:1.4.0" From 81d70a81aca3c406f2f9675e9515d3840c5d94d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:34:22 -0700 Subject: [PATCH 19/81] build(deps-dev): bump lint-staged from 14.0.1 to 15.0.2 (#2147) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 85 +++++++++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 89cf40dc117f..4bd3fa2162a3 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "express": "^4.18.2", "glob": "^10.3.10", "husky": "^8.0.3", - "lint-staged": "^14.0.1", + "lint-staged": "^15.0.2", "postcss": "^8.4.31", "prettier": "^3.0.3", "pretty-quick": "^3.1.3", diff --git a/yarn.lock b/yarn.lock index 112dd4bf8072..e4033fe66a2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1908,7 +1908,7 @@ __metadata: express: ^4.18.2 glob: ^10.3.10 husky: ^8.0.3 - lint-staged: ^14.0.1 + lint-staged: ^15.0.2 postcss: ^8.4.31 prettier: ^3.0.3 pretty-quick: ^3.1.3 @@ -2602,10 +2602,10 @@ __metadata: languageName: node linkType: hard -"commander@npm:11.0.0": - version: 11.0.0 - resolution: "commander@npm:11.0.0" - checksum: 6621954e1e1d078b4991c1f5bbd9439ad37aa7768d6ab4842de1dbd4d222c8a27e1b8e62108b3a92988614af45031d5bb2a2aaa92951f4d0c934d1a1ac564bb4 +"commander@npm:11.1.0": + version: 11.1.0 + resolution: "commander@npm:11.1.0" + checksum: fd1a8557c6b5b622c89ecdfde703242ab7db3b628ea5d1755784c79b8e7cb0d74d65b4a262289b533359cd58e1bfc0bf50245dfbcd2954682a6f367c828b79ef languageName: node linkType: hard @@ -3839,20 +3839,20 @@ __metadata: languageName: node linkType: hard -"execa@npm:7.2.0": - version: 7.2.0 - resolution: "execa@npm:7.2.0" +"execa@npm:8.0.1": + version: 8.0.1 + resolution: "execa@npm:8.0.1" dependencies: cross-spawn: ^7.0.3 - get-stream: ^6.0.1 - human-signals: ^4.3.0 + get-stream: ^8.0.1 + human-signals: ^5.0.0 is-stream: ^3.0.0 merge-stream: ^2.0.0 npm-run-path: ^5.1.0 onetime: ^6.0.0 - signal-exit: ^3.0.7 + signal-exit: ^4.1.0 strip-final-newline: ^3.0.0 - checksum: 14fd17ba0ca8c87b277584d93b1d9fc24f2a65e5152b31d5eb159a3b814854283eaae5f51efa9525e304447e2f757c691877f7adff8fde5746aae67eb1edd1cc + checksum: cac1bf86589d1d9b73bdc5dda65c52012d1a9619c44c526891956745f7b366ca2603d29fe3f7460bacc2b48c6eab5d6a4f7afe0534b31473d3708d1265545e1f languageName: node linkType: hard @@ -4234,10 +4234,10 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^6.0.1": - version: 6.0.1 - resolution: "get-stream@npm:6.0.1" - checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad +"get-stream@npm:^8.0.1": + version: 8.0.1 + resolution: "get-stream@npm:8.0.1" + checksum: 01e3d3cf29e1393f05f44d2f00445c5f9ec3d1c49e8179b31795484b9c117f4c695e5e07b88b50785d5c8248a788c85d9913a79266fc77e3ef11f78f10f1b974 languageName: node linkType: hard @@ -4507,10 +4507,10 @@ __metadata: languageName: node linkType: hard -"human-signals@npm:^4.3.0": - version: 4.3.1 - resolution: "human-signals@npm:4.3.1" - checksum: 6f12958df3f21b6fdaf02d90896c271df00636a31e2bbea05bddf817a35c66b38a6fdac5863e2df85bd52f34958997f1f50350ff97249e1dff8452865d5235d1 +"human-signals@npm:^5.0.0": + version: 5.0.0 + resolution: "human-signals@npm:5.0.0" + checksum: 6504560d5ed91444f16bea3bd9dfc66110a339442084e56c3e7fa7bbdf3f406426d6563d662bdce67064b165eac31eeabfc0857ed170aaa612cf14ec9f9a464c languageName: node linkType: hard @@ -4916,29 +4916,29 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^14.0.1": - version: 14.0.1 - resolution: "lint-staged@npm:14.0.1" +"lint-staged@npm:^15.0.2": + version: 15.0.2 + resolution: "lint-staged@npm:15.0.2" dependencies: chalk: 5.3.0 - commander: 11.0.0 + commander: 11.1.0 debug: 4.3.4 - execa: 7.2.0 + execa: 8.0.1 lilconfig: 2.1.0 - listr2: 6.6.1 + listr2: 7.0.2 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.1 + yaml: 2.3.3 bin: lint-staged: bin/lint-staged.js - checksum: 8c5d740cb3c90fab2d970fa6bbffe5ddf35ec66ed374a52caf3a3cf83d8f4d5fd01a949994822bce5ea18c0b8dc8fa4ce087ef886a8c11db674139a063cdfe4f + checksum: 437bc006a103eda779584b0beccef03732d1e79fe3c5d66004fee0ba641b2defe81ed8f7b4909fd1b4c59a7b7e2587d811dcc3a2e171f95573976af4294da9fc languageName: node linkType: hard -"listr2@npm:6.6.1": - version: 6.6.1 - resolution: "listr2@npm:6.6.1" +"listr2@npm:7.0.2": + version: 7.0.2 + resolution: "listr2@npm:7.0.2" dependencies: cli-truncate: ^3.1.0 colorette: ^2.0.20 @@ -4946,12 +4946,7 @@ __metadata: log-update: ^5.0.1 rfdc: ^1.3.0 wrap-ansi: ^8.1.0 - peerDependencies: - enquirer: ">= 2.3.0 < 3" - peerDependenciesMeta: - enquirer: - optional: true - checksum: 99600e8a51f838f7208bce7e16d6b3d91d361f13881e6aa91d0b561a9a093ddcf63b7bc2a7b47aec7fdbff9d0e8c9f68cb66e6dfe2d857e5b1df8ab045c26ce8 + checksum: 1734c6b9367ceeb09bf372427930a4586b3727097373408f2f840896b9333cc80e53a1a696771a83a7d4d9ada46229843f3052b87f3b0b58c20e9451362c2dd3 languageName: node linkType: hard @@ -6641,6 +6636,13 @@ __metadata: languageName: node linkType: hard +"signal-exit@npm:^4.1.0": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 64c757b498cb8629ffa5f75485340594d2f8189e9b08700e69199069c8e3070fb3e255f7ab873c05dc0b3cec412aea7402e10a5990cb6a050bd33ba062a6c549 + languageName: node + linkType: hard + "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -7412,7 +7414,14 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.3.1, yaml@npm:^2.1.1": +"yaml@npm:2.3.3": + version: 2.3.3 + resolution: "yaml@npm:2.3.3" + checksum: cdfd132e7e0259f948929efe8835923df05c013c273c02bb7a2de9b46ac3af53c2778a35b32c7c0f877cc355dc9340ed564018c0242bfbb1278c2a3e53a0e99e + languageName: node + linkType: hard + +"yaml@npm:^2.1.1": version: 2.3.1 resolution: "yaml@npm:2.3.1" checksum: 2c7bc9a7cd4c9f40d3b0b0a98e370781b68b8b7c4515720869aced2b00d92f5da1762b4ffa947f9e795d6cd6b19f410bd4d15fdd38aca7bd96df59bd9486fb54 From 41d9060e2c588e1aed09a285f25a52cb6c7a6899 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:34:39 -0700 Subject: [PATCH 20/81] build(deps): bump JS-DevTools/npm-publish from 2 to 3 (#2133) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 98154bd3f400..5e06587eb56d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: with: skip-tag: 'true' - name: Publish to npm - uses: JS-DevTools/npm-publish@v2 + uses: JS-DevTools/npm-publish@v3 with: access: public token: ${{ secrets.NPM_PUBLISH_TOKEN }} From 1f58d65ce5816e24c1d7fa8c5e2beb8be6f84c1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:34:52 -0700 Subject: [PATCH 21/81] build(deps): bump @babel/traverse from 7.23.0 to 7.23.2 (#2129) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index e4033fe66a2b..4fa47b118811 100644 --- a/yarn.lock +++ b/yarn.lock @@ -276,8 +276,8 @@ __metadata: linkType: hard "@babel/traverse@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/traverse@npm:7.23.0" + version: 7.23.2 + resolution: "@babel/traverse@npm:7.23.2" dependencies: "@babel/code-frame": ^7.22.13 "@babel/generator": ^7.23.0 @@ -289,7 +289,7 @@ __metadata: "@babel/types": ^7.23.0 debug: ^4.1.0 globals: ^11.1.0 - checksum: 0b17fae53269e1af2cd3edba00892bc2975ad5df9eea7b84815dab07dfec2928c451066d51bc65b4be61d8499e77db7e547ce69ef2a7b0eca3f96269cb43a0b0 + checksum: 26a1eea0dde41ab99dde8b9773a013a0dc50324e5110a049f5d634e721ff08afffd54940b3974a20308d7952085ac769689369e9127dea655f868c0f6e1ab35d languageName: node linkType: hard From 8e1616c41636ade921ee538cfbe6f689548c010a Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Fri, 27 Oct 2023 14:36:39 -0700 Subject: [PATCH 22/81] spec(create-redwood-app): Add spec for create-redwood-app (#2138) --- src/create-redwood-app.ts | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/create-redwood-app.ts diff --git a/src/create-redwood-app.ts b/src/create-redwood-app.ts new file mode 100644 index 000000000000..557710189742 --- /dev/null +++ b/src/create-redwood-app.ts @@ -0,0 +1,39 @@ +const spec: Fig.Spec = { + name: "create-redwood-app", + icon: "https://avatars.githubusercontent.com/u/45050444?s=48&v=4", + args: { + name: "projectName", + description: "Name of your Redwood project", + }, + options: [ + { name: ["--help", "-h"], description: "Show help" }, + { + name: ["--typescript", "--ts"], + description: "Generate a TypeScript project", + }, + { + name: "--overwrite", + description: "Create even if target directory isn't empty", + }, + { + name: "--telemetry", + description: "Enables sending telemetry events for this create", + }, + { + name: ["--git-init", "--git"], + description: "Initialize a git repository", + }, + { + name: ["--commit-message", "-m"], + description: "Commit message for the initial commit", + }, + { name: ["--yes", "-y"], description: "Skip prompts and use defaults" }, + { name: "--version", description: "Show version number" }, + { + name: "--yarn-install", + description: "Install node modules. Skip via --no-yarn-install", + }, + ], +}; + +export default spec; From 2690bdebad67a647cc7f708476f6c45065782e10 Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Fri, 27 Oct 2023 14:37:03 -0700 Subject: [PATCH 23/81] spec(rails): Add rails icon (#2137) --- src/rails.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rails.ts b/src/rails.ts index 9000d654efc9..f35895a3b23f 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -629,6 +629,7 @@ export const railsCommandsGenerator: Fig.Generator = { const completionSpec: Fig.Spec = { name: "rails", description: "Ruby on Rails CLI", + icon: "https://avatars.githubusercontent.com/u/4223?s=48&v=4", generateSpec: async (_, executeShellCommand) => { const isRailsDirectory = !!(await executeShellCommand( `until [[ -f Gemfile ]] || [[ $PWD = '/' ]]; do cd ..; done; if [ -f Gemfile ]; then cat Gemfile | \\grep "gem ['\\"]rails['\\"]"; fi` From 6c13c6025176760e1e8dc428dd4198fc015241d4 Mon Sep 17 00:00:00 2001 From: Lakshyajeet Singh Goyal <74810454+DarkMatter-999@users.noreply.github.com> Date: Sat, 28 Oct 2023 03:08:30 +0530 Subject: [PATCH 24/81] feat: Added dpkg spec (#2151) --- src/dpkg.ts | 311 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 src/dpkg.ts diff --git a/src/dpkg.ts b/src/dpkg.ts new file mode 100644 index 000000000000..932df1eb1edb --- /dev/null +++ b/src/dpkg.ts @@ -0,0 +1,311 @@ +const completionSpec: Fig.Spec = { + name: "dpkg", + description: "Debian package management system", + subcommands: [ + { + name: "query", + description: "Query the dpkg database", + options: [ + { + name: ["-l", "--list"], + description: "List packages matching a pattern", + args: { name: "pattern" }, + }, + { + name: ["-s", "--status"], + description: "Display the status of available packages", + args: { name: "package" }, + }, + { + name: ["-L", "--listfiles"], + description: "List files in a package", + args: { name: "package" }, + }, + { + name: ["-S", "--search"], + description: "Search for a package owning a file", + args: { name: "file" }, + }, + { + name: ["-p", "--print-avail"], + description: "Display details about a package in the dpkg database", + args: { name: "package" }, + }, + { + name: ["-W", "--show"], + description: "Show a package in the dpkg database", + args: { name: "package" }, + }, + ], + }, + { + name: "install", + description: "Install or upgrade packages", + args: { name: "package" }, + options: [ + { + name: ["-R", "--recursive"], + description: "Recursively handle packages", + }, + { + name: ["-B", "--auto-deconfigure"], + description: "Uninstall packages that depend on the target package", + }, + { + name: ["--skip-same-version"], + description: "Don't upgrade if the same version is already installed", + }, + { + name: ["--force-depends"], + description: "Ignore dependency problems", + }, + { + name: ["--force-confnew"], + description: "Always install the new version of configuration files", + }, + { + name: ["--force-confold"], + description: "Always install the old version of configuration files", + }, + { + name: ["--force-confdef"], + description: "Always install the default version of configuration files", + }, + { + name: ["--force-confmiss"], + description: "Always install missing configuration files", + }, + { + name: ["--no-triggers"], + description: "Skip processing triggers", + }, + { + name: ["--no-act"], + description: "Simulate the action, but don't execute", + }, + ], + }, + { + name: "remove", + description: "Remove packages", + args: { name: "package" }, + options: [ + { + name: ["-R", "--recursive"], + description: "Recursively remove packages", + }, + { + name: ["-B", "--auto-deconfigure"], + description: "Uninstall packages that depend on the target package", + }, + { + name: ["--no-act"], + description: "Simulate the action, but don't execute", + }, + ], + }, + { + name: "purge", + description: "Remove packages and their configuration files", + args: { name: "package" }, + options: [ + { + name: ["-R", "--recursive"], + description: "Recursively remove packages", + }, + { + name: ["--no-act"], + description: "Simulate the action, but don't execute", + }, + ], + }, + { + name: "configure", + description: "Configure a package after installation", + args: { name: "package" }, + options: [ + { + name: ["--pending"], + description: "Configure all unconfigured packages", + }, + { + name: ["--no-triggers"], + description: "Skip processing triggers", + }, + { + name: ["--no-act"], + description: "Simulate the action, but don't execute", + }, + ], + }, + { + name: "reconfigure", + description: "Reconfigure a package", + args: { name: "package" }, + options: [ + { + name: ["--no-triggers"], + description: "Skip processing triggers", + }, + { + name: ["--no-act"], + description: "Simulate the action, but don't execute", + }, + ], + }, + { + name: "list", + description: "List packages in the dpkg database", + options: [ + { + name: ["-l", "--list"], + description: "List packages matching a pattern", + args: { name: "pattern" }, + }, + { + name: ["-s", "--status"], + description: "Display the status of available packages", + args: { name: "package" }, + }, + { + name: ["-L", "--listfiles"], + description: "List files in a package", + args: { name: "package" }, + }, + { + name: ["-S", "--search"], + description: "Search for a package owning a file", + args: { name: "file" }, + }, + { + name: ["-p", "--print-avail"], + description: "Display details about a package in the dpkg database", + args: { name: "package" }, + }, + { + name: ["-W", "--show"], + description: "Show a package in the dpkg database", + args: { name: "package" }, + }, + { + name: ["--installed"], + description: "List installed packages", + }, + { + name: ["--avail"], + description: "List available packages", + }, + { + name: ["--hold"], + description: "List packages on hold", + }, + { + name: ["--deferred"], + description: "List deferred packages", + }, + ], + }, + { + name: "builddeb", + description: "Build Debian package files from sources", + args: { name: "directory" }, + options: [ + { + name: ["-us", "--unsigned"], + description: "Build unsigned .changes and .dsc files", + }, + { + name: ["-uc", "--unsigned-changes"], + description: "Build unsigned .changes file", + }, + { + name: ["-sa", "--source"], + description: "Build source package", + }, + { + name: ["-rfakeroot"], + description: "Use fakeroot when building the package", + }, + { + name: ["-b", "--binary"], + description: "Build binary package from source", + }, + { + name: ["--force-sign"], + description: "Force signing of changes file", + }, + { + name: ["-m", "--maintainer"], + description: "Specify the package maintainer", + args: { name: "email" }, + }, + { + name: ["-c", "--changes"], + description: "Specify the changes file to use", + args: { name: "file" }, + }, + { + name: ["-v", "--version"], + description: "Specify the version to use", + args: { name: "version" }, + }, + { + name: ["--increment"], + description: "Increment the version number in the changelog", + }, + ], + }, + { + name: "check", + description: "Check the dependencies of packages", + args: { + name: "package", + isOptional: true, + }, + options: [ + { + name: ["-a", "--all"], + description: "Check all installed packages", + }, + { + name: ["-d", "--unmet"], + description: "Check for unmet dependencies", + }, + { + name: ["-i", "--check-installed"], + description: "Check installed packages", + }, + { + name: ["-U", "--check-unpacked"], + description: "Check unpacked packages", + }, + { + name: ["-c", "--nocheck"], + description: "Skip checking for broken dependencies", + }, + { + name: ["-r", "--reverse"], + description: "Check reverse dependencies", + }, + ], + }, + { + name: "compare-versions", + description: "Compare package versions", + args: [ + { name: "version1" }, + { name: "relation", isOptional: true, suggestions: ["lt", "le", "eq", "ne", "gt", "ge"] }, + { name: "version2" }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Help for dpkg", + }, + ], +}; + +export default completionSpec; + From 457a47fdf6b052d964cceeb92e84d191d47541e6 Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Fri, 27 Oct 2023 14:39:08 -0700 Subject: [PATCH 25/81] spec(rake): Add task generator to rake (#2136) --- src/rake.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/rake.ts b/src/rake.ts index 8dbc7d3edd26..f525172aa0f0 100644 --- a/src/rake.ts +++ b/src/rake.ts @@ -1,10 +1,28 @@ const completionSpec: Fig.Spec = { name: "rake", description: "A ruby build program with capabilities similar to make", + icon: "https://avatars.githubusercontent.com/u/210414?s=48&v=4", args: { name: "targets", isVariadic: true, isOptional: true, + generators: { + script: "rake --tasks --silent", + cache: { + strategy: "stale-while-revalidate", + cacheByDirectory: true, + }, + postProcess: function (out) { + return out.split("\n").map((line) => { + const [name, description] = line.split("#"); + + return { + name: name.trim().slice("rake ".length), + description: description.trim(), + }; + }); + }, + }, }, options: [ { From 52c87a3256dcf522a7c780f44ccc0e4922303583 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 21:40:47 +0000 Subject: [PATCH 26/81] ci: version bump to 2.638.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4bd3fa2162a3..cffb2d3542c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.3", + "version": "2.638.4", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From dba0cc23bc8df4e9a9ac813ae053a9306876f26f Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Fri, 27 Oct 2023 14:44:29 -0700 Subject: [PATCH 27/81] spec(git): Add remote generators + remove console.log (#2134) --- src/git.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/git.ts b/src/git.ts index c349ef7c612b..f4921d492c8b 100644 --- a/src/git.ts +++ b/src/git.ts @@ -50,6 +50,7 @@ const postProcessTrackedFiles: Fig.Generator["postProcess"] = ( interface PostProcessBranchesOptions { insertWithoutRemotes?: true; } + const postProcessBranches = (options: PostProcessBranchesOptions = {}): Fig.Generator["postProcess"] => (out) => { @@ -269,7 +270,6 @@ export const gitGenerators: Record = { const remoteURLs = out.split("\n").reduce((dict, line) => { const pair = line.split("\t"); const remote = pair[0]; - console.log(remote, pair); const url = pair[1].split(" ")[0]; dict[remote] = url; @@ -6312,6 +6312,8 @@ const completionSpec: Fig.Spec = { args: [ { name: "name", + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, { name: "branch", @@ -6345,6 +6347,8 @@ const completionSpec: Fig.Spec = { args: [ { name: "name", + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, { name: "branch", @@ -6390,6 +6394,8 @@ const completionSpec: Fig.Spec = { ], args: { name: "name", + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, }, { @@ -6398,6 +6404,8 @@ const completionSpec: Fig.Spec = { args: [ { name: "name", + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, { name: "newurl", @@ -6430,6 +6438,8 @@ const completionSpec: Fig.Spec = { args: { name: "name", isVariadic: true, + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, options: [ { @@ -6446,6 +6456,8 @@ const completionSpec: Fig.Spec = { args: { name: "name", isVariadic: true, + generators: gitGenerators.remotes, + filterStrategy: "fuzzy", }, options: [ { From 8751a5143c7091dcd307e09cab50873985724508 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 21:46:18 +0000 Subject: [PATCH 28/81] ci: version bump to 2.638.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cffb2d3542c2..cc74b868de28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.4", + "version": "2.638.5", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From ae375ca85db9d43042dfea779430b8f949d157e8 Mon Sep 17 00:00:00 2001 From: Grant Gurvis Date: Fri, 27 Oct 2023 14:47:36 -0700 Subject: [PATCH 29/81] fix(dpkg): lints --- src/dpkg.ts | 54 ++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/dpkg.ts b/src/dpkg.ts index 932df1eb1edb..1d5c146d3528 100644 --- a/src/dpkg.ts +++ b/src/dpkg.ts @@ -52,35 +52,36 @@ const completionSpec: Fig.Spec = { description: "Uninstall packages that depend on the target package", }, { - name: ["--skip-same-version"], + name: "--skip-same-version", description: "Don't upgrade if the same version is already installed", }, { - name: ["--force-depends"], + name: "--force-depends", description: "Ignore dependency problems", }, { - name: ["--force-confnew"], + name: "--force-confnew", description: "Always install the new version of configuration files", }, { - name: ["--force-confold"], + name: "--force-confold", description: "Always install the old version of configuration files", }, { - name: ["--force-confdef"], - description: "Always install the default version of configuration files", + name: "--force-confdef", + description: + "Always install the default version of configuration files", }, { - name: ["--force-confmiss"], + name: "--force-confmiss", description: "Always install missing configuration files", }, { - name: ["--no-triggers"], + name: "--no-triggers", description: "Skip processing triggers", }, { - name: ["--no-act"], + name: "--no-act", description: "Simulate the action, but don't execute", }, ], @@ -99,7 +100,7 @@ const completionSpec: Fig.Spec = { description: "Uninstall packages that depend on the target package", }, { - name: ["--no-act"], + name: "--no-act", description: "Simulate the action, but don't execute", }, ], @@ -114,7 +115,7 @@ const completionSpec: Fig.Spec = { description: "Recursively remove packages", }, { - name: ["--no-act"], + name: "--no-act", description: "Simulate the action, but don't execute", }, ], @@ -125,15 +126,15 @@ const completionSpec: Fig.Spec = { args: { name: "package" }, options: [ { - name: ["--pending"], + name: "--pending", description: "Configure all unconfigured packages", }, { - name: ["--no-triggers"], + name: "--no-triggers", description: "Skip processing triggers", }, { - name: ["--no-act"], + name: "--no-act", description: "Simulate the action, but don't execute", }, ], @@ -144,11 +145,11 @@ const completionSpec: Fig.Spec = { args: { name: "package" }, options: [ { - name: ["--no-triggers"], + name: "--no-triggers", description: "Skip processing triggers", }, { - name: ["--no-act"], + name: "--no-act", description: "Simulate the action, but don't execute", }, ], @@ -188,19 +189,19 @@ const completionSpec: Fig.Spec = { args: { name: "package" }, }, { - name: ["--installed"], + name: "--installed", description: "List installed packages", }, { - name: ["--avail"], + name: "--avail", description: "List available packages", }, { - name: ["--hold"], + name: "--hold", description: "List packages on hold", }, { - name: ["--deferred"], + name: "--deferred", description: "List deferred packages", }, ], @@ -223,7 +224,7 @@ const completionSpec: Fig.Spec = { description: "Build source package", }, { - name: ["-rfakeroot"], + name: "-rfakeroot", description: "Use fakeroot when building the package", }, { @@ -231,7 +232,7 @@ const completionSpec: Fig.Spec = { description: "Build binary package from source", }, { - name: ["--force-sign"], + name: "--force-sign", description: "Force signing of changes file", }, { @@ -250,7 +251,7 @@ const completionSpec: Fig.Spec = { args: { name: "version" }, }, { - name: ["--increment"], + name: "--increment", description: "Increment the version number in the changelog", }, ], @@ -294,7 +295,11 @@ const completionSpec: Fig.Spec = { description: "Compare package versions", args: [ { name: "version1" }, - { name: "relation", isOptional: true, suggestions: ["lt", "le", "eq", "ne", "gt", "ge"] }, + { + name: "relation", + isOptional: true, + suggestions: ["lt", "le", "eq", "ne", "gt", "ge"], + }, { name: "version2" }, ], }, @@ -308,4 +313,3 @@ const completionSpec: Fig.Spec = { }; export default completionSpec; - From 14728a11e38f6f05418a074b6aa1e14ab7ca3c6e Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 21:49:20 +0000 Subject: [PATCH 30/81] ci: version bump to 2.638.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc74b868de28..533cbba91cbe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.5", + "version": "2.638.6", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 64dc6757f968adea85a98b750bbf73fca3c00f74 Mon Sep 17 00:00:00 2001 From: Andy Vo <121371226+andvvo@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:02:02 -0700 Subject: [PATCH 31/81] spec(pijul): Add pijul spec (#2145) Co-authored-by: Duan Chen Co-authored-by: duanhash <122394349+duanhash@users.noreply.github.com> Co-authored-by: ObtuseGooose --- src/pijul.ts | 837 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 837 insertions(+) create mode 100644 src/pijul.ts diff --git a/src/pijul.ts b/src/pijul.ts new file mode 100644 index 000000000000..5cab74f234c5 --- /dev/null +++ b/src/pijul.ts @@ -0,0 +1,837 @@ +const completionSpec: Fig.Spec = { + name: "pijul", + description: + "A distributed version control system that is at the same time theoretically sound, fast and easy to learn and use", + subcommands: [ + { + name: "add", + description: "Adds a path to the tree", + args: { + name: "PATHS", + description: "Paths to add to the internal tree", + }, + options: [ + { + name: ["-f", "--force"], + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: ["-r", "--recursive"], + }, + ], + }, + { + name: "apply", + description: "Applies changes to a channel", + args: { + name: "CHANGE", + description: + "The change that need to be applied. If this value is missing, read the change in text format on the standard input", + }, + options: [ + { + name: "--channel", + description: "Apply change to this channel", + args: { + name: "CHANNEL", + }, + }, + { + name: "--deps-only", + description: + "Only apply the dependencies of the change, not the change itself. Only applicable for a single change", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "archive", + description: "Creates an archive of the repository", + options: [ + { + name: "--change", + description: "Apply these changes after switching to the channel", + args: { + name: "CHANGE", + }, + }, + { + name: "--channel", + description: "Use this channel, instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "-k", + description: + "Do not check certificates (HTTPS remotes only, this option might be dangerous)", + }, + { + name: "-o", + description: "Name of the output file", + args: { + name: "NAME", + }, + }, + { + name: "--prefix", + description: + "Append this path in front of each path inside the archive", + args: { + name: "PREFIX", + }, + }, + { + name: "--remote", + description: "Ask the remote to send an archive", + args: { + name: "REMOTE", + }, + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--state", + description: "Archive in this state", + args: { + name: "STATE", + }, + }, + { + name: "--umask", + description: + "Append this path in front of each path inside the archive", + args: { + name: "UMASK", + }, + }, + ], + }, + { + name: "change", + description: "Shows information about a particular change", + args: { + name: "HASH", + description: + "The hash of the change to show, or an unambiguous prefix thereof", + }, + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Use the repository at PATH instead of the current directory", + args: { + name: "PATH", + }, + }, + ], + }, + { + name: "channel", + description: "Manages different channels", + subcommands: [ + { + name: "delete", + description: + "Delete a channel. The channel must not be the current channel", + args: { + name: "DELETE", + }, + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + { + name: "new", + description: "Create a new, empty channel", + }, + { + name: "rename", + description: "Rename a channel", + args: [ + { + name: "FROM", + }, + { + name: "TO", + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "switch", + description: + "Switch to a channel. There must not be unrecorded changes in the working copy", + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "clone", + description: "Clones an existing pijul repository", + args: [ + { + name: "REMOTE", + description: "Clone this remote", + }, + { + name: "PATH", + description: + "Path where to clone the repository. If missing, the inferred name of the remote repository is used", + }, + { + name: "SALT", + }, + ], + options: [ + { + name: "--change", + description: "Clone this change and its dependencies", + args: { + name: "CHANGE", + }, + }, + { + name: "--channel", + description: "Set the remote channel [default: main]", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "-k", + description: + "Do not check certificates (HTTPS remotes only, this option might be dangerous)", + }, + { + name: "--path", + description: "Clone this path only", + args: { + name: "PARTIAL_PATHS", + }, + }, + { + name: "--state", + description: "Clone this state", + args: { + name: "STATE", + }, + }, + ], + }, + { + name: "credit", + description: + "Shows which change last affected each line of the given file(s)", + args: { + name: "FILE", + description: "The file to annotate", + }, + options: [ + { + name: "--channel", + description: "Use this channel instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "diff", + description: "Shows difference between two channels/changes", + args: { + name: "PREFIXES", + description: + "Only diff those paths (files or directories). If missing, diff the entire repository", + }, + options: [ + { + name: "--channel", + description: "Compare with this channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--json", + description: + "Output the diff in JSON format instead of the default change text format", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: ["-s", "--short"], + description: "Show a short version of the diff", + }, + { + name: "--tag", + description: + "Add all the changes of this channel as dependencies (except changes implied transitively), instead of the minimal dependencies", + }, + { + name: ["-u", "--untracked"], + description: "Include the untracked files", + }, + ], + }, + { + name: "fork", + description: "Create a new channel", + args: { + name: "TO", + description: "The name of the new channel", + }, + options: [ + { + name: "--change", + description: "Apply this change after creating the channel", + args: { + name: "CHANGE", + }, + }, + { + name: "--channel", + description: + "Make the new channel from this channel instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "init", + description: "Initializes an empty pijul repository", + args: { + name: "PATH", + description: "Path where the repository should be initialized", + }, + options: [ + { + name: "--channel", + description: + "Set the name of the current channel (defaults to “main”)", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: ["-k", "--kind"], + description: + "Project kind; if Pijul knows about your project kind, the .ignore file will be populated with a conservative list of commonly ignored entries. Example: pijul init --kind=rust", + args: { + name: "KIND", + }, + }, + ], + }, + { + name: "log", + description: "Show the entire log of changes", + args: { + name: "FILTERS", + description: + "Filter log output, showing only log entries that touched the specified files. Accepted as a list of paths relative to your current directory. Currently, filters can only be applied when logging the channel that’s in use", + }, + options: [ + { + name: "--channel", + description: + "Show logs for this channel instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: "--description", + description: "Include full change description in the output", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--hash-only", + description: "Only show the change hashes", + }, + { + name: "--limit", + description: "Output at most this many changes", + args: { + name: "LIMIT", + }, + }, + { + name: "--offset", + description: "Start after this many changes", + args: { + name: "OFFSET", + }, + }, + { + name: "--output-format", + args: { + name: "OUTPUT_FORMAT", + }, + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--state", + description: "Include state identifiers in the output", + }, + ], + }, + { + name: "ls", + }, + { + name: "mv", + }, + { + name: "pull", + description: "Pulls changes from a remote upstream", + args: [ + { + name: "FROM", + description: "Pulls from this remote", + }, + { + name: "CHANGES", + description: + "Pull changes from the local repository, not necessarily from a channel", + }, + ], + options: [ + { + name: ["-a", "--all"], + description: "Pull all changes", + }, + { + name: ["-f", "--force-cache"], + description: + "Force an update of the local remote cache. May effect some reporting of unrecords/concurrent changes in the remote", + }, + { + name: "--from-channel", + description: "Pull from this remote channel", + args: { + name: "FROM_CHANNEL", + }, + }, + { + name: "--full", + description: "Download full changes, even when not necessary", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "-k", + description: + "Do not check certificates (HTTPS remotes only, this option might be dangerous)", + }, + { + name: "--path", + description: "Only pull to these paths", + args: { + name: "PATH", + }, + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--to-channel", + description: "Pull into this channel instead of the current channel", + args: { + name: "TO_CHANNEL", + }, + }, + ], + }, + { + name: "push", + description: "Pushes changes to a remote upstream", + args: [ + { + name: "TO", + description: "Push to this remote", + }, + { + name: "CHANGES", + description: "Push only these changes", + }, + ], + options: [ + { + name: ["-a", "--all"], + description: "Push all changes", + }, + { + name: ["-f", "--force-cache"], + description: + "Force an update of the local remote cache. May effect some reporting of unrecords/concurrent changes in the remote", + }, + { + name: "--from-channel", + description: "Push from this channel instead of the default channel", + args: { + name: "FROM_CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "-k", + description: + "Do not check certificates (HTTPS remotes only, this option might be dangerous)", + }, + { + name: "--path", + description: "Push changes only relating to these paths", + args: { + name: "PATH", + }, + }, + { + name: "--repository", + description: + "Path to the repository. Uses the current repository if the argument is omitted", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--to-channel", + description: + "Push to this remote channel instead of the remote’s default channel", + args: { + name: "TO_CHANNEL", + }, + }, + ], + }, + { + name: "record", + description: "Creates a new change", + args: { + name: "PREFIXES", + description: "Paths in which to record the changes", + }, + options: [ + { + name: ["-a", "--all"], + description: "Record all paths that have changed", + }, + { + name: "--amend", + description: "Amend this change instead of creating a new change", + args: { + name: "AMEND", + }, + }, + { + name: "--author", + description: "Set the author field", + args: { + name: "AUTHOR", + }, + }, + { + name: "--channel", + description: + "Record the change in this channel instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--ignore-missing", + description: "Ignore missing (deleted) files", + }, + { + name: ["-m", "--message"], + description: "Set the change message", + args: { + name: "MESSAGE", + }, + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--timestamp", + description: "Set the timestamp field", + args: { + name: "TIMESTAMP", + }, + }, + { + name: "--working-copy", + args: { + name: "WORKING_COPY", + }, + }, + ], + }, + { + name: "remote", + description: "Manages remote repositories", + subcommands: [ + { + name: "delete", + description: "Deletes the remote", + args: { + name: "REMOTE", + }, + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "remove", + description: + "Removes a file from the tree of tracked files (pijul record will then record this as a deletion)", + args: { + name: "PATHS", + description: "The paths need to be removed", + }, + options: [ + { + name: ["-h", "--help"], + description: "Print help information", + }, + ], + }, + { + name: "reset", + description: + "Resets the working copy to the last recorded change.\nIn other words, discards all unrecorded changes", + args: { + name: "FILES", + description: "Only reset these files", + }, + options: [ + { + name: "--channel", + description: + "Reset the working copy to this channel, and change the current channel to this channel", + args: { + name: "CHANNEL", + }, + }, + { + name: "--dry-run", + description: + "Print this file to the standard output, without modifying the repository (works for a single file only)", + }, + { + name: ["-f", "--force"], + description: "Reset even if there are unrecorded changes", + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + ], + }, + { + name: "unrecord", + description: "Unrecords a list of changes", + args: { + name: "CHANGE_ID", + description: "The hash of a change (unambiguous prefixes are accepted)", + }, + options: [ + { + name: "--channel", + description: + "Unrecord changes from this channel instead of the current channel", + args: { + name: "CHANNEL", + }, + }, + { + name: ["-h", "--help"], + description: "Print help information", + }, + { + name: "--repository", + description: + "Set the repository where this command should run. Defaults to the first ancestor of the current directory that contains a .pijul directory", + args: { + name: "REPO_PATH", + }, + }, + { + name: "--reset", + description: + "Also undo the changes in the working copy (preserving unrecorded changes if there are any)", + }, + { + name: "--show-changes", + description: + "Show N changes in a text editor if no s were given. Defaults to the value of unrecord_changes in your global configuration", + args: { + name: "N", + }, + }, + ], + }, + ], +}; +export default completionSpec; From f89f8ce7c7dd916f885e677eec69677becda6a6b Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 22:03:44 +0000 Subject: [PATCH 32/81] ci: version bump to 2.638.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 533cbba91cbe..321c512720ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.6", + "version": "2.638.7", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 08890617018b45dbd5081eff8cbf87c64b9147ee Mon Sep 17 00:00:00 2001 From: Swarom Muley Date: Fri, 27 Oct 2023 15:09:43 -0700 Subject: [PATCH 33/81] feat(pip): add openai to the list of packages (#1223) --- src/pip.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pip.ts b/src/pip.ts index 6824199812cd..5c6372490356 100644 --- a/src/pip.ts +++ b/src/pip.ts @@ -431,6 +431,10 @@ export const packageList: Array = [ name: "ipython-genutils", icon: "📦", }, + { + name: "openai", + icon: "📦", + }, { name: "mccabe", icon: "📦", From 2a75a00e45577378f340d9ffe557ba87a7591f21 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 22:11:23 +0000 Subject: [PATCH 34/81] ci: version bump to 2.639.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 321c512720ef..6ac7bd098ef8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.638.7", + "version": "2.639.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From b41d5414083ab743769647228e7a56eebfd65911 Mon Sep 17 00:00:00 2001 From: Fall1ngStar <12586447+Fall1ngStar@users.noreply.github.com> Date: Fri, 27 Oct 2023 18:17:21 -0400 Subject: [PATCH 35/81] feat(atuin): add spec) (#2122) --- src/atuin.ts | 520 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 520 insertions(+) create mode 100644 src/atuin.ts diff --git a/src/atuin.ts b/src/atuin.ts new file mode 100644 index 000000000000..fdae7ffb3714 --- /dev/null +++ b/src/atuin.ts @@ -0,0 +1,520 @@ +const completionSpec: Fig.Spec = { + name: "atuin", + description: "Magical shell history", + subcommands: [ + { + name: "history", + description: "Manipulate shell history", + subcommands: [ + { + name: "start", + description: "Begins a new command in the history", + args: { + name: "COMMAND", + isVariadic: true, + }, + }, + { + name: "end", + description: + "Finishes a new command in the history (adds time, exit code)", + args: { + name: "ID", + }, + options: [ + { + name: ["--exit", "-e"], + args: { + name: "EXIT", + }, + }, + ], + }, + { + name: "list", + description: "List all items in history", + options: [ + { + name: ["--cwd", "-c"], + }, + { + name: ["--session", "-s"], + }, + { + name: "--human", + }, + { + name: "--cmd-only", + description: "Show only the text of the command", + }, + { + name: ["--format", "-f"], + args: { + name: "FORMAT", + description: + 'Available variables: {command}, {directory}, {duration}, {user}, {host} and {time}. Example: --format "{time} - [{duration}] - {directory}$\\t{command}"', + }, + }, + ], + }, + { + name: "last", + description: "Get the last command ran", + options: [ + { + name: "--human", + }, + { + name: "--cmd-only", + description: "Show only the text of the command", + }, + { + name: ["--format", "-f"], + args: { + name: "FORMAT", + description: + 'Available variables: {command}, {directory}, {duration}, {user}, {host} and {time}. Example: --format "{time} - [{duration}] - {directory}$\\t{command}"', + }, + }, + ], + }, + ], + }, + { + name: "import", + description: "Import shell history from file", + subcommands: [ + { + name: "auto", + description: "Import history for the current shell", + }, + ...[ + "zsh", + "zsh-hist-db", + "bash", + "resh", + "fish", + "nu", + "nu-hist-db", + ].map((shell) => { + const prettyShellName = shell.replace(/-hist-db/, ""); + return { + name: shell, + description: `Import history from the ${prettyShellName} history file`, + }; + }), + ], + }, + { + name: "stats", + description: "Calculate statistics for your history", + args: { + name: "PERIOD", + description: + "Compute statistics for the specified period, leave blank for statistics since the beginning", + isVariadic: true, + }, + options: [ + { + name: ["--count", "-c"], + description: "How many top commands to list", + args: { + name: "COUNT", + }, + }, + ], + }, + { + name: "search", + description: "Interactive history search", + args: { + name: "QUERY", + isVariadic: true, + }, + options: [ + { + name: ["--cwd", "-c"], + description: "Filter search result by directory", + args: { + name: "CWD", + }, + }, + { + name: "--exclude-cwd", + description: "Exclude directory from results", + args: { + name: "EXCLUDE_CWD", + }, + }, + { + name: ["--exit", "-e"], + description: "Filter search result by exit code", + args: { + name: "EXIT", + }, + }, + { + name: "--exclude-exit", + description: "Exclude results with this exit code", + args: { + name: "EXCLUDE_EXIT", + }, + }, + { + name: ["--before", "-b"], + description: "Only include results added before this date", + args: { + name: "BEFORE", + }, + }, + { + name: "--after", + description: "Only include results after this date", + args: { + name: "AFTER", + }, + }, + { + name: "--limit", + description: "How many entries to return at most", + args: { + name: "LIMIT", + }, + }, + { + name: "--offset", + description: "Offset from the start of the results", + args: { + name: "OFFSET", + }, + }, + { + name: ["--interactive", "-i"], + description: "Open interactive search UI", + }, + { + name: "--filter-mode", + description: "Allow overriding filter mode over config", + args: { + name: "FILTER_MODE", + suggestions: [ + "global", + "host", + "session", + "directory", + "workspace", + ], + }, + }, + { + name: "--search-mode", + description: "Allow overriding search mode over config", + args: { + name: "SEARCH_MODE", + suggestions: ["prefix", "full-text", "fuzzy", "skim"], + }, + }, + { + name: "--human", + description: "Use human-readable formatting for time", + }, + { + name: "--cmd-only", + description: "Show only the text of the command", + }, + { + name: "--delete", + description: + "Delete anything matching this query. Will not print out the match", + }, + { + name: "--delete-it-all", + description: "Delete EVERYTHING!", + }, + { + name: ["--reverse", "-r"], + description: "Reverse the order of results, oldest first", + }, + { + name: ["--format", "-f"], + args: { + name: "FORMAT", + description: + 'Available variables: {command}, {directory}, {duration}, {user}, {host} and {time}. Example: --format "{time} - [{duration}] - {directory}$\\t{command}"', + }, + }, + { + name: "--inline-height", + description: + "Set the maximum number of lines Atuin's interface should take up", + args: { + name: "INLINE_HEIGHT", + }, + }, + ], + }, + { + name: "sync", + description: "Sync with the configured server", + options: [ + { + name: ["--force", "-f"], + description: "Force re-download everything", + }, + ], + }, + { + name: "login", + description: "Login to the configured server", + options: [ + { + name: ["--username", "-u"], + args: { + name: "USERNAME", + }, + }, + { + name: ["--password", "-p"], + args: { + name: "PASSWORD", + }, + }, + { + name: ["--key", "-k"], + description: "The encryption key for your account", + args: { + name: "KEY", + }, + }, + ], + }, + { + name: "logout", + description: "Log out", + }, + { + name: "register", + description: "Register with the configured server", + options: [ + { + name: ["--username", "-u"], + args: { + name: "USERNAME", + }, + }, + { + name: ["--password", "-p"], + args: { + name: "PASSWORD", + }, + }, + { + name: ["--email", "-e"], + args: { + name: "EMAIL", + }, + }, + ], + }, + { + name: "key", + description: "Print the encryption key for transfer to another machine", + options: [ + { + name: "--base64", + description: "Switch to base64 output of the key", + }, + ], + }, + { + name: "status", + }, + { + name: "account", + subcommands: [ + { + name: "login", + description: "Login to the configured server", + options: [ + { + name: ["--username", "-u"], + args: { + name: "USERNAME", + }, + }, + { + name: ["--password", "-p"], + args: { + name: "PASSWORD", + }, + }, + { + name: ["--key", "-k"], + description: "The encryption key for your account", + args: { + name: "KEY", + }, + }, + ], + }, + { + name: "register", + options: [ + { + name: ["--username", "-u"], + args: { + name: "USERNAME", + }, + }, + { + name: ["--password", "-p"], + args: { + name: "PASSWORD", + }, + }, + { + name: ["--email", "-e"], + args: { + name: "EMAIL", + }, + }, + ], + }, + { + name: "logout", + description: "Log out", + }, + { + name: "delete", + }, + ], + }, + { + name: "kv", + subcommands: [ + { + name: "set", + args: { + name: "VALUE", + }, + options: [ + { + name: ["--key", "-k"], + isRequired: true, + args: { + name: "KEY", + }, + }, + { + name: ["--namespace", "-n"], + args: { + name: "NAMESPACE", + }, + }, + ], + }, + { + name: "get", + args: { + name: "KEY", + }, + options: [ + { + name: ["--namespace", "-n"], + args: { + name: "NAMESPACE", + }, + }, + ], + }, + ], + }, + { + name: "server", + description: "Start an atuin server", + subcommands: [ + { + name: "start", + description: "Start the server", + options: [ + { + name: "--host", + description: "The host address to bind", + args: { + name: "HOST", + }, + }, + { + name: ["--port", "-p"], + description: "The port to bind", + args: { + name: "PORT", + }, + }, + ], + }, + ], + }, + { + name: "init", + description: "Output shell setup", + args: { + name: "SHELL", + suggestions: ["zsh", "bash", "fish", "nu"], + }, + options: [ + { + name: "--disable-ctrl-r", + description: "Disable the binding of CTRL-R to atuin", + }, + { + name: "--disable-up-arrow", + description: "Disable the binding of the Up Arrow key to atuin", + }, + ], + }, + { + name: "uuid", + description: "Generate a UUID", + }, + { + name: "contributors", + }, + { + name: "gen-completions", + description: "Generate shell completions", + options: [ + { + name: ["--shell", "-s"], + description: "Set the shell for generating completions", + isRequired: true, + args: { + name: "SHELL", + suggestions: ["bash", "elvish", "fish", "powershell", "zsh"], + }, + }, + { + name: ["--out-dir", "-o"], + description: "Set the output directory", + args: { + name: "OUT_DIR", + }, + }, + ], + }, + ], + options: [ + { + name: ["--help", "-h"], + description: "Print help", + isPersistent: true, + }, + { + name: ["--version", "-V"], + description: "Print version", + }, + ], + // Only uncomment if atuin takes an argument + // args: {} +}; +export default completionSpec; From 35078ab42f1f88de6030a1eeabc0148d79da26c4 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:17:58 +0000 Subject: [PATCH 36/81] feat: add capgo spec (#2131) --- src/@capgo/cli.ts | 417 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 src/@capgo/cli.ts diff --git a/src/@capgo/cli.ts b/src/@capgo/cli.ts new file mode 100644 index 000000000000..5130c58044af --- /dev/null +++ b/src/@capgo/cli.ts @@ -0,0 +1,417 @@ +const completionSpec: Fig.Spec = { + name: "cli", + description: "Manage packages and bundle versions in Capgo Cloud", + subcommands: [ + { + name: "login", + description: "Save apikey to your machine or folder", + args: { + name: "apikey", + }, + options: [ + { + name: "--local", + description: "Only save in local folder", + }, + ], + }, + { + name: "doctor", + description: "Get info about your Capgo app install", + }, + { + name: "init", + description: "Init a new app", + args: [ + { + name: "apikey", + }, + { + name: "appId", + }, + ], + options: [ + { + name: ["-n", "--name"], + description: "App name", + args: { + name: "name", + }, + }, + { + name: ["-i", "--icon"], + description: "App icon path", + args: { + name: "icon", + template: "filepaths", + }, + }, + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + ], + }, + { + name: "app", + description: "Manage app", + subcommands: [ + { + name: ["add", "a"], + description: "Add a new app in Capgo Cloud", + args: { + name: "appId", + }, + options: [ + { + name: ["-n", "--name"], + description: "App name", + args: { + name: "name", + }, + }, + { + name: ["-i", "--icon"], + description: "App icon path", + args: { + name: "icon", + template: "filepaths", + }, + }, + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + ], + }, + { + name: ["delete", "d"], + description: "Delete an app in Capgo Cloud", + args: { + name: "appId", + }, + options: [ + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + ], + }, + { + name: ["list", "l"], + description: "List apps in Capgo Cloud", + options: [ + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + ], + }, + { + name: "debug", + description: + "Listen for live updates event in Capgo Cloud to debug your app", + args: { + name: "appId", + }, + options: [ + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + { + name: ["-d", "--device"], + description: "The specific device to debug", + args: { + name: "device", + }, + }, + ], + }, + { + name: ["set", "s"], + description: "Set an app in Capgo Cloud", + args: { + name: "appId", + }, + options: [ + { + name: ["-n", "--name"], + description: "App name", + args: { + name: "name", + }, + }, + { + name: ["-i", "--icon"], + description: "App icon path", + args: { + name: "icon", + template: "filepaths", + }, + }, + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + { + name: ["-r", "--retention"], + description: "Retention period of app bundle in days", + args: { + name: "retention", + }, + }, + ], + }, + ], + }, + { + name: "bundle", + description: "Manage bundle", + subcommands: [ + { + name: ["delete", "d"], + description: "Delete a bundle in Capgo Cloud", + args: [ + { + name: "bundleId", + }, + { + name: "appId", + }, + ], + options: [ + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + ], + }, + { + name: ["decrypt", "l"], + description: "Decrypt a signed zip bundle", + args: [ + { + name: "zipPath", + template: "filepaths", + }, + { + name: "sessionKey", + }, + ], + options: [ + { + name: "--key", + description: "Custom path for private signing key", + args: { + name: "key", + template: "filepaths", + }, + }, + { + name: "--key-data", + description: "Base64 private signing key", + args: { + name: "keyData", + }, + }, + ], + }, + { + name: "encrypt", + description: "Encrypt a zip bundle", + args: { + name: "zipPath", + template: "filepaths", + }, + options: [ + { + name: "--key", + description: "Custom path for private signing key", + args: { + name: "key", + template: "filepaths", + }, + }, + { + name: "--key-data", + description: "Base64 private signing key", + args: { + name: "keyData", + }, + }, + ], + }, + { + name: "zip", + description: "Zip a bundle", + args: { + name: "appId", + }, + options: [ + { + name: ["-p", "--path"], + description: "Path of the folder to upload", + args: { + name: "path", + template: "folders", + }, + }, + ], + }, + ], + }, + { + name: "channel", + description: "Manage channel", + subcommands: [ + { + name: ["add", "a"], + description: "Create channel", + args: [ + { + name: "channelId", + }, + { + name: "appId", + }, + ], + options: [ + { + name: ["-d", "--default"], + description: "Set the channel as default", + }, + ], + }, + { + name: ["delete", "d"], + description: "Delete channel", + args: [ + { + name: "channelId", + }, + { + name: "appId", + }, + ], + }, + { + name: ["list", "l"], + description: "List channel", + args: { + name: "appId", + }, + }, + { + name: "currentBundle", + description: "Get current bundle for specific channel in Capgo Cloud", + args: [ + { + name: "channel", + }, + { + name: "appId", + }, + ], + options: [ + { + name: ["-c", "--channel"], + description: "Channel to get the current bundle from", + args: { + name: "channel", + }, + }, + { + name: ["-a", "--apikey"], + description: "Apikey to link to your account", + args: { + name: "apikey", + }, + }, + { + name: "--quiet", + description: "Only print the bundle version", + }, + ], + }, + { + name: ["set", "s"], + description: "Set channel", + args: [ + { + name: "channelId", + }, + { + name: "appId", + }, + ], + }, + ], + }, + { + name: "key", + description: "Manage key", + subcommands: [ + { + name: "save", + description: + "Save base64 signing key in capacitor config, useful for CI", + options: [ + { + name: ["-f", "--force"], + description: "Force generate a new one", + }, + { + name: "--key", + description: "Key path to save in capacitor config", + args: { + name: "key", + template: "filepaths", + }, + }, + { + name: "--key-data", + description: "Key data to save in capacitor config", + args: { + name: "keyData", + }, + }, + ], + }, + { + name: "create", + description: "Create a new signing key", + options: [ + { + name: ["-f", "--force"], + description: "Force generate a new one", + }, + ], + }, + ], + }, + ], +}; + +export default completionSpec; From 15ad671ac451ddda66e8a8cfdc15e21ab74339ae Mon Sep 17 00:00:00 2001 From: Grant G Date: Fri, 27 Oct 2023 15:18:31 -0700 Subject: [PATCH 37/81] Remove old CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5ea3c354a951..95cff3d0fbaf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,4 +4,4 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @fedeci @mschrage @SeparateRecords +* @grant0417 @mschrage From 6ac11255b7b2cdc65153930c650aa60acc791a33 Mon Sep 17 00:00:00 2001 From: Robert Clover Date: Sat, 28 Oct 2023 09:19:32 +1100 Subject: [PATCH 38/81] feat(deno): update generators (#1491) Co-authored-by: Robert <52195359+SeparateRecords@users.noreply.github.com> Unsure whether the copy/paste generator works but worst case, we it fails and throws a silent error --- src/deno.ts | 9 +- src/deno/generators.ts | 393 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 377 insertions(+), 25 deletions(-) diff --git a/src/deno.ts b/src/deno.ts index 6f4684882d1e..5db8fd55d6f7 100644 --- a/src/deno.ts +++ b/src/deno.ts @@ -4,6 +4,7 @@ import { generateLintRules, generateTasks, generateVersions, + generateUrlScript, } from "./deno/generators"; const completion: Fig.Spec = { @@ -899,8 +900,8 @@ const completion: Fig.Spec = { args: { name: "script_arg", isVariadic: true, - template: "filepaths", isScript: true, + generators: [{ template: "filepaths" }, generateUrlScript], }, parserDirectives: { optionsMustPrecedeArguments: true, @@ -1076,7 +1077,7 @@ const completion: Fig.Spec = { { name: "source_file", isOptional: true, - template: "filepaths", + generators: [{ template: "filepaths" }, generateUrlScript], suggestions: [ { name: "--builtin", @@ -1821,8 +1822,8 @@ const completion: Fig.Spec = { args: { name: "cmd", isVariadic: true, - template: "filepaths", isScript: true, + generators: [{ template: "filepaths" }, generateUrlScript], }, parserDirectives: { optionsMustPrecedeArguments: true, @@ -2490,7 +2491,6 @@ const completion: Fig.Spec = { args: { name: "script_arg", isVariadic: true, - template: "filepaths", isScript: true, suggestions: [ { @@ -2499,6 +2499,7 @@ const completion: Fig.Spec = { hidden: true, }, ], + generators: [{ template: "filepaths" }, generateUrlScript], }, parserDirectives: { optionsMustPrecedeArguments: true, diff --git a/src/deno/generators.ts b/src/deno/generators.ts index db9b1855483f..a6ec1a429a35 100644 --- a/src/deno/generators.ts +++ b/src/deno/generators.ts @@ -1,6 +1,6 @@ /* eslint-disable @withfig/fig-linter/no-missing-default-export */ -import { filepaths } from "@fig/autocomplete-generators"; +import { filepaths, valueList } from "@fig/autocomplete-generators"; import stripJsonComments from "strip-json-comments"; import type { DenoConfigurationFileSchema } from "./config_schema"; @@ -237,25 +237,331 @@ export const generateRunnableFiles = filepaths({ // --- Generate lint rules -type DenoLintRulesJSON = { - code: string; - tags: string[]; - docs: string; -}[]; - -export const generateLintRules: Fig.Generator = { - script: "deno lint --rules --json", - getQueryTerm: ",", - cache: { ttl: 1000 * 60 * 60 * 24 }, - postProcess: (out) => { - const json = JSON.parse(out) as DenoLintRulesJSON; - return json.map((rule) => ({ - name: rule.code, - description: rule.docs.slice(0, rule.docs.indexOf("\n\n")), - icon: "fig://icon?type=string", - })); - }, -}; +export const generateLintRules = valueList({ + insertDelimiter: true, + values: [ + { + name: "adjacent-overload-signatures", + description: "Requires overload signatures to be adjacent to each other", + }, + { + name: "ban-ts-comment", + description: + "Disallows the use of Typescript directives without a comment", + }, + { + name: "ban-types", + description: + "Bans the use of primitive wrapper objects (e.g. `String` the object is a wrapper\nof `string` the primitive) in addition to the non-explicit `Function` type and\nthe misunderstood `Object` type", + }, + { + name: "ban-unknown-rule-code", + description: "Warns the usage of unknown rule codes in ignore directives", + }, + { + name: "ban-untagged-ignore", + description: + "Requires `deno-lint-ignore` to be annotated with one or more rule names", + }, + { + name: "ban-unused-ignore", + description: "Warns unused ignore directives", + }, + { + name: "constructor-super", + description: + "Verifies the correct usage of constructors and calls to `super()`", + }, + { + name: "for-direction", + description: + "Requires `for` loop control variables to increment in the correct direction", + }, + { + name: "getter-return", + description: "Requires all property getter functions to return a value", + }, + { + name: "no-array-constructor", + description: "Enforce conventional usage of array construction", + }, + { + name: "no-async-promise-executor", + description: + "Requires that async promise executor functions are not used", + }, + { + name: "no-case-declarations", + description: + "Requires lexical declarations (`let`, `const`, `function` and `class`) in switch\n`case` or `default` clauses to be scoped with brackets", + }, + { + name: "no-class-assign", + description: "Disallows modifying variables of class declarations", + }, + { + name: "no-compare-neg-zero", + description: "Disallows comparing against negative zero (`-0`)", + }, + { + name: "no-cond-assign", + description: + "Disallows the use of the assignment operator, `=`, in conditional statements", + }, + { + name: "no-constant-condition", + description: + "Disallows the use of a constant expression in conditional test", + }, + { + name: "no-control-regex", + description: + "Disallows the use ascii control characters in regular expressions", + }, + { + name: "no-debugger", + description: "Disallows the use of the `debugger` statement", + }, + { + name: "no-delete-var", + description: "Disallows the deletion of variables", + }, + { + name: "no-deprecated-deno-api", + description: "Warns the usage of the deprecated Deno APIs", + }, + { + name: "no-dupe-args", + description: + "Disallows using an argument name more than once in a function signature", + }, + { + name: "no-dupe-class-members", + description: + "Disallows using a class member function name more than once", + }, + { + name: "no-dupe-else-if", + description: + "Disallows using the same condition twice in an `if`/`else if` statement", + }, + { + name: "no-dupe-keys", + description: "Disallows duplicate keys in object literals", + }, + { + name: "no-duplicate-case", + description: + "Disallows using the same case clause in a switch statement more than once", + }, + { + name: "no-empty", + description: "Disallows the use of empty block statements", + }, + { + name: "no-empty-character-class", + description: + "Disallows using the empty character class in a regular expression", + }, + { + name: "no-empty-enum", + description: "Disallows the declaration of an empty enum", + }, + { + name: "no-empty-interface", + description: "Disallows the declaration of an empty interface", + }, + { + name: "no-empty-pattern", + description: "Disallows the use of empty patterns in destructuring", + }, + { + name: "no-ex-assign", + description: "Disallows the reassignment of exception parameters", + }, + { + name: "no-explicit-any", + description: "Disallows use of the `any` type", + }, + { + name: "no-extra-boolean-cast", + description: "Disallows unnecessary boolean casts", + }, + { + name: "no-extra-non-null-assertion", + description: "Disallows unnecessary non-null assertions", + }, + { + name: "no-extra-semi", + description: "", + }, + { + name: "no-fallthrough", + description: "Disallows the implicit fallthrough of case statements", + }, + { + name: "no-func-assign", + description: + "Disallows the overwriting/reassignment of an existing function", + }, + { + name: "no-global-assign", + description: "Disallows assignment to native Javascript objects", + }, + { + name: "no-import-assign", + description: "Disallows reassignment of imported module bindings", + }, + { + name: "no-inferrable-types", + description: "Disallows easily inferrable types", + }, + { + name: "no-inner-declarations", + description: + "Disallows variable or function definitions in nested blocks", + }, + { + name: "no-invalid-regexp", + description: + "Disallows specifying invalid regular expressions in RegExp constructors", + }, + { + name: "no-invalid-triple-slash-reference", + description: "Warns the wrong usage of triple-slash reference directives", + }, + { + name: "no-irregular-whitespace", + description: + "Disallows the use of non-space or non-tab whitespace characters", + }, + { + name: "no-misused-new", + description: + "Disallows defining `constructor`s for interfaces or `new` for classes", + }, + { + name: "no-namespace", + description: + "Disallows the use of `namespace` and `module` keywords in TypeScript code", + }, + { + name: "no-new-symbol", + description: + "Disallows the use of `new` operators with built-in `Symbol`s", + }, + { + name: "no-obj-calls", + description: "Disallows calling built-in global objects like functions", + }, + { + name: "no-octal", + description: + "Disallows expressing octal numbers via numeric literals beginning with `0`", + }, + { + name: "no-prototype-builtins", + description: "Disallows the use of `Object.prototype` builtins directly", + }, + { + name: "no-redeclare", + description: + "Disallows redeclaration of variables, functions, parameters with the same name", + }, + { + name: "no-regex-spaces", + description: "Disallows multiple spaces in regular expression literals", + }, + { + name: "no-self-assign", + description: "Disallows self assignments", + }, + { + name: "no-setter-return", + description: "Disallows returning values from setters", + }, + { + name: "no-shadow-restricted-names", + description: "Disallows shadowing of restricted names", + }, + { + name: "no-this-alias", + description: "Disallows assigning variables to `this`", + }, + { + name: "no-this-before-super", + description: + "Disallows use of `this` or `super` before calling `super()` in constructors", + }, + { + name: "no-unreachable", + description: + "Disallows the unreachable code after the control flow statements", + }, + { + name: "no-unsafe-finally", + description: + "Disallows the use of control flow statements within `finally` blocks", + }, + { + name: "no-unsafe-negation", + description: + "Disallows the usage of negation operator `!` as the left operand of relational\noperators", + }, + { + name: "no-unused-labels", + description: "Disallows unused labels", + }, + { + name: "no-unused-vars", + description: "Enforces all variables used at least once", + }, + { + name: "no-var", + description: + "Enforces the use of block scoped variables over more error prone function scoped\nvariables. Block scoped variables are defined using `const` and `let` keywords", + }, + { + name: "no-window-prefix", + description: "Disallows the use of Web APIs via the `window` object", + }, + { + name: "no-with", + description: "Disallows the usage of `with` statements", + }, + { + name: "prefer-as-const", + description: + "Recommends using const assertion (`as const`) over explicitly specifying literal\ntypes or using type assertion", + }, + { + name: "prefer-const", + description: "Recommends declaring variables with [`const`] over [`let`]", + }, + { + name: "prefer-namespace-keyword", + description: + "Recommends the use of `namespace` keyword over `module` keyword when declaring\nTypeScript module", + }, + { + name: "require-await", + description: "Disallows async functions that have no await expression", + }, + { + name: "require-yield", + description: "Disallows generator functions that have no `yield`", + }, + { + name: "use-isnan", + description: "Disallows comparisons to `NaN`", + }, + { + name: "valid-typeof", + description: + "Restricts the use of the `typeof` operator to a specific set of string literals", + }, + ].map((suggestion) => ({ ...suggestion, icon: "fig://icon?type=string" })), +}); // --- Generate tasks @@ -351,7 +657,7 @@ export const generateTasks: Fig.Generator = { // --- Generate installed deno scripts export const generateInstalledDenoScripts: Fig.Generator = { - script: "\\find ~/.deno/bin -maxdepth 1 -perm -111 -type f", + script: "command find ~/.deno/bin -maxdepth 1 -perm -111 -type f", postProcess: (out) => out .split("\n") @@ -362,3 +668,48 @@ export const generateInstalledDenoScripts: Fig.Generator = { description: path, })), }; + +// --- Suggest URLs from clipboard + +// Our transpilation causes this to become `new RegExp` which we don't want to +// run on every invocation of the function +const httpsRe = /^(https?:\/\/.*\.(?:m?[jt]sx?))(?:\?.*)?(?:\#.*)?$/; + +const clipboardTests: ((str: string) => string | boolean)[] = [ + // HTTPS test + (str) => { + const match = str.match(httpsRe); + if (!match) { + return false; + } + return match[1]; + }, + // NPM test + (str) => str.startsWith("npm:"), +]; + +export const generateUrlScript: Fig.Generator = { + // There's no simple solution for pasting on Linux, it depends on + // whether you use X11 or Wayland. For Wayland on some (most?) distros, + // you would have to manually install wl-paste. + script: `pbpaste`, + postProcess: (clipboard) => { + clipboard = clipboard.trim(); + if (!clipboard) { + return []; + } + for (const test of clipboardTests) { + const match = test(clipboard); + if (!match) { + continue; + } + return [ + { + name: match === true ? clipboard : match, + icon: "fig://template?badge=📋&color=000000", + priority: 100, + }, + ]; + } + }, +}; From e8a02439b3e4a47f39edb56236d68d7b19be171e Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 22:21:33 +0000 Subject: [PATCH 39/81] ci: version bump to 2.640.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ac7bd098ef8..13bf3949e7b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.639.0", + "version": "2.640.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From a47448e13033a0a986d489c182c606206ffadfb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:27:35 -0700 Subject: [PATCH 40/81] build(deps): bump yaml from 2.3.2 to 2.3.3 (#2123) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4fa47b118811..ecb9790e21aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7414,27 +7414,13 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.3.3": +"yaml@npm:2.3.3, yaml@npm:^2.1.1, yaml@npm:^2.3.2": version: 2.3.3 resolution: "yaml@npm:2.3.3" checksum: cdfd132e7e0259f948929efe8835923df05c013c273c02bb7a2de9b46ac3af53c2778a35b32c7c0f877cc355dc9340ed564018c0242bfbb1278c2a3e53a0e99e languageName: node linkType: hard -"yaml@npm:^2.1.1": - version: 2.3.1 - resolution: "yaml@npm:2.3.1" - checksum: 2c7bc9a7cd4c9f40d3b0b0a98e370781b68b8b7c4515720869aced2b00d92f5da1762b4ffa947f9e795d6cd6b19f410bd4d15fdd38aca7bd96df59bd9486fb54 - languageName: node - linkType: hard - -"yaml@npm:^2.3.2": - version: 2.3.2 - resolution: "yaml@npm:2.3.2" - checksum: acd80cc24df12c808c6dec8a0176d404ef9e6f08ad8786f746ecc9d8974968c53c6e8a67fdfabcc5f99f3dc59b6bb0994b95646ff03d18e9b1dcd59eccc02146 - languageName: node - linkType: hard - "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" From 707300d9a53b0a782c0d4759b7fa2ca38634ea31 Mon Sep 17 00:00:00 2001 From: Aleksey Tsalolikhin <66701226+atsalolikhin-spokeo@users.noreply.github.com> Date: Fri, 27 Oct 2023 16:42:42 -0700 Subject: [PATCH 41/81] Add "--name-only" to "git diff" autocomplete (#2128) Co-authored-by: Aleksey Tsalolikhin --- src/git.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/git.ts b/src/git.ts index f4921d492c8b..a84464f72508 100644 --- a/src/git.ts +++ b/src/git.ts @@ -6073,6 +6073,10 @@ const completionSpec: Fig.Spec = { description: "Shows number of added and deleted lines in decimal notation", }, + { + name: "--name-only", + description: "Show only names of changed files", + }, { name: "--shortstat", description: From 54fa2eaf5de6ed8d2455b0d6cde58e77732901a0 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Fri, 27 Oct 2023 23:44:27 +0000 Subject: [PATCH 42/81] ci: version bump to 2.640.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 13bf3949e7b8..ff9f21d91cbe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.640.0", + "version": "2.640.1", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 18d1cf2f6d222899ec6a0a66c1a81d377a942fe3 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Fri, 27 Oct 2023 23:49:59 -0700 Subject: [PATCH 43/81] @jpbnetley has signed the CLA in withfig/autocomplete#2153 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index e3f388bbe46b..74087da42981 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1007,6 +1007,14 @@ "created_at": "2023-10-26T17:33:01Z", "repoId": 299482335, "pullRequestNo": 2151 + }, + { + "name": "jpbnetley", + "id": 25173863, + "comment_id": 1783725071, + "created_at": "2023-10-28T06:49:43Z", + "repoId": 299482335, + "pullRequestNo": 2153 } ] } \ No newline at end of file From 9d930148384b6cd178e8cde2af3fa97cdb0b12f6 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:16:09 -0700 Subject: [PATCH 44/81] @diegofcornejo has signed the CLA in withfig/autocomplete#2158 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 74087da42981..2687f25f7ac0 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1015,6 +1015,14 @@ "created_at": "2023-10-28T06:49:43Z", "repoId": 299482335, "pullRequestNo": 2153 + }, + { + "name": "diegofcornejo", + "id": 7274655, + "comment_id": 1790084882, + "created_at": "2023-11-02T05:15:54Z", + "repoId": 299482335, + "pullRequestNo": 2158 } ] } \ No newline at end of file From 027cda2b4eb8dc7e111f07816d28a2f8fb7ef75d Mon Sep 17 00:00:00 2001 From: Brendan Falk Date: Thu, 2 Nov 2023 15:14:24 -0700 Subject: [PATCH 45/81] added single quotes around git commit shortcut --- src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git.ts b/src/git.ts index a84464f72508..cd641afc77bc 100644 --- a/src/git.ts +++ b/src/git.ts @@ -9738,7 +9738,7 @@ const completionSpec: Fig.Spec = { { name: "commit -m 'msg'", description: "Git commit shortcut", - insertValue: "commit -m {cursor}", + insertValue: "commit -m '{cursor}'", icon: "fig://template?color=2ecc71&badge=🔥", // type: "shortcut", }, From 6749f3d30c267f3af5fb1452a8e3143f2fb1e159 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Thu, 2 Nov 2023 22:15:41 +0000 Subject: [PATCH 46/81] ci: version bump to 2.640.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ff9f21d91cbe..c2c954cf688e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.640.1", + "version": "2.640.2", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 9ebe13794ab7e4e14f5562ba646c609b2bc8cba6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:30:29 -0700 Subject: [PATCH 47/81] build(deps-dev): bump eslint from 8.51.0 to 8.52.0 (#2157) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/yarn.lock b/yarn.lock index ecb9790e21aa..abd9aa0d4692 100644 --- a/yarn.lock +++ b/yarn.lock @@ -725,10 +725,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.51.0": - version: 8.51.0 - resolution: "@eslint/js@npm:8.51.0" - checksum: 0228bf1e1e0414843e56d9ff362a2a72d579c078f93174666f29315690e9e30a8633ad72c923297f7fd7182381b5a476805ff04dac8debe638953eb1ded3ac73 +"@eslint/js@npm:8.52.0": + version: 8.52.0 + resolution: "@eslint/js@npm:8.52.0" + checksum: 490893b8091a66415f4ac98b963d23eb287264ea3bd6af7ec788f0570705cf64fd6ab84b717785980f55e39d08ff5c7fde6d8e4391ccb507169370ce3a6d091a languageName: node linkType: hard @@ -829,14 +829,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.11": - version: 0.11.11 - resolution: "@humanwhocodes/config-array@npm:0.11.11" +"@humanwhocodes/config-array@npm:^0.11.13": + version: 0.11.13 + resolution: "@humanwhocodes/config-array@npm:0.11.13" dependencies: - "@humanwhocodes/object-schema": ^1.2.1 + "@humanwhocodes/object-schema": ^2.0.1 debug: ^4.1.1 minimatch: ^3.0.5 - checksum: db84507375ab77b8ffdd24f498a5b49ad6b64391d30dd2ac56885501d03964d29637e05b1ed5aefa09d57ac667e28028bc22d2da872bfcd619652fbdb5f4ca19 + checksum: f8ea57b0d7ed7f2d64cd3944654976829d9da91c04d9c860e18804729a33f7681f78166ef4c761850b8c324d362f7d53f14c5c44907a6b38b32c703ff85e4805 languageName: node linkType: hard @@ -847,10 +847,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^1.2.1": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 +"@humanwhocodes/object-schema@npm:^2.0.1": + version: 2.0.1 + resolution: "@humanwhocodes/object-schema@npm:2.0.1" + checksum: 24929487b1ed48795d2f08346a0116cc5ee4634848bce64161fb947109352c562310fd159fc64dda0e8b853307f5794605191a9547f7341158559ca3c8262a45 languageName: node linkType: hard @@ -1814,6 +1814,13 @@ __metadata: languageName: node linkType: hard +"@ungap/structured-clone@npm:^1.2.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 + languageName: node + linkType: hard + "@vitejs/plugin-react@npm:^4.1.0": version: 4.1.0 resolution: "@vitejs/plugin-react@npm:4.1.0" @@ -3722,16 +3729,17 @@ __metadata: linkType: hard "eslint@npm:^8.50.0": - version: 8.51.0 - resolution: "eslint@npm:8.51.0" + version: 8.52.0 + resolution: "eslint@npm:8.52.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.2 - "@eslint/js": 8.51.0 - "@humanwhocodes/config-array": ^0.11.11 + "@eslint/js": 8.52.0 + "@humanwhocodes/config-array": ^0.11.13 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 + "@ungap/structured-clone": ^1.2.0 ajv: ^6.12.4 chalk: ^4.0.0 cross-spawn: ^7.0.2 @@ -3764,7 +3772,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 214fa5d1fcb67af1b8992ce9584ccd85e1aa7a482f8b8ea5b96edc28fa838a18a3b69456db45fc1ed3ef95f1e9efa9714f737292dc681e572d471d02fda9649c + checksum: fd22d1e9bd7090e31b00cbc7a3b98f3b76020a4c4641f987ae7d0c8f52e1b88c3b268bdfdabac2e1a93513e5d11339b718ff45cbff48a44c35d7e52feba510ed languageName: node linkType: hard From 322eebdbc32d26bb1d5cac58ab22b0e672337dea Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sun, 5 Nov 2023 04:49:08 -0800 Subject: [PATCH 48/81] @vdmgolub has signed the CLA in withfig/autocomplete#1666 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 2687f25f7ac0..d74f90e13a72 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1023,6 +1023,14 @@ "created_at": "2023-11-02T05:15:54Z", "repoId": 299482335, "pullRequestNo": 2158 + }, + { + "name": "vdmgolub", + "id": 87082, + "comment_id": 1793728071, + "created_at": "2023-11-05T12:48:53Z", + "repoId": 299482335, + "pullRequestNo": 1666 } ] } \ No newline at end of file From e7c0e2702ed3fce774c95127192facaa6a29b213 Mon Sep 17 00:00:00 2001 From: Grant G Date: Mon, 6 Nov 2023 15:38:23 -0800 Subject: [PATCH 49/81] Update to new command api (#2161) --- .vscode/settings.json | 2 +- migrate.ts | 30 +++++ package.json | 4 +- src/@usermn/sdc/index.ts | 7 +- src/amplify.ts | 2 +- src/ansible-doc.ts | 2 +- src/ant.ts | 2 +- src/apt.ts | 17 ++- src/asdf.ts | 39 ++++--- src/assimp.ts | 4 +- src/aws-vault.ts | 2 +- src/aws.ts | 11 +- src/aws/acm.ts | 12 +- src/aws/amplify.ts | 42 +++---- src/aws/cloudformation.ts | 83 +++++++------ src/aws/cloudwatch.ts | 116 ++++++++++-------- src/aws/ec2.ts | 226 ++++++++++++++++++++++++++++-------- src/aws/ecs.ts | 72 +++++++----- src/aws/eks.ts | 46 ++++---- src/aws/elasticbeanstalk.ts | 54 +++++---- src/aws/iam.ts | 88 ++++++++------ src/aws/lambda.ts | 167 +++++++++++++++----------- src/aws/s3.ts | 28 ++--- src/aws/s3api.ts | 2 +- src/aws/secretsmanager.ts | 56 +++++---- src/bat.ts | 34 ++++-- src/bazel.ts | 6 +- src/black.ts | 2 +- src/bosh.ts | 2 +- src/brew.ts | 20 ++-- src/browser-sync.ts | 5 +- src/bun.ts | 17 ++- src/bundle.ts | 2 +- src/bunx.ts | 6 +- src/capacitor.ts | 9 +- src/cargo.ts | 139 ++++++++++++---------- src/cf.ts | 8 +- src/checkov.ts | 2 +- src/chown.ts | 19 ++- src/chsh.ts | 2 +- src/coda.ts | 6 +- src/composer.ts | 31 +++-- src/conda.ts | 8 +- src/copilot.ts | 2 +- src/cordova.ts | 4 +- src/dcli.ts | 4 +- src/defaultbrowser.ts | 2 +- src/defaults.ts | 2 +- src/degit.ts | 9 +- src/deno/generators.ts | 31 +++-- src/deployctl.ts | 6 +- src/deta.ts | 24 ++-- src/docker-compose.ts | 10 +- src/docker.ts | 57 +++++---- src/doppler.ts | 8 +- src/dotnet.ts | 7 +- src/dotnet/dotnet-add.ts | 16 ++- src/dotnet/dotnet-new.ts | 10 +- src/dotnet/dotnet-run.ts | 2 +- src/dotnet/dotnet-tool.ts | 20 +++- src/drush.ts | 6 +- src/dscacheutil.ts | 7 +- src/dscl.ts | 6 +- src/dtm.ts | 2 +- src/eb.ts | 2 +- src/elm-format.ts | 21 ++-- src/elm-json.ts | 9 +- src/elm-review.ts | 25 ++-- src/elm.ts | 9 +- src/env.ts | 15 +-- src/envchain.ts | 2 +- src/esbuild.ts | 12 +- src/eslint.ts | 5 +- src/example/trigger.ts | 8 +- src/expo-cli.ts | 18 ++- src/expo.ts | 18 ++- src/expressots.ts | 4 +- src/ffmpeg.ts | 18 +-- src/fig-teams.ts | 8 -- src/fig-teams@latest.ts | 119 ------------------- src/fig/index.ts | 8 +- src/fig/shared.ts | 154 ++++++++++++++---------- src/fin.ts | 20 ++-- src/firebase.ts | 2 +- src/fisher.ts | 2 +- src/flutter.ts | 4 +- src/flyctl.ts | 4 +- src/fnm.ts | 4 +- src/fvm.ts | 2 +- src/gem.ts | 20 ++-- src/gh.ts | 52 ++++++--- src/gibo.ts | 2 +- src/git-cliff.ts | 2 +- src/git-flow.ts | 26 +++-- src/git-profile.ts | 2 +- src/git.ts | 130 +++++++++++++++------ src/go.ts | 2 +- src/goto.ts | 10 +- src/gource.ts | 2 +- src/gpg.ts | 4 +- src/heroku.ts | 2 +- src/hexo.ts | 2 +- src/hugo.ts | 2 +- src/hyper.ts | 2 +- src/ibus.ts | 2 +- src/iconv.ts | 2 +- src/id.ts | 2 +- src/ignite-cli.ts | 2 +- src/infracost/index.ts | 8 +- src/ipatool.ts | 12 +- src/j.ts | 14 ++- src/jenv.ts | 14 ++- src/just.ts | 14 ++- src/k3d.ts | 8 +- src/k9s.ts | 2 +- src/kill.ts | 4 +- src/killall.ts | 4 +- src/kind.ts | 4 +- src/kool.ts | 4 +- src/kubectl.ts | 39 +++++-- src/kubectx.ts | 6 +- src/kubens.ts | 4 +- src/launchctl.ts | 2 +- src/lerna.ts | 16 +-- src/limactl.ts | 2 +- src/login.ts | 2 +- src/lsof.ts | 8 +- src/m.ts | 23 ++-- src/mackup.ts | 2 +- src/magento.ts | 8 +- src/make.ts | 19 ++- src/mamba.ts | 6 +- src/man.ts | 7 +- src/mask.ts | 20 +++- src/mdfind.ts | 33 ++++-- src/meteor.ts | 6 +- src/mix.ts | 4 +- src/mkinitcpio.ts | 2 +- src/mount.ts | 4 +- src/multipass.ts | 10 +- src/n.ts | 2 +- src/networkQuality.ts | 2 +- src/nextflow.ts | 18 ++- src/ng.ts | 2 +- src/node.ts | 11 +- src/npm.ts | 69 ++++++++--- src/npx.ts | 6 +- src/ns.ts | 11 +- src/nx.ts | 53 ++++++--- src/okteto.ts | 4 +- src/op.ts | 2 +- src/open.ts | 13 ++- src/pandoc.ts | 72 +++++++----- src/pass.ts | 31 +++-- src/passwd.ts | 2 +- src/php.ts | 41 +++++-- src/php/artisan.ts | 9 +- src/php/bin-console.ts | 7 +- src/php/please.ts | 7 +- src/phpunit-watcher.ts | 2 +- src/pip.ts | 2 +- src/pipx.ts | 2 +- src/pkgutil.ts | 18 ++- src/pnpm.ts | 15 ++- src/pre-commit.ts | 2 +- src/projj.ts | 20 +++- src/pulumi.ts | 2 +- src/pyenv.ts | 4 +- src/python.ts | 11 +- src/python3.ts | 10 +- src/quickmail.ts | 2 +- src/r.ts | 2 +- src/rails.ts | 26 ++++- src/rake.ts | 2 +- src/rancher.ts | 2 +- src/rbenv.ts | 4 +- src/rclone.ts | 2 +- src/react-native.ts | 18 +-- src/redwood.ts | 5 +- src/robot.ts | 22 +++- src/rugby.ts | 11 +- src/rush.ts | 5 +- src/rustup.ts | 23 ++-- src/scarb.ts | 48 +++++++- src/scc.ts | 32 +++-- src/serverless.ts | 10 +- src/shadcn-ui.ts | 12 +- src/shopify/index.ts | 8 +- src/shortcuts.ts | 4 +- src/snaplet.ts | 6 +- src/softwareupdate.ts | 2 +- src/spring.ts | 15 ++- src/ssh.ts | 41 +++++-- src/stepzen.ts | 7 +- src/svtplay-dl.ts | 2 +- src/sysctl.ts | 2 +- src/systemctl.ts | 32 +++-- src/tailscale.ts | 2 +- src/task.ts | 8 +- src/task/go-task.ts | 2 +- src/task/taskwarrior.ts | 16 +-- src/terraform.ts | 4 +- src/terragrunt.ts | 4 +- src/tfenv.ts | 4 +- src/tfsec.ts | 2 +- src/tldr.ts | 30 ++--- src/tmux.ts | 2 +- src/tmuxinator.ts | 4 +- src/tokei.ts | 2 +- src/trap.ts | 2 +- src/trex.ts | 4 +- src/tsh.ts | 6 +- src/tsuru.ts | 10 +- src/turbo.ts | 5 +- src/unset.ts | 2 +- src/v.ts | 2 +- src/valet.ts | 2 +- src/vercel.ts | 24 +--- src/vite.ts | 10 +- src/vr.ts | 9 +- src/vsce.ts | 2 +- src/vultr-cli.ts | 2 +- src/watson.ts | 6 +- src/wd.ts | 11 +- src/which.ts | 6 +- src/wifi-password.ts | 5 +- src/xc.ts | 8 +- src/xcodes.ts | 4 +- src/yalc.ts | 8 +- src/yarn.ts | 94 +++++++++++---- src/ykman.ts | 8 +- src/yo.ts | 2 +- src/youtube-dl.ts | 45 ++++--- src/z.ts | 48 +++++--- src/zellij.ts | 2 +- yarn.lock | 20 ++-- 236 files changed, 2481 insertions(+), 1480 deletions(-) create mode 100644 migrate.ts delete mode 100644 src/fig-teams.ts delete mode 100644 src/fig-teams@latest.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 6a0a4b2ce529..b24c139437d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,6 @@ "source.fixAll.eslint": true }, "editor.formatOnSave": true, - "deno.enablePaths": [".cicada"], + "deno.enablePaths": ["migrate.ts"], "deno.enable": true } diff --git a/migrate.ts b/migrate.ts new file mode 100644 index 000000000000..0ca3bfc51e81 --- /dev/null +++ b/migrate.ts @@ -0,0 +1,30 @@ +import { walkSync } from "https://deno.land/std/fs/walk.ts"; +import { split } from "npm:shlex"; + +const walk = walkSync("src"); + +for (const entry of walk) { + // console.log(entry.path); + + if (entry.isFile) { + const file = Deno.readTextFileSync(`${entry.path}`); + + const re = /script:\s"([^"]*)"/g; + const newFile = file.replaceAll(re, (match) => { + const a = re.exec(match); + if (a && a[1]) { + console.log(a[1]); + console.log(split(a[1])); + if (confirm("abc")) { + return `script: ${JSON.stringify(split(a[1]))}`; + } else { + return match; + } + } else { + return match; + } + }); + + Deno.writeTextFileSync(entry.path, newFile); + } +} diff --git a/package.json b/package.json index c2c954cf688e..1b8041c0fee2 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-react": "^4.1.0", "@withfig/autocomplete-tools": "^2.7.10", - "@withfig/autocomplete-types": "^1.28.0", + "@withfig/autocomplete-types": "^1.29.0", "autoprefixer": "^10.4.16", "chalk": "^5.3.0", "chokidar": "^3.5.3", @@ -96,7 +96,7 @@ "vite-plugin-externals": "^0.6.2" }, "dependencies": { - "@fig/autocomplete-generators": "^2.2.5", + "@fig/autocomplete-generators": "^2.3.0", "@fig/autocomplete-helpers": "^1.0.7", "@fig/autocomplete-hooks": "^1.0.2", "@withfig/api-bindings": "^0.30.3", diff --git a/src/@usermn/sdc/index.ts b/src/@usermn/sdc/index.ts index 79078c2bd6d6..406588fe6f63 100644 --- a/src/@usermn/sdc/index.ts +++ b/src/@usermn/sdc/index.ts @@ -3,6 +3,11 @@ const versionFiles = ["0.0.0"]; export const getVersionCommand: Fig.GetVersionCommand = async ( executeShellCommand ) => { - return await executeShellCommand("npx @usermn/sdc --version"); + return ( + await executeShellCommand({ + command: "npx", + args: ["@usermn/sdc", "--version"], + }) + ).stdout; }; export default createVersionedSpec("@usermn/sdc", versionFiles); diff --git a/src/amplify.ts b/src/amplify.ts index e9e7a055b1c9..3fa44095a97b 100644 --- a/src/amplify.ts +++ b/src/amplify.ts @@ -1,5 +1,5 @@ const envNameGenerator: Fig.Generator = { - script: "amplify env list --json", + script: ["amplify", "env", "list", "--json"], postProcess: function (out) { const envContent = JSON.parse(out); return envContent["envs"].map((env: string) => { diff --git a/src/ansible-doc.ts b/src/ansible-doc.ts index 063f0beaf083..1dc72912eb97 100644 --- a/src/ansible-doc.ts +++ b/src/ansible-doc.ts @@ -1,5 +1,5 @@ const allPluginsGenerator: Fig.Generator = { - script: "ansible-doc --list --json 2>/dev/null", + script: ["ansible-doc", "--list", "--json"], postProcess: function (output) { const plugins = JSON.parse(output); return Object.keys(plugins).map((key) => ({ diff --git a/src/ant.ts b/src/ant.ts index f8976b5c909e..99e72de90bc9 100644 --- a/src/ant.ts +++ b/src/ant.ts @@ -1,5 +1,5 @@ const tasksGenerator: Fig.Generator = { - script: "command ant -p | grep -i '^\\s' | tr -d ' '", + script: ["bash", "-c", "command ant -p | grep -i '^\\s' | tr -d ' '"], postProcess: (out) => out.split("\n").map((task) => ({ name: task, diff --git a/src/apt.ts b/src/apt.ts index 3ef740dbf989..9af3741ca287 100644 --- a/src/apt.ts +++ b/src/apt.ts @@ -11,13 +11,18 @@ const packages: Fig.Generator = { if (finalToken.length === 0) { return []; } + const { stdout } = await executeShellCommand({ + command: "apt", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["list"], + }); + // Only lines matching the first character, delete characters after '/' - const out = await executeShellCommand( - `apt list | grep '^${finalToken[0]}' | sed 's#/.*##g'` - ); - return out + return stdout .trim() .split("\n") + .filter((name) => name.startsWith(finalToken)) + .map((name) => name.replace(/\/.*/, "")) .map((name) => ({ name, description: "Package", @@ -30,7 +35,7 @@ const packages: Fig.Generator = { }; const installedPackages: Fig.Generator = { - script: "apt list --installed", + script: ["apt", "list", "--installed"], postProcess: function (a) { return a .trim() @@ -46,7 +51,7 @@ const installedPackages: Fig.Generator = { }; const upgradablePackages: Fig.Generator = { - script: "apt list --upgradable", + script: ["apt", "list", "--upgradable"], postProcess: function (a) { return a .trim() diff --git a/src/asdf.ts b/src/asdf.ts index 53eaeb2647ee..2de3174d5c1d 100644 --- a/src/asdf.ts +++ b/src/asdf.ts @@ -1,6 +1,4 @@ const PRIORITY_TOP_THRESHOLD = 76; -const LS_BIN = "/bin/ls"; -const ASDF_DATA_DIR = "~/.asdf"; const HOUR_IN_MILLISECONDS = 3600000; /* @@ -9,7 +7,7 @@ const HOUR_IN_MILLISECONDS = 3600000; const installedPluginNamesGenerator = ( suggestOptions?: Partial ): Fig.Generator => ({ - script: "asdf plugin-list", + script: ["asdf", "plugin-list"], postProcess: (output) => output.split("\n").map((pluginName) => ({ name: `${pluginName}`, @@ -24,15 +22,23 @@ const allPluginNamesGenerator = ( suggestOptions?: Partial ): Fig.Generator => ({ // If use `asdf plugin-list-all`, it will time out, so use `ls`. - script: `${LS_BIN} -1 ${ASDF_DATA_DIR}/repository/plugins`, - postProcess: (output) => - output.split("\n").map((pluginName) => ({ + custom: async (_, executeCommand, generatorContext) => { + const { stdout } = await executeCommand({ + command: "ls", + args: [ + "-1", + `${generatorContext.environmentVariables["HOME"]}/.asdf/repository/plugins`, + ], + }); + + return stdout.split("\n").map((pluginName) => ({ name: `${pluginName}`, description: "Plugin name", priority: PRIORITY_TOP_THRESHOLD, icon: "fig://icon?type=package", ...suggestOptions, - })), + })); + }, }); const installedPluginVersionsGenerator = ( @@ -41,7 +47,7 @@ const installedPluginVersionsGenerator = ( ): Fig.Generator => ({ script: (context) => { const pluginName = context[context.length - 2]; - return `asdf list ${pluginName}`; + return ["asdf", "list", pluginName]; }, postProcess: (output) => output @@ -63,7 +69,7 @@ const allPluginVersionsGenerator = ( ): Fig.Generator => ({ script: (context) => { const pluginName = context[context.length - 2]; - return `asdf list-all ${pluginName}`; + return ["asdf", "list-all", pluginName]; }, cache: { ttl: HOUR_IN_MILLISECONDS, @@ -86,15 +92,22 @@ const shimNamesGenerator = ( suggestOptions?: Partial ): Fig.Generator => ({ // Use `ls` because there is no command to get shims in `asdf`. - script: `${LS_BIN} -1 ${ASDF_DATA_DIR}/shims`, - postProcess: (output) => - output.split("\n").map((shimName) => ({ + custom: async (_, executeCommand, generatorContext) => { + const { stdout } = await executeCommand({ + command: "ls", + args: [ + "-1", + `${generatorContext.environmentVariables["HOME"]}/.asdf/shims`, + ], + }); + return stdout.split("\n").map((shimName) => ({ name: `${shimName}`, description: "Shim name", priority: PRIORITY_TOP_THRESHOLD, icon: "fig://icon?type=command", ...suggestOptions, - })), + })); + }, }); /* diff --git a/src/assimp.ts b/src/assimp.ts index 52698f690486..163a31ed8033 100644 --- a/src/assimp.ts +++ b/src/assimp.ts @@ -21,7 +21,7 @@ const commonOptions: Fig.Option[] = [ ]; const importExtGenerator: Fig.Generator = { - script: "assimp listext", + script: ["assimp", "listext"], postProcess: function (out) { return out.split(";").map((ext) => { return { @@ -33,7 +33,7 @@ const importExtGenerator: Fig.Generator = { }; const exportExtGenerator: Fig.Generator = { - script: "assimp listexport", + script: ["assimp", "listexport"], postProcess: function (out) { return out.split("\n").map((ext) => { return { diff --git a/src/aws-vault.ts b/src/aws-vault.ts index c6b76a35ba5e..dea41f6563c4 100644 --- a/src/aws-vault.ts +++ b/src/aws-vault.ts @@ -1,5 +1,5 @@ const profilesGenerator: Fig.Generator = { - script: "aws-vault list --profiles", + script: ["aws-vault", "list", "--profiles"], postProcess(out) { return out.split("\n").map((name) => ({ name })); }, diff --git a/src/aws.ts b/src/aws.ts index 97dee14c8924..dcf46eed5a7c 100644 --- a/src/aws.ts +++ b/src/aws.ts @@ -3,7 +3,7 @@ export const awsProfileGenerator: Fig.Generator = { strategy: "stale-while-revalidate", cacheByDirectory: true, }, - script: "aws configure list-profiles", + script: ["aws", "configure", "list-profiles"], postProcess: function (out) { if (out.trim() == "") { return []; @@ -19,10 +19,11 @@ export const awsProfileGenerator: Fig.Generator = { const completionSpec: Fig.Spec = { name: "aws", async generateSpec(_, executeShellCommand) { - const check = await executeShellCommand( - "ls ~/.aws/credentials && ls ~/.aws/config" - ); - const prioritize = check.includes("No such file or directory"); + const { stdout } = await executeShellCommand({ + command: "bash", + args: ["-c", "ls ~/.aws/credentials && ls ~/.aws/config"], + }); + const prioritize = stdout.includes("No such file or directory"); return { name: "aws", subcommands: [ diff --git a/src/aws/acm.ts b/src/aws/acm.ts index 4963d8afbd18..dd4e8af97a82 100644 --- a/src/aws/acm.ts +++ b/src/aws/acm.ts @@ -31,12 +31,12 @@ const postPrecessGenerator = ( const _prefixFile = "file://"; const _prefixBlob = "fileb://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -51,7 +51,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -157,7 +157,7 @@ const generators: Record = { }, listCertificates: { - script: "aws acm list-certificates", + script: ["aws", "acm", "list-certificates"], postProcess: (out) => { return postPrecessGenerator( out, @@ -168,7 +168,7 @@ const generators: Record = { }, listCertificateAuthorities: { - script: "aws acm-pca list-certificate-authorities", + script: ["aws", "acm-pca", "list-certificate-authorities"], postProcess: (out) => { return postPrecessGenerator(out, "CertificateAuthorities", "Arn"); }, diff --git a/src/aws/amplify.ts b/src/aws/amplify.ts index ee64fbd3f6a4..3e2652c2641b 100644 --- a/src/aws/amplify.ts +++ b/src/aws/amplify.ts @@ -38,28 +38,30 @@ const postPrecessGenerator = ( const customGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws amplify ${command}`; + let args = ["amplify", command]; - for (let i = 0; i < options.length; i++) { - const option = options[i]; + for (const option of options) { const idx = tokens.indexOf(option); if (idx < 0) { continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -70,8 +72,8 @@ const customGenerator = async ( ]; } - return list.map((elm) => { - const name = (childKey ? elm[childKey] : elm) as string; + return list.map((resource) => { + const name = (childKey ? resource[childKey] : resource) as string; return { name, icon: "fig://icon?type=aws", @@ -85,12 +87,12 @@ const customGenerator = async ( const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -105,7 +107,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -194,7 +196,7 @@ const generators: Record = { }, listAmplifyServiceRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => { try { const list = JSON.parse(out)["Roles"]; @@ -223,21 +225,21 @@ const generators: Record = { }, listAmplifyAppIds: { - script: "aws amplify list-apps", + script: ["aws", "amplify", "list-apps"], postProcess: (out) => { return postPrecessGenerator(out, "apps", "appId"); }, }, listAmplifyAppArns: { - script: "aws amplify list-apps", + script: ["aws", "amplify", "list-apps"], postProcess: (out) => { return postPrecessGenerator(out, "apps", "appArn"); }, }, listCfnStackNames: { - script: "aws cloudformation list-stacks", + script: ["aws", "cloudformation", "list-stacks"], postProcess: (out) => { return postPrecessGenerator(out, "StackSummaries", "StackName"); }, @@ -309,7 +311,7 @@ const generators: Record = { }, listIamRoleArns: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => { return postPrecessGenerator(out, "Roles", "Arn"); }, @@ -342,14 +344,14 @@ const generators: Record = { }, listWebhookIds: { - script: "aws amplify list-webhooks", + script: ["aws", "amplify", "list-webhooks"], postProcess: (out) => { return postPrecessGenerator(out, "webhooks", "webhookId"); }, }, listAllBranches: { - script: "aws amplify list-apps", + script: ["aws", "amplify", "list-apps"], postProcess: (out) => { try { const list = JSON.parse(out)["Roles"]; diff --git a/src/aws/cloudformation.ts b/src/aws/cloudformation.ts index 42c64a8edba4..708771e51e08 100644 --- a/src/aws/cloudformation.ts +++ b/src/aws/cloudformation.ts @@ -59,28 +59,30 @@ const postPrecessGenerator = ( const customGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws cloudformation ${command}`; + let args = ["cloudformation", command]; - for (let i = 0; i < options.length; i++) { - const option = options[i]; + for (const option of options) { const idx = tokens.indexOf(option); if (idx < 0) { continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -106,7 +108,7 @@ const customGenerator = async ( const customGeneratorWithFilter = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, @@ -114,21 +116,23 @@ const customGeneratorWithFilter = async ( filter: string ): Promise => { try { - let cmd = `aws cloudformation ${command}`; + let args = ["cloudformation", command]; - for (let i = 0; i < options.length; i++) { - const option = options[i]; + for (const option of options) { const idx = tokens.indexOf(option); if (idx < 0) { continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; return list .filter((resource) => { @@ -147,12 +151,12 @@ const customGeneratorWithFilter = async ( const _prefixFile = "file://"; const _prefixS3 = "s3://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -167,7 +171,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -273,7 +277,7 @@ const generators: Record = { listRemoteFilesGenerator: { script: (tokens) => { const whatHasUserTyped = tokens[tokens.length - 1]; - const baseLSCommand = "\\aws s3 ls "; + const baseLsCommand = ["aws", "s3", "ls"]; let folderPath = ""; @@ -284,17 +288,17 @@ const generators: Record = { // then we can assume that the filepath generator is in work // so do not return any s3 related filepaths if (!_prefixS3.startsWith(whatHasUserTyped)) { - return ""; + return undefined; } - return "echo 's3://'"; + return ["echo", "s3://"]; } if (lastSlashIndex > -1) { folderPath = whatHasUserTyped.slice(0, lastSlashIndex + 1); } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }, postProcess: (out) => { if (out == "") { @@ -373,7 +377,7 @@ const generators: Record = { }, listCfnStackIds: { - script: "aws cloudformation list-stacks", + script: ["aws", "cloudformation", "list-stacks"], postProcess: (out) => { return postPrecessGenerator(out, "StackSummaries", "StackId"); }, @@ -434,42 +438,42 @@ const generators: Record = { }, listCfnStackSets: { - script: "aws cloudformation list-stack-sets", + script: ["aws", "cloudformation", "list-stack-sets"], postProcess: (out) => { return postPrecessGenerator(out, "Summaries", "StackSetId"); }, }, listCfnChangeSets: { - script: "aws cloudformation list-change-sets", + script: ["aws", "cloudformation", "list-change-sets"], postProcess: (out) => { return postPrecessGenerator(out, "Summaries", "ChangeSetId"); }, }, listRoleArns: { - script: "aws iam list-roles --page-size 100", + script: ["aws", "iam", "list-roles", "--page-size", "100"], postProcess: (out) => { return postPrecessGenerator(out, "Roles", "Arn"); }, }, listRoles: { - script: "aws iam list-roles --page-size 100", + script: ["aws", "iam", "list-roles", "--page-size", "100"], postProcess: (out) => { return postPrecessGenerator(out, "Roles", "RoleName"); }, }, listSNSTopics: { - script: "aws sns list-topics", + script: ["aws", "sns", "list-topics"], postProcess: (out) => { return postPrecessGenerator(out, "Topics", "TopicArn"); }, }, getAccountId: { - script: "aws sts get-caller-identity", + script: ["aws", "sts", "get-caller-identity"], postProcess: function (out) { try { const accountId = JSON.parse(out)["Account"]; @@ -482,7 +486,7 @@ const generators: Record = { }, listTypeArns: { - script: "aws cloudformation list-types", + script: ["aws", "cloudformation", "list-types"], postProcess: function (out) { return postPrecessGenerator(out, "TypeSummaries", "TypeArn"); }, @@ -522,10 +526,17 @@ const generators: Record = { return []; } const param = tokens[idx + 1]; - const cmd = `aws cloudformation describe-change-set --change-set-name ${param}`; - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args: [ + "cloudformation", + "describe-change-set", + "--change-set-name", + param, + ], + }); - const stackId = JSON.parse(out)["StackId"]; + const stackId = JSON.parse(stdout)["StackId"]; return [ { @@ -541,14 +552,14 @@ const generators: Record = { }, listExportNames: { - script: "aws cloudformation list-exports", + script: ["aws", "cloudformation", "list-exports"], postProcess: function (out) { return postPrecessGenerator(out, "Exports", "Name"); }, }, listBuckets: { - script: "aws s3 ls --page-size 1000", + script: ["aws", "s3", "ls", "--page-size", "1000"], postProcess: function (out, tokens) { try { return out.split("\n").map((line) => { @@ -569,7 +580,7 @@ const generators: Record = { }, listKmsKeys: { - script: "aws kms list-keys --page-size 100", + script: ["aws", "kms", "list-keys", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Keys", "KeyId"); }, diff --git a/src/aws/cloudwatch.ts b/src/aws/cloudwatch.ts index dea4189108bc..dbf8102022d8 100644 --- a/src/aws/cloudwatch.ts +++ b/src/aws/cloudwatch.ts @@ -177,14 +177,14 @@ const postPrecessGenerator = ( const listCustomGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws cloudwatch ${command}`; + let args = ["cloudwatch", command]; for (let i = 0; i < options.length; i++) { const option = options[i]; @@ -193,12 +193,15 @@ const listCustomGenerator = async ( continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -209,15 +212,13 @@ const listCustomGenerator = async ( ]; } - return list - .map((elm) => { - const name = (childKey ? elm[childKey] : elm) as string; - return { - name, - icon: "fig://icon?type=aws", - }; - }) - .filter(uniqueNames); + return list.map((elm) => { + const name = (childKey ? elm[childKey] : elm) as string; + return { + name, + icon: "fig://icon?type=aws", + }; + }); } catch (e) { console.log(e); } @@ -226,7 +227,7 @@ const listCustomGenerator = async ( const listDimensionTypes = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, option: string, parentKey: string, @@ -237,11 +238,13 @@ const listDimensionTypes = async ( if (idx < 0) { return []; } - const cmd = `aws cloudwatch ${command} ${option} ${tokens[idx + 1]}`; - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["cloudwatch", command, option, tokens[idx + 1]], + }); - const metrics = JSON.parse(out)[parentKey]; + const metrics = JSON.parse(stdout)[parentKey]; // traverse JSON & compose key-value style suggestion return metrics @@ -265,22 +268,29 @@ const listDimensionTypes = async ( const MultiSuggestionsGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - enabled: Record[] + executeShellCommand: Fig.ExecuteCommandFunction, + enabled: { + command: string[]; + parentKey: string; + childKey: string; + }[] ) => { try { const list: Fig.Suggestion[][] = []; const promises: Promise[] = []; for (let i = 0; i < enabled.length; i++) { - promises[i] = executeShellCommand(enabled[i]["command"]); + promises[i] = executeShellCommand({ + command: "aws", + args: enabled[i].command, + }).then(({ stdout }) => stdout); } const result = await Promise.all(promises); for (let i = 0; i < enabled.length; i++) { list[i] = postPrecessGenerator( result[i], - enabled[i]["parentKey"], - enabled[i]["childKey"] + enabled[i].parentKey, + enabled[i].childKey ); } @@ -293,22 +303,25 @@ const MultiSuggestionsGenerator = async ( const getResultList = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - command: string, + executeShellCommand: Fig.ExecuteCommandFunction, + args: string[], key: string ): Promise => { - const out = await executeShellCommand(command); - return JSON.parse(out)[key]; + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); + return JSON.parse(stdout)[key]; }; const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -323,7 +336,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -415,28 +428,28 @@ const generators: Record = { }, listAlarms: { - script: "aws cloudwatch describe-alarms", + script: ["aws", "cloudwatch", "describe-alarms"], postProcess: (out) => { return postPrecessGenerator(out, "MetricAlarms", "AlarmName"); }, }, listAlarmArns: { - script: "aws cloudwatch describe-alarms", + script: ["aws", "cloudwatch", "describe-alarms"], postProcess: (out) => { return postPrecessGenerator(out, "MetricAlarms", "AlarmArn"); }, }, listAdNamespaces: { - script: "aws cloudwatch describe-anomaly-detectors", + script: ["aws", "cloudwatch", "describe-anomaly-detectors"], postProcess: (out) => { return postPrecessGenerator(out, "AnomalyDetectors", "Namespace"); }, }, listMetricNamespaces: { - script: "aws cloudwatch list-metrics", + script: ["aws", "cloudwatch", "list-metrics"], postProcess: (out) => { return postPrecessGenerator(out, "Metrics", "Namespace"); }, @@ -495,35 +508,35 @@ const generators: Record = { }, listDashboards: { - script: "aws cloudwatch list-dashboards", + script: ["aws", "cloudwatch", "list-dashboards"], postProcess: (out) => { return postPrecessGenerator(out, "DashboardEntries", "DashboardName"); }, }, listInsightRules: { - script: "aws cloudwatch describe-insight-rules", + script: ["aws", "cloudwatch", "describe-insight-rules"], postProcess: (out) => { return postPrecessGenerator(out, "InsightRules", "Name"); }, }, listMetricStreams: { - script: "aws cloudwatch list-metric-streams", + script: ["aws", "cloudwatch", "list-metric-streams"], postProcess: (out) => { return postPrecessGenerator(out, "Entries", "Name"); }, }, listMetrics: { - script: "aws cloudwatch list-metrics", + script: ["aws", "cloudwatch", "list-metrics"], postProcess: (out) => { return postPrecessGenerator(out, "Metrics", "MetricName"); }, }, listSNSTopics: { - script: "aws sns list-topics", + script: ["aws", "sns", "list-topics"], postProcess: (out) => { return postPrecessGenerator(out, "Topics", "TopicArn"); }, @@ -535,19 +548,22 @@ const generators: Record = { // individually, to get an ARN custom: async function (tokens, executeShellCommand) { // get list of stream names - const result = await Promise.all([ - getResultList( - tokens, - executeShellCommand, - "aws firehose list-delivery-streams", - "DeliveryStreamNames" - ), - ]); + const result = await getResultList( + tokens, + executeShellCommand, + ["firehose", "list-delivery-streams"], + "DeliveryStreamNames" + ); // construct "query" const objects = result.flat().map((stream) => { return { - command: `aws firehose describe-delivery-stream --delivery-stream-name ${stream}`, + command: [ + "firehose", + "describe-delivery-stream", + "--delivery-stream-name", + Array.isArray(stream.name) ? stream.name[0] : stream.name, + ], parentKey: "DeliveryStreamDescription", childKey: "DeliveryStreamARN", }; @@ -561,7 +577,7 @@ const generators: Record = { }, listRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => { return postPrecessGenerator(out, "Roles", "Arn"); }, diff --git a/src/aws/ec2.ts b/src/aws/ec2.ts index f8bd84be1bb1..73d451247169 100644 --- a/src/aws/ec2.ts +++ b/src/aws/ec2.ts @@ -12,127 +12,261 @@ const postProcessAWS: Fig.Generator["postProcess"] = (out) => { }; const awsGenerators: Record = { instances: { - script: - "aws ec2 describe-instances --query 'Reservations[*].Instances[].InstanceId'", + script: [ + "aws", + "ec2", + "describe-instances", + "--query", + "Reservations[*].Instances[].InstanceId", + ], postProcess: postProcessAWS, }, rtb: { - script: - "aws ec2 describe-route-tables --query 'RouteTables[*].RouteTableId'", + script: [ + "aws", + "ec2", + "describe-route-tables", + "--query", + "RouteTables[*].RouteTableId", + ], postProcess: postProcessAWS, }, start: { - script: - "aws ec2 describe-instances --filters 'Name=instance-state-name,Values=stopped' --query 'Reservations[*].Instances[].InstanceId'", + script: [ + "aws", + "ec2", + "describe-instances", + "--filters", + "Name=instance-state-name,Values=stopped", + "--query", + "Reservations[*].Instances[].InstanceId", + ], postProcess: postProcessAWS, }, stop: { - script: - "aws ec2 describe-instances --filters 'Name=instance-state-name,Values=running' --query 'Reservations[*].Instances[].InstanceId'", + script: [ + "aws", + "ec2", + "describe-instances", + "--filters", + "Name=instance-state-name,Values=running", + "--query", + "Reservations[*].Instances[].InstanceId", + ], postProcess: postProcessAWS, }, volume_id: { - script: "aws ec2 describe-volumes --query 'Volumes[*].VolumeId'", + script: [ + "aws", + "ec2", + "describe-volumes", + "--query", + "Volumes[*].VolumeId", + ], postProcess: postProcessAWS, }, reserved_instance_id: { - script: - "aws ec2 describe-reserved-instances --query 'ReservedInstances[*].ReservedInstancesId'", + script: [ + "aws", + "ec2", + "describe-reserved-instances", + "--query", + "ReservedInstances[*].ReservedInstancesId", + ], postProcess: postProcessAWS, }, transit_gateway_multicast_domain_id: { - script: - "aws ec2 describe-transit-gateway-multicast-domains --query 'TransitGatewayMulticastDomains[*].TransitGatewayMulticastDomainId'", + script: [ + "aws", + "ec2", + "describe-transit-gateway-multicast-domains", + "--query", + "TransitGatewayMulticastDomains[*].TransitGatewayMulticastDomainId", + ], postProcess: postProcessAWS, }, transit_gateway_attachment_id: { - script: - "aws ec2 describe-transit-gateway-attachments --query 'TransitGatewayAttachments[*].TransitGatewayAttachmentId'", + script: [ + "aws", + "ec2", + "describe-transit-gateway-attachments", + "--query", + "TransitGatewayAttachments[*].TransitGatewayAttachmentId", + ], postProcess: postProcessAWS, }, vpc_id: { - script: "aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[*].VpcId'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoints", + "--query", + "VpcEndpoints[*].VpcId", + ], postProcess: postProcessAWS, }, vpc_endpoint_id: { - script: - "aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[*].VpcEndpointId'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoints", + "--query", + "VpcEndpoints[*].VpcEndpointId", + ], postProcess: postProcessAWS, }, subnet_ids: { - script: - "aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[*].SubnetIds'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoints", + "--query", + "VpcEndpoints[*].SubnetIds", + ], postProcess: postProcessAWS, }, route_table_ids: { - script: - "aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[*].RouteTableIds'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoints", + "--query", + "VpcEndpoints[*].RouteTableIds", + ], postProcess: postProcessAWS, }, network_interface_ids: { - script: - "aws ec2 describe-vpc-endpoints --query 'VpcEndpoints[*].NetworkInterfaceIds'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoints", + "--query", + "VpcEndpoints[*].NetworkInterfaceIds", + ], postProcess: postProcessAWS, }, instance_type: { - script: - "aws ec2 describe-instance-types --query 'InstanceTypes[*].InstanceType'", + script: [ + "aws", + "ec2", + "describe-instance-types", + "--query", + "InstanceTypes[*].InstanceType", + ], postProcess: postProcessAWS, }, snapshot_ids: { - script: "aws ec2 describe-snapshots --query 'Snapshots[*].SnapshotId'", + script: [ + "aws", + "ec2", + "describe-snapshots", + "--query", + "Snapshots[*].SnapshotId", + ], postProcess: postProcessAWS, }, vpc_peering_connection_id: { - script: - "aws ec2 describe-vpc-peering-connections --query 'VpcPeeringConnections[*].VpcPeeringConnectionId'", + script: [ + "aws", + "ec2", + "describe-vpc-peering-connections", + "--query", + "VpcPeeringConnections[*].VpcPeeringConnectionId", + ], postProcess: postProcessAWS, }, service_id: { - script: - "aws ec2 describe-vpc-endpoint-services --query 'ServiceDetails[*].ServiceId'", + script: [ + "aws", + "ec2", + "describe-vpc-endpoint-services", + "--query", + "ServiceDetails[*].ServiceId", + ], postProcess: postProcessAWS, }, cidr_block: { - script: "aws ec2 describe-subnets --query 'Subnets[*].CidrBlock'", + script: [ + "aws", + "ec2", + "describe-subnets", + "--query", + "Subnets[*].CidrBlock", + ], postProcess: postProcessAWS, }, image_id: { - script: "aws ec2 describe-images --query 'Images[*].ImageId'", + script: ["aws", "ec2", "describe-images", "--query", "Images[*].ImageId"], postProcess: postProcessAWS, }, key_pair: { - script: "aws ec2 describe-key-pairs --query 'KeyPairs[*].KeyName'", + script: [ + "aws", + "ec2", + "describe-key-pairs", + "--query", + "KeyPairs[*].KeyName", + ], postProcess: postProcessAWS, }, internet_gateway_id: { - script: - "aws ec2 describe-internet-gateways --query 'InternetGateways[*].InternetGatewayId'", + script: [ + "aws", + "ec2", + "describe-internet-gateways", + "--query", + "InternetGateways[*].InternetGatewayId", + ], postProcess: postProcessAWS, }, region_name: { - script: - "aws ec2 describe-availability-zones --query 'AvailabilityZones[*].RegionName'", + script: [ + "aws", + "ec2", + "describe-availability-zones", + "--query", + "AvailabilityZones[*].RegionName", + ], postProcess: postProcessAWS, }, zone_name: { - script: - "aws ec2 describe-availability-zones --query 'AvailabilityZones[*].ZoneName'", + script: [ + "aws", + "ec2", + "describe-availability-zones", + "--query", + "AvailabilityZones[*].ZoneName", + ], postProcess: postProcessAWS, }, zone_id: { - script: - "aws ec2 describe-availability-zones --query 'AvailabilityZones[*].ZoneId'", + script: [ + "aws", + "ec2", + "describe-availability-zones", + "--query", + "AvailabilityZones[*].ZoneId", + ], postProcess: postProcessAWS, }, group_name: { - script: - "aws ec2 describe-availability-zones --query 'AvailabilityZones[*].GroupName'", + script: [ + "aws", + "ec2", + "describe-availability-zones", + "--query", + "AvailabilityZones[*].GroupName", + ], postProcess: postProcessAWS, }, network_border_group: { - script: - "aws ec2 describe-availability-zones --query 'AvailabilityZones[*].NetworkBorderGroup'", + script: [ + "aws", + "ec2", + "describe-availability-zones", + "--query", + "AvailabilityZones[*].NetworkBorderGroup", + ], postProcess: postProcessAWS, }, }; diff --git a/src/aws/ecs.ts b/src/aws/ecs.ts index 92abed3bdd56..87cbc7ac5b11 100644 --- a/src/aws/ecs.ts +++ b/src/aws/ecs.ts @@ -57,14 +57,14 @@ const postPrecessGenerator = ( const customGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws ecs ${command}`; + let args = ["ecs", command]; for (const option of options) { const idx = tokens.indexOf(option); @@ -72,12 +72,15 @@ const customGenerator = async ( continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -103,22 +106,29 @@ const customGenerator = async ( const MultiSuggestionsGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - enabled: Record[] + executeShellCommand: Fig.ExecuteCommandFunction, + enabled: { + command: string[]; + parentKey: string; + childKey: string; + }[] ) => { try { const list: Fig.Suggestion[][] = []; const promises: Promise[] = []; for (let i = 0; i < enabled.length; i++) { - promises[i] = executeShellCommand(enabled[i]["command"]); + promises[i] = executeShellCommand({ + command: "aws", + args: enabled[i].command, + }).then(({ stdout }) => stdout); } const result = await Promise.all(promises); for (let i = 0; i < enabled.length; i++) { list[i] = postPrecessGenerator( result[i], - enabled[i]["parentKey"], - enabled[i]["childKey"] + enabled[i].parentKey, + enabled[i].childKey ); } @@ -131,12 +141,12 @@ const MultiSuggestionsGenerator = async ( const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -151,7 +161,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -255,18 +265,18 @@ const generators = { }, listCapacityProviders: { - script: "aws ecs describe-capacity-providers", + script: ["aws", "ecs", "describe-capacity-providers"], postProcess: (out) => postPrecessGenerator(out, "capacityProviders", "name"), }, listClusters: { - script: "aws ecs list-clusters", + script: ["aws", "ecs", "list-clusters"], postProcess: (out) => postPrecessGenerator(out, "clusterArns"), }, listTaskDefinitions: { - script: "aws ecs list-task-definitions", + script: ["aws", "ecs", "list-task-definitions"], postProcess: (out) => postPrecessGenerator(out, "taskDefinitionArns"), }, @@ -283,32 +293,38 @@ const generators = { }, listRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => postPrecessGenerator(out, "Roles", "RoleName"), }, listServices: { - script: "aws ecs list-services", + script: ["aws", "ecs", "list-services"], postProcess: (out) => postPrecessGenerator(out, "serviceArns"), }, listUsers: { - script: "aws iam list-users", + script: ["aws", "iam", "list-users"], postProcess: (out) => postPrecessGenerator(out, "Users", "Arn"), }, listContainerInstances: { - script: "aws ecs list-container-instances", + script: ["aws", "ecs", "list-container-instances"], postProcess: (out) => postPrecessGenerator(out, "containerInstanceArns"), }, listTasks: { - script: "aws ecs list-tasks", + script: ["aws", "ecs", "list-tasks"], postProcess: (out) => postPrecessGenerator(out, "taskArns"), }, listAttributeNames: { - script: "aws ecs list-attributes --target-type container-instance", + script: [ + "aws", + "ecs", + "list-attributes", + "--target-type", + "container-instance", + ], postProcess: (out) => postPrecessGenerator(out, "attributes", "name"), }, @@ -325,7 +341,7 @@ const generators = { }, listTaskDefinitionFamilies: { - script: "aws ecs list-task-definition-families", + script: ["aws", "ecs", "list-task-definition-families"], postProcess: (out) => postPrecessGenerator(out, "families"), }, @@ -334,7 +350,7 @@ const generators = { const out = await executeShellCommand("aws ecs list-tasks"); const list = JSON.parse(out)["taskArns"]; const tasks = list.map((arn) => ({ - command: `aws ecs describe-tasks --tasks ${arn}`, + command: ["ecs", "describe-tasks", "--tasks", arn], parentKey: "tasks", childKey: "startedBy", })); @@ -355,7 +371,7 @@ const generators = { ); const list = JSON.parse(out)["taskArns"]; const tasks = list.map((arn) => ({ - command: `aws ecs describe-tasks --tasks ${arn}`, + command: ["ecs", "describe-tasks", "--tasks", arn], parentKey: "tasks", childKey: "group", })); @@ -368,7 +384,7 @@ const generators = { customGenerator( out, executeShellCommand, - "aws ecs list-tags-for-resource", + "list-tags-for-resource", ["--resource-arn"], "tags", "key" @@ -376,7 +392,7 @@ const generators = { }, listCodedeployApplications: { - script: "aws deploy list-applications", + script: ["aws", "deploy", "list-applications"], postProcess: (out) => postPrecessGenerator(out, "applications"), }, diff --git a/src/aws/eks.ts b/src/aws/eks.ts index cf051643a8f4..4ccc050d96a8 100644 --- a/src/aws/eks.ts +++ b/src/aws/eks.ts @@ -32,14 +32,14 @@ const postPrecessGenerator = ( const listCustomGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws eks ${command}`; + let args = ["eks", command]; for (let i = 0; i < options.length; i++) { const option = options[i]; @@ -48,12 +48,15 @@ const listCustomGenerator = async ( continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -108,12 +111,12 @@ const listRolesForPrincipal = ( const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -128,7 +131,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -220,12 +223,12 @@ const generators: Record = { }, listClusters: { - script: "aws eks list-clusters", + script: ["aws", "eks", "list-clusters"], postProcess: (out) => postPrecessGenerator(out, "clusters"), }, listKmsKeys: { - script: "aws kms list-keys", + script: ["aws", "kms", "list-keys"], postProcess: function (out) { try { const list = JSON.parse(out)["Keys"]; @@ -255,12 +258,12 @@ const generators: Record = { }, listAddons: { - script: "aws eks describe-addon-versions", + script: ["aws", "eks", "describe-addon-versions"], postProcess: (out) => postPrecessGenerator(out, "addons", "addonName"), }, listAddonVersions: { - script: "aws eks describe-addon-versions", + script: ["aws", "eks", "describe-addon-versions"], postProcess: (out) => { try { const addons = JSON.parse(out)["addons"]; @@ -283,23 +286,23 @@ const generators: Record = { }, listRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => postPrecessGenerator(out, "Roles", "RoleName"), }, listEKSClusterRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => listRolesForPrincipal(out, "eks.amazonaws.com"), }, listFargatePodRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => listRolesForPrincipal(out, "eks-fargate-pods.amazonaws.com"), }, listNodeGroupRoles: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => listRolesForPrincipal(out, "eks-nodegroup.amazonaws.com"), }, @@ -313,10 +316,11 @@ const generators: Record = { } const param = tokens[idx + 1]; - const out = await executeShellCommand( - `aws eks describe-cluster --name ${param}` - ); - const cluster = JSON.parse(out)["cluster"]; + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["eks", "describe-cluster", "--name", param], + }); + const cluster = JSON.parse(stdout)["cluster"]; const subnets = cluster["resourcesVpcConfig"]["subnetIds"]; return subnets.map((subnet) => { return { diff --git a/src/aws/elasticbeanstalk.ts b/src/aws/elasticbeanstalk.ts index 9df9012fa6bc..23d65247491b 100644 --- a/src/aws/elasticbeanstalk.ts +++ b/src/aws/elasticbeanstalk.ts @@ -39,27 +39,31 @@ const postPrecessGenerator = ( const customGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - command: string, + executeShellCommand: Fig.ExecuteCommandFunction, + command: string[], options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws elasticbeanstalk ${command}`; - for (let i = 0; i < options.length; i++) { - const option = options[i]; + let args = ["elasticbeanstalk", ...command]; + + for (const option of options) { const idx = tokens.indexOf(option); if (idx < 0) { continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); + + const list = JSON.parse(stdout)[parentKey]; - const list = JSON.parse(out)[parentKey]; if (!Array.isArray(list)) { return [ { @@ -84,7 +88,7 @@ const customGenerator = async ( const filterManagedAction = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, @@ -94,7 +98,7 @@ const filterManagedAction = async ( return customGenerator( tokens, executeShellCommand, - `${command} --status ${filter}`, + [command, "--status", filter], options, parentKey, childKey @@ -103,12 +107,12 @@ const filterManagedAction = async ( const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -123,7 +127,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -212,14 +216,14 @@ const generators: Record = { }, listEnvironmentIds: { - script: "aws elasticbeanstalk describe-environments", + script: ["aws", "elasticbeanstalk", "describe-environments"], postProcess: (out) => { return postPrecessGenerator(out, "Environments", "EnvironmentId"); }, }, listEnvironmentNames: { - script: "aws elasticbeanstalk describe-environments", + script: ["aws", "elasticbeanstalk", "describe-environments"], postProcess: (out) => { return postPrecessGenerator(out, "Environments", "EnvironmentName"); }, @@ -240,14 +244,14 @@ const generators: Record = { }, listIamRoleArns: { - script: "aws iam list-roles", + script: ["aws", "iam", "list-roles"], postProcess: (out) => { return postPrecessGenerator(out, "Roles", "Arn"); }, }, listCnamePrefixes: { - script: "aws elasticbeanstalk describe-environments", + script: ["aws", "elasticbeanstalk", "describe-environments"], postProcess: (out) => { return postPrecessGenerator(out, "Environments", "CNAME").map((cname) => { try { @@ -267,7 +271,7 @@ const generators: Record = { }, listApplications: { - script: "aws elasticbeanstalk describe-applications", + script: ["aws", "elasticbeanstalk", "describe-applications"], postProcess: (out) => { return postPrecessGenerator(out, "Applications", "ApplicationName"); }, @@ -278,7 +282,7 @@ const generators: Record = { return customGenerator( tokens, executeShellCommand, - "describe-application-versions", + ["describe-application-versions"], ["--application-name"], "ApplicationVersions", "VersionLabel" @@ -287,7 +291,7 @@ const generators: Record = { }, listBuckets: { - script: "aws s3 ls --page-size 1000", + script: ["aws", "s3", "ls", "--page-size", "1000"], postProcess: (out) => { try { return out.split("\n").map((line) => { @@ -310,28 +314,28 @@ const generators: Record = { }, listSolutionStacks: { - script: "aws elasticbeanstalk list-available-solution-stacks", + script: ["aws", "elasticbeanstalk", "list-available-solution-stacks"], postProcess: (out) => { return postPrecessGenerator(out, "SolutionStacks"); }, }, listPlatformArns: { - script: "aws elasticbeanstalk list-platform-versions", + script: ["aws", "elasticbeanstalk", "list-platform-versions"], postProcess: (out) => { return postPrecessGenerator(out, "PlatformSummaryList", "PlatformArn"); }, }, listApplicationArns: { - script: "aws elasticbeanstalk describe-applications", + script: ["aws", "elasticbeanstalk", "describe-applications"], postProcess: (out) => { return postPrecessGenerator(out, "Applications", "ApplicationArn"); }, }, listEnvironmentArns: { - script: "aws elasticbeanstalk describe-environments", + script: ["aws", "elasticbeanstalk", "describe-environments"], postProcess: (out) => { return postPrecessGenerator(out, "Environments", "EnvironmentArn"); }, diff --git a/src/aws/iam.ts b/src/aws/iam.ts index 0e5ced002af4..cbaea79063b8 100644 --- a/src/aws/iam.ts +++ b/src/aws/iam.ts @@ -182,25 +182,25 @@ const awsPrincipals = [ ]; interface Identity { - command: string; + command: string[]; parentKey: string; childKey: string; } const identityStruct: Identity[] = [ - { command: "aws iam list-users", parentKey: "Users", childKey: "Arn" }, - { command: "aws iam list-groups", parentKey: "Groups", childKey: "Arn" }, - { command: "aws iam list-roles", parentKey: "Roles", childKey: "Arn" }, + { command: ["iam", "list-users"], parentKey: "Users", childKey: "Arn" }, + { command: ["iam", "list-groups"], parentKey: "Groups", childKey: "Arn" }, + { command: ["iam", "list-roles"], parentKey: "Roles", childKey: "Arn" }, ]; const _prefixFile = "file://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -215,7 +215,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -288,7 +288,7 @@ const filterWithPrefix = (token: string, prefix: string): string => { const listCustomGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, option: string, parentKey: string, @@ -300,11 +300,12 @@ const listCustomGenerator = async ( return []; } const param = tokens[idx + 1]; - const out = await executeShellCommand( - `aws iam ${command} ${option} ${param}` - ); + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["iam", command, option, param], + }); - const policies = JSON.parse(out)[parentKey]; + const policies = JSON.parse(stdout)[parentKey]; return policies.map((elm) => (childKey ? elm[childKey] : elm)); } catch (e) { console.log(e); @@ -328,14 +329,17 @@ const postPrecessGenerator = ( const MultiSuggestionsGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, enabled: Identity[] ) => { try { const list: Fig.Suggestion[][] = []; const promises: Promise[] = []; for (let i = 0; i < enabled.length; i++) { - promises[i] = executeShellCommand(enabled[i]["command"]); + promises[i] = executeShellCommand({ + command: "aws", + args: enabled[i].command, + }).then(({ stdout }) => stdout); } const result = await Promise.all(promises); @@ -357,7 +361,7 @@ const MultiSuggestionsGenerator = async ( const generators: Record = { getAccountArn: { - script: "aws sts get-caller-identity", + script: ["aws", "sts", "get-caller-identity"], postProcess: function (out, tokens) { try { const accountId = JSON.parse(out)["Account"]; @@ -373,7 +377,7 @@ const generators: Record = { }, listOpenIdProviders: { - script: "aws iam list-open-id-connect-providers", + script: ["aws", "iam", "list-open-id-connect-providers"], postProcess: function (out) { return postPrecessGenerator(out, "OpenIDConnectProviderList", "Arn"); }, @@ -413,7 +417,7 @@ const generators: Record = { }, listInstanceProfiles: { - script: "aws iam list-instance-profiles --page-size 100", + script: ["aws", "iam", "list-instance-profiles", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator( out, @@ -434,11 +438,17 @@ const generators: Record = { return []; } const param = tokens[idx + 1]; - const out = await executeShellCommand( - `aws iam get-instance-profile --instance-profile-name ${param}` - ); + const { stdout } = await executeShellCommand({ + command: "aws", + args: [ + "iam", + "get-instance-profile", + "--instance-profile-name", + param, + ], + }); - const policies = JSON.parse(out as string)["InstanceProfile"]; + const policies = JSON.parse(stdout)["InstanceProfile"]; return policies["Roles"].map((elm) => { return { name: elm["RoleName"], @@ -455,7 +465,7 @@ const generators: Record = { }, listUsers: { - script: "aws iam list-users --page-size 100", + script: ["aws", "iam", "list-users", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Users", "UserName"); }, @@ -465,7 +475,7 @@ const generators: Record = { }, listUserArns: { - script: "aws iam list-users --page-size 100", + script: ["aws", "iam", "list-users", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Users", "Arn"); }, @@ -490,7 +500,7 @@ const generators: Record = { }, listGroups: { - script: "aws iam list-groups --page-size 100", + script: ["aws", "iam", "list-groups", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Groups", "GroupName"); }, @@ -516,7 +526,15 @@ const generators: Record = { }, listIamPoliciesArn: { - script: "aws iam list-policies --page-size 100 --scope Local", + script: [ + "aws", + "iam", + "list-policies", + "--page-size", + "100", + "--scope", + "Local", + ], postProcess: function (out) { return postPrecessGenerator(out, "Policies", "Arn"); }, @@ -621,7 +639,7 @@ const generators: Record = { }, listRoles: { - script: "aws iam list-roles --page-size 100", + script: ["aws", "iam", "list-roles", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Roles", "RoleName"); }, @@ -666,7 +684,7 @@ const generators: Record = { }, listMfaDevices: { - script: "aws iam list-mfa-devices --page-size 100", + script: ["aws", "iam", "list-mfa-devices", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "MFADevices", "SerialNumber"); }, @@ -676,7 +694,7 @@ const generators: Record = { }, listVirtualMfaDevices: { - script: "aws iam list-virtual-mfa-devices --page-size 100", + script: ["aws", "iam", "list-virtual-mfa-devices", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "VirtualMFADevices", "SerialNumber"); }, @@ -686,7 +704,7 @@ const generators: Record = { }, listAccessKeyIds: { - script: "aws iam list-access-keys --page-size 100", + script: ["aws", "iam", "list-access-keys", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "AccessKeyMetadata", "AccessKeyId"); }, @@ -696,7 +714,7 @@ const generators: Record = { }, listAccountAliases: { - script: "aws iam list-account-aliases --page-size 100", + script: ["aws", "iam", "list-account-aliases", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "AccountAliases"); }, @@ -706,7 +724,7 @@ const generators: Record = { }, listSamlProviders: { - script: "aws iam list-saml-providers", + script: ["aws", "iam", "list-saml-providers"], postProcess: function (out) { return postPrecessGenerator(out, "SAMLProviderList", "Arn"); }, @@ -716,7 +734,7 @@ const generators: Record = { }, listSSHPublicKeys: { - script: "aws iam list-ssh-public-keys --page-size 1000", + script: ["aws", "iam", "list-ssh-public-keys", "--page-size", "1000"], postProcess: function (out) { return postPrecessGenerator(out, "SSHPublicKeys", "SSHPublicKeyId"); }, @@ -742,7 +760,7 @@ const generators: Record = { }, listServerCerts: { - script: "aws iam list-server-certificates --page-size 1000", + script: ["aws", "iam", "list-server-certificates", "--page-size", "1000"], postProcess: function (out) { return postPrecessGenerator( out, @@ -792,7 +810,7 @@ const generators: Record = { return MultiSuggestionsGenerator(tokens, executeShellCommand, [ ...identityStruct, { - command: "aws iam list-policies --scope Local", + command: ["iam", "list-policies", "--scope", "Local"], parentKey: "Policies", childKey: "Arn", }, diff --git a/src/aws/lambda.ts b/src/aws/lambda.ts index ddd9f3c0f341..5ea223f26e7f 100644 --- a/src/aws/lambda.ts +++ b/src/aws/lambda.ts @@ -264,14 +264,14 @@ const postPrecessGenerator = ( const listCustomGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[], parentKey: string, childKey = "" ): Promise => { try { - let cmd = `aws lambda ${command}`; + let args = ["lambda", command]; for (let i = 0; i < options.length; i++) { const option = options[i]; @@ -280,12 +280,15 @@ const listCustomGenerator = async ( continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)[parentKey]; + const list = JSON.parse(stdout)[parentKey]; if (!Array.isArray(list)) { return [ @@ -309,24 +312,14 @@ const listCustomGenerator = async ( return []; }; -const getResultList = async ( - tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - command: string, - key: string -): Promise => { - const out = await executeShellCommand(command); - return JSON.parse(out)[key]; -}; - const listCustomSIDGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, command: string, options: string[] ): Promise => { try { - let cmd = `aws lambda ${command}`; + let args = ["lambda", command]; for (let i = 0; i < options.length; i++) { const option = options[i]; @@ -335,12 +328,15 @@ const listCustomSIDGenerator = async ( continue; } const param = tokens[idx + 1]; - cmd += ` ${option} ${param}`; + args = [...args, option, param]; } - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const policies = JSON.parse(out)["Policy"]; + const policies = JSON.parse(stdout)["Policy"]; const statement = JSON.parse(policies)["Statement"]; return statement.map((elm) => { return { @@ -356,22 +352,29 @@ const listCustomSIDGenerator = async ( const MultiSuggestionsGenerator = async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, - enabled: Record[] + executeShellCommand: Fig.ExecuteCommandFunction, + enabled: { + command: string[]; + parentKey: string; + childKey: string; + }[] ) => { try { const list: Fig.Suggestion[][] = []; const promises: Promise[] = []; for (let i = 0; i < enabled.length; i++) { - promises[i] = executeShellCommand(enabled[i]["command"]); + promises[i] = executeShellCommand({ + command: "aws", + args: enabled[i].command, + }).then(({ stdout }) => stdout); } const result = await Promise.all(promises); for (let i = 0; i < enabled.length; i++) { list[i] = postPrecessGenerator( result[i], - enabled[i]["parentKey"], - enabled[i]["childKey"] + enabled[i].parentKey, + enabled[i].childKey ); } @@ -386,12 +389,12 @@ const _prefixFile = "file://"; const _prefixBlob = "fileb://"; const _prefixS3 = "s3://"; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; if (!whatHasUserTyped.startsWith(prefix)) { - return `echo '${prefix}'`; + return ["echo", prefix]; } whatHasUserTyped = whatHasUserTyped.slice(prefix.length); @@ -406,7 +409,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -515,7 +518,7 @@ const generators: Record = { }, listLayerArns: { - script: "aws lambda list-layers", + script: ["aws", "lambda", "list-layers"], postProcess: (out) => { return postPrecessGenerator(out, "Layers", "LayerArn"); }, @@ -541,7 +544,7 @@ const generators: Record = { }, getPrincipal: { - script: "aws sts get-caller-identity", + script: ["aws", "sts", "get-caller-identity"], postProcess: function (out, tokens) { try { const accountId = JSON.parse(out)["Account"]; @@ -603,7 +606,7 @@ const generators: Record = { }, listLambdaFunctions: { - script: "aws lambda list-functions", + script: ["aws", "lambda", "list-functions"], postProcess: (out) => { return postPrecessGenerator(out, "Functions", "FunctionArn"); }, @@ -638,13 +641,19 @@ const generators: Record = { custom: async function (tokens, executeShellCommand) { try { const idx = tokens.indexOf("--function-name"); - const cmd = `aws lambda list-versions-by-function --function-name ${ - tokens[idx + 1] - }`; + const args = [ + "lambda", + "list-versions-by-function", + "--function-name", + tokens[idx + 1], + ]; - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - const list = JSON.parse(out)["Versions"]; + const list = JSON.parse(stdout)["Versions"]; return list .filter((elm) => elm.Version !== "$LATEST") .map((elm) => { @@ -720,12 +729,12 @@ const generators: Record = { return MultiSuggestionsGenerator(tokens, executeShellCommand, [ { - command: "aws dynamodbstreams list-streams", + command: ["dynamodbstreams", "list-streams"], parentKey: "Streams", childKey: "StreamArn", }, { - command: "aws kafka list-clusters", + command: ["kafka", "list-clusters"], parentKey: "ClusterInfoList", childKey: "ClusterArn", }, @@ -753,17 +762,17 @@ const generators: Record = { return MultiSuggestionsGenerator(tokens, executeShellCommand, [ { - command: "aws sns list-topics", + command: ["sns", "list-topics"], parentKey: "Topics", childKey: "TopicArn", }, { - command: "aws events list-event-buses", + command: ["events", "list-event-buses"], parentKey: "EventBuses", childKey: "Arn", }, { - command: "aws lambda list-functions", + command: ["lambda", "list-functions"], parentKey: "Functions", childKey: "FunctionArn", }, @@ -776,7 +785,7 @@ const generators: Record = { }, listRoles: { - script: "aws iam list-roles --page-size 100", + script: ["aws", "iam", "list-roles", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Roles", "RoleName"); }, @@ -786,7 +795,7 @@ const generators: Record = { }, listKmsKeys: { - script: "aws kms list-keys --page-size 100", + script: ["aws", "kms", "list-keys", "--page-size", "100"], postProcess: function (out) { return postPrecessGenerator(out, "Keys", "KeyArn"); }, @@ -796,7 +805,7 @@ const generators: Record = { }, listLayers: { - script: "aws lambda list-layers", + script: ["aws", "lambda", "list-layers"], postProcess: function (out) { return postPrecessGenerator(out, "Layers", "LayerArn"); }, @@ -806,7 +815,7 @@ const generators: Record = { }, listLayerArnsWithVersion: { - script: "aws lambda list-layers", + script: ["aws", "lambda", "list-layers"], postProcess: function (out) { try { const list = JSON.parse(out)["Layers"]; @@ -827,7 +836,7 @@ const generators: Record = { }, listFilesystemConfigs: { - script: "aws efs describe-file-systems", + script: ["aws", "efs", "describe-file-systems"], postProcess: function (out) { try { const list = JSON.parse(out)["FileSystems"]; @@ -849,7 +858,13 @@ const generators: Record = { }, listCodeSigningConfigs: { - script: "aws lambda list-code-signing-configs --page-size 100", + script: [ + "aws", + "lambda", + "list-code-signing-configs", + "--page-size", + "100", + ], postProcess: function (out) { return postPrecessGenerator( out, @@ -863,7 +878,13 @@ const generators: Record = { }, listEventSourceMappingUUIDs: { - script: "aws lambda list-event-source-mappings --page-size 100", + script: [ + "aws", + "lambda", + "list-event-source-mappings", + "--page-size", + "100", + ], postProcess: function (out) { return postPrecessGenerator(out, "EventSourceMappings", "UUID"); }, @@ -873,7 +894,7 @@ const generators: Record = { }, listCodeSHA: { - script: "aws lambda list-functions", + script: ["aws", "lambda", "list-functions"], postProcess: function (out) { return postPrecessGenerator(out, "Functions", "CodeSha256"); }, @@ -883,7 +904,7 @@ const generators: Record = { }, listBuckets: { - script: "aws s3 ls --page-size 1000", + script: ["aws", "s3", "ls", "--page-size", "1000"], postProcess: function (out, tokens) { try { return out.split("\n").map((line) => { @@ -910,17 +931,25 @@ const generators: Record = { custom: async function (tokens, executeShellCommand) { try { const idx = tokens.indexOf("--s3-bucket"); - const cmd = `aws s3 ls ${_prefixS3}${ - tokens[idx + 1] - } --recursive --page-size 1000`; + const args = [ + "s3", + "ls", + `${_prefixS3}${tokens[idx + 1]}`, + "--recursive", + "--page-size", + "1000", + ]; - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - if (out == "") { + if (stdout == "") { return []; } - if (out.trim() === _prefixS3) { + if (stdout.trim() === _prefixS3) { return [ { name: _prefixS3, @@ -929,7 +958,7 @@ const generators: Record = { ]; } - return out.split("\n").map((line) => { + return stdout.split("\n").map((line) => { const parts = line.split(/\s+/); // sub prefix if (!parts.length) { @@ -954,17 +983,25 @@ const generators: Record = { try { const bucketIdx = tokens.indexOf("--s3-bucket"); const objectIdx = tokens.indexOf("--s3-key"); - const cmd = `aws s3api list-object-versions --bucket ${ - tokens[bucketIdx + 1] - } --prefix ${tokens[objectIdx + 1]}`; + const args = [ + "s3api", + "list-object-versions", + "--bucket", + tokens[bucketIdx + 1], + "--prefix", + tokens[objectIdx + 1], + ]; - const out = await executeShellCommand(cmd); + const { stdout } = await executeShellCommand({ + command: "aws", + args, + }); - if (out == "") { + if (stdout == "") { return []; } - if (out.trim() === _prefixS3) { + if (stdout.trim() === _prefixS3) { return [ { name: _prefixS3, @@ -973,7 +1010,7 @@ const generators: Record = { ]; } - const list = JSON.parse(out)["Versions"]; + const list = JSON.parse(stdout)["Versions"]; return list .filter((elm) => elm["VersionId"] !== "null") .map((elm) => { diff --git a/src/aws/s3.ts b/src/aws/s3.ts index 897a469322eb..c88bd6d948f4 100644 --- a/src/aws/s3.ts +++ b/src/aws/s3.ts @@ -53,8 +53,8 @@ const ttl = 30000; const appendFolderPath = ( whatHasUserTyped: string, - baseLSCommand: string -): string => { + baseLSCommand: string[] +): string[] => { let folderPath = ""; const lastSlashIndex = whatHasUserTyped.lastIndexOf("/"); @@ -66,7 +66,7 @@ const appendFolderPath = ( } } - return baseLSCommand + folderPath; + return [...baseLSCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -153,15 +153,15 @@ const _prefixFileb = "fileb://"; const generators: Record = { listFilesGenerator: { script: (tokens) => { - const baseLSCommand = "\\ls -1ApL "; + const baseLsCommand = ["ls", "-1ApL"]; const whatHasUserTyped = tokens[tokens.length - 1]; // Do not show file suggestions when s3:// typed if (whatHasUserTyped.startsWith(_prefixS3)) { - return ""; + return undefined; } - return appendFolderPath(whatHasUserTyped, baseLSCommand); + return appendFolderPath(whatHasUserTyped, baseLsCommand); }, postProcess: (out) => { return postProcessFiles(out, _prefixFile); @@ -186,13 +186,13 @@ const generators: Record = { // See more: https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html listBlobsGenerator: { script: (tokens) => { - const baseLSCommand = "\\ls -1ApL "; + const baseLSCommand = ["ls", "-1ApL "]; let whatHasUserTyped = tokens[tokens.length - 1]; if (whatHasUserTyped.startsWith(_prefixFileb)) { whatHasUserTyped = whatHasUserTyped.slice(_prefixFileb.length); } else { - return "echo 'fileb://'"; + return ["echo", "fileb://"]; } return appendFolderPath(whatHasUserTyped, baseLSCommand); @@ -215,7 +215,7 @@ const generators: Record = { listRemoteFilesGenerator: { script: (tokens) => { const whatHasUserTyped = tokens[tokens.length - 1]; - const baseLSCommand = "\\aws s3 ls "; + const baseLsCommand = ["aws", "s3", "ls"]; let folderPath = ""; @@ -226,17 +226,17 @@ const generators: Record = { // then we can assume that the filepath generator is in work // so do not return any s3 related filepaths if (!_prefixS3.startsWith(whatHasUserTyped)) { - return ""; + return undefined; } - return "echo 's3://'"; + return ["echo", "s3://"]; } if (lastSlashIndex > -1) { folderPath = whatHasUserTyped.slice(0, lastSlashIndex + 1); } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }, postProcess: (out) => { if (out == "") { @@ -319,7 +319,7 @@ const generators: Record = { // just bucket names listBuckets: { - script: "aws s3 ls --page-size 1000", + script: ["aws", "s3", "ls", "--page-size", "1000"], postProcess: function (out, context) { try { return out.split("\n").map((line) => { @@ -345,7 +345,7 @@ const generators: Record = { kmsKeyIdGenerator: { // --page-size does not affect the number of items returned, // just chunks request so it won't timeout - script: "aws kms list-keys --page-size 100", + script: ["aws", "kms", "list-keys", "--page-size", "100"], postProcess: function (out) { try { const list = JSON.parse(out)["Keys"]; diff --git a/src/aws/s3api.ts b/src/aws/s3api.ts index 740dfa0a2c25..d510584d1e31 100644 --- a/src/aws/s3api.ts +++ b/src/aws/s3api.ts @@ -1,5 +1,5 @@ const bucketGenerator: Fig.Generator = { - script: "aws s3api list-buckets", + script: ["aws", "s3api", "list-buckets"], postProcess: function (out) { const json = JSON.parse(out); return json.Buckets.map((bucket) => { diff --git a/src/aws/secretsmanager.ts b/src/aws/secretsmanager.ts index 54c639c46bd5..d088d21677c2 100644 --- a/src/aws/secretsmanager.ts +++ b/src/aws/secretsmanager.ts @@ -24,15 +24,14 @@ const awsRegions = [ const ttl = 30000; -const appendFolderPath = (tokens: string[], prefix: string): string => { - const baseLSCommand = "\\ls -1ApL "; +const appendFolderPath = (tokens: string[], prefix: string): string[] => { + const baseLsCommand = ["ls", "-1ApL"]; let whatHasUserTyped = tokens[tokens.length - 1]; - if (whatHasUserTyped.startsWith(prefix)) { - whatHasUserTyped = whatHasUserTyped.slice(prefix.length); - } else { - return `echo '${prefix}'`; + if (!whatHasUserTyped.startsWith(prefix)) { + return ["echo", prefix]; } + whatHasUserTyped = whatHasUserTyped.slice(prefix.length); let folderPath = ""; const lastSlashIndex = whatHasUserTyped.lastIndexOf("/"); @@ -45,7 +44,7 @@ const appendFolderPath = (tokens: string[], prefix: string): string => { } } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }; const postProcessFiles = (out: string, prefix: string): Fig.Suggestion[] => { @@ -123,7 +122,15 @@ const generators: Record = { secretIdsGenerator: { // --page-size does not affect the number of items returned, // just chunks request so it won't timeout - script: "aws secretsmanager list-secrets --sort-order asc --page-size 100", + script: [ + "aws", + "secretsmanager", + "list-secrets", + "--sort-order", + "asc", + "--page-size", + "100", + ], postProcess: function (out) { try { const list = JSON.parse(out)["SecretList"]; @@ -142,7 +149,7 @@ const generators: Record = { kmsKeyIdGenerator: { // --page-size does not affect the number of items returned, // just chunks request so it won't timeout - script: "aws kms list-keys --page-size 100", + script: ["aws", "kms", "list-keys", "--page-size", "100"], postProcess: function (out) { try { const list = JSON.parse(out)["Keys"]; @@ -199,7 +206,7 @@ const generators: Record = { }, }, getReplicaRegionsGenerator: { - script: "aws kms list-keys --page-size 100", + script: ["aws", "kms", "list-keys", "--page-size", "100"], postProcess: function (out, tokens) { try { const list = JSON.parse(out)["Keys"]; @@ -220,7 +227,7 @@ const generators: Record = { }, }, getLambdasGenerator: { - script: "aws lambda list-functions --page-size 100", + script: ["aws", "lambda", "list-functions", "--page-size", "100"], postProcess: function (out, tokens) { try { const list = JSON.parse(out)["Functions"]; @@ -245,10 +252,11 @@ const generators: Record = { return []; } const secretId = tokens[idx + 1]; - const out = await executeShellCommand( - `aws secretsmanager describe-secret --secret-id ${secretId}` - ); - const versions = JSON.parse(out as string)["VersionIdsToStages"]; + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["secretsmanager", "describe-secret", "--secret-id", secretId], + }); + const versions = JSON.parse(stdout)["VersionIdsToStages"]; return Object.keys(versions).map((elm) => ({ name: elm })); } catch (e) { console.log(e); @@ -268,10 +276,11 @@ const generators: Record = { return []; } const secretId = tokens[idx + 1]; - const out = await executeShellCommand( - `aws secretsmanager describe-secret --secret-id ${secretId}` - ); - const versions = JSON.parse(out as string)["VersionIdsToStages"]; + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["secretsmanager", "describe-secret", "--secret-id", secretId], + }); + const versions = JSON.parse(stdout)["VersionIdsToStages"]; return Object.keys(versions).map((elm) => ({ name: versions[elm][0] })); } catch (e) { console.log(e); @@ -292,10 +301,11 @@ const generators: Record = { return []; } const secretId = tokens[idx + 1]; - const out = await executeShellCommand( - `aws secretsmanager describe-secret --secret-id ${secretId}` - ); - const versions = JSON.parse(out as string)["Tags"]; + const { stdout } = await executeShellCommand({ + command: "aws", + args: ["secretsmanager", "describe-secret", "--secret-id", secretId], + }); + const versions = JSON.parse(stdout)["Tags"]; return versions.map((elm) => ({ name: elm["Key"] })); } catch (e) { console.log(e); diff --git a/src/bat.ts b/src/bat.ts index d45507e56296..b0f7841954bd 100644 --- a/src/bat.ts +++ b/src/bat.ts @@ -16,7 +16,7 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --list-languages", + script: ["bat", "--list-languages"], postProcess: function (out) { // unpack 2-dimension array return out @@ -86,7 +86,11 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --wrap unknow 2>&1 >/dev/null | grep possible", + script: [ + "bash", + "-c", + "bat --wrap unknow 2>&1 >/dev/null | grep possible", + ], postProcess: function (out) { return out .trim() @@ -123,7 +127,11 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --color unknow 2>&1 >/dev/null | grep possible", + script: [ + "bash", + "-c", + "bat --color unknow 2>&1 >/dev/null | grep possible", + ], postProcess: function (out) { return out .trim() @@ -148,7 +156,11 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --italic-text unknow 2>&1 >/dev/null | grep possible", + script: [ + "bash", + "-c", + "bat --italic-text unknow 2>&1 >/dev/null | grep possible", + ], postProcess: function (out) { return out .trim() @@ -174,7 +186,11 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --decorations unknow 2>&1 >/dev/null | grep possible", + script: [ + "bash", + "-c", + "bat --decorations unknow 2>&1 >/dev/null | grep possible", + ], postProcess: function (out) { return out .trim() @@ -203,7 +219,11 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --paging unknow 2>&1 >/dev/null | grep possible", + script: [ + "bash", + "-c", + "bat --paging unknow 2>&1 >/dev/null | grep possible", + ], postProcess: function (out) { return out .trim() @@ -251,7 +271,7 @@ const completionSpec: Fig.Spec = { args: { name: "", generators: { - script: "bat --list-themes", + script: ["bat", "--list-themes"], postProcess: function (out) { return out.split("\n").map((theme) => { return { name: theme, description: "theme: " + theme }; diff --git a/src/bazel.ts b/src/bazel.ts index 243e5e4efad1..bd44e8f22e26 100644 --- a/src/bazel.ts +++ b/src/bazel.ts @@ -1,5 +1,9 @@ const bazelBuildFiles: Fig.Generator = { - script: `FILES=( $(find ./ -name BUILD) ); for f in $FILES; do echo "----$f"; \\cat "$f"; done`, + script: [ + "bash", + "-c", + `FILES=( $(find ./ -name BUILD) ); for f in $FILES; do echo "----$f"; \\cat "$f"; done`, + ], // returns filepaths and contents in the form below, note the "----" to indicate the filepath // ----.//lib/BUILD // load("@rules_cc//cc:defs.bzl", "cc_library") diff --git a/src/black.ts b/src/black.ts index 00e3d421bfe9..4f4df0a523e7 100644 --- a/src/black.ts +++ b/src/black.ts @@ -1,6 +1,6 @@ // https://github.com/psf/black const blackVersions: Fig.Generator = { - script: "gh release list --repo psf/black", + script: ["gh", "release", "list", "--repo", "psf/black"], cache: { ttl: 1000 * 60 * 60 * 24 * 2, // 2 days }, diff --git a/src/bosh.ts b/src/bosh.ts index ea9558c3cc7c..8b9612c561fe 100644 --- a/src/bosh.ts +++ b/src/bosh.ts @@ -4,7 +4,7 @@ const genericPathArg: Fig.Arg = { }; const deployments: Fig.Generator = { - script: "bosh --json deployments", + script: ["bosh", "--json", "deployments"], postProcess: function (out) { if (out.startsWith("fatal:")) { return []; diff --git a/src/brew.ts b/src/brew.ts index 9b3ebaf5672b..99b87c45ca9a 100644 --- a/src/brew.ts +++ b/src/brew.ts @@ -1,5 +1,5 @@ const servicesGenerator = (action: string): Fig.Generator => ({ - script: "brew services list | sed -e 's/ .*//' | tail -n +2", + script: ["bash", "-c", "brew services list | sed -e 's/ .*//' | tail -n +2"], postProcess: function (out) { return out .split("\n") @@ -13,14 +13,14 @@ const servicesGenerator = (action: string): Fig.Generator => ({ }); const repositoriesGenerator = (): Fig.Generator => ({ - script: "brew tap", + script: ["brew", "tap"], postProcess: (out) => { return out.split("\n").map((line) => ({ name: line })); }, }); const formulaeGenerator: Fig.Generator = { - script: "brew list -1", + script: ["brew", "list", "-1"], postProcess: function (out) { return out .split("\n") @@ -34,7 +34,7 @@ const formulaeGenerator: Fig.Generator = { }; const outdatedformulaeGenerator: Fig.Generator = { - script: "brew outdated -q", + script: ["brew", "outdated", "-q"], postProcess: function (out) { return out.split("\n").map((formula) => ({ name: formula, @@ -45,7 +45,7 @@ const outdatedformulaeGenerator: Fig.Generator = { }; const generateAllFormulae: Fig.Generator = { - script: "brew formulae", + script: ["brew", "formulae"], postProcess: function (out) { return out.split("\n").map((formula) => ({ name: formula, @@ -57,7 +57,7 @@ const generateAllFormulae: Fig.Generator = { }; const generateAllCasks: Fig.Generator = { - script: "brew casks", + script: ["brew", "casks"], postProcess: function (out) { return out.split("\n").map((cask) => ({ name: cask, @@ -68,7 +68,11 @@ const generateAllCasks: Fig.Generator = { }, }; const generateAliases: Fig.Generator = { - script: 'find ~/.brew-aliases/ -type f ! -name "*.*" -d 1 | sed "s/.*\\///"', + script: [ + "bash", + "-c", + 'find ~/.brew-aliases/ -type f ! -name "*.*" -d 1 | sed "s/.*\\///"', + ], postProcess: function (out) { return out .split("\n") @@ -1274,7 +1278,7 @@ const completionSpec: Fig.Spec = { isVariadic: true, generators: { - script: "brew list -1 --cask", + script: ["brew", "list", "-1", "--cask"], postProcess: function (out) { return out.split("\n").map((formula) => { return { diff --git a/src/browser-sync.ts b/src/browser-sync.ts index 48f36cae5d58..4fd800e8ad31 100644 --- a/src/browser-sync.ts +++ b/src/browser-sync.ts @@ -225,8 +225,11 @@ const completionSpec: Fig.Spec = { args: { name: "recipe-name", generators: { - script: + script: [ + "bash", + "-c", "browser-sync recipe ls | tail -n +3 | sed -e 's/^[[:space:]]*//'", + ], splitOn: "\n", cache: { strategy: "max-age", diff --git a/src/bun.ts b/src/bun.ts index c43840a79552..0069180a1d62 100644 --- a/src/bun.ts +++ b/src/bun.ts @@ -303,8 +303,21 @@ const spec: Fig.Spec = { ], generators: [ { template: "folders" }, - { script: "command ls -1 ~/.bun-create", splitOn: "\n" }, - { script: "command ls -1 .bun-create", splitOn: "\n" }, + { + custom: async (_, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "ls", + args: [ + "-1", + `${context.environmentVariables["HOME"]}/.bun-create`, + ], + }); + return stdout.split("\n").map((name) => ({ + name, + })); + }, + }, + { script: ["command", "ls", "-1", ".bun-create"], splitOn: "\n" }, createCLIsGenerator, ], loadSpec: async (token) => ({ diff --git a/src/bundle.ts b/src/bundle.ts index e97e8fab6c98..3a00814243cb 100644 --- a/src/bundle.ts +++ b/src/bundle.ts @@ -1,5 +1,5 @@ const gemfileGemsGenerator: Fig.Generator = { - script: "bundle list --name-only", + script: ["bundle", "list", "--name-only"], postProcess: (out) => { return out.split("\n").map((gem) => { return { diff --git a/src/bunx.ts b/src/bunx.ts index a5a77ae4a1e5..f3ed883d3489 100644 --- a/src/bunx.ts +++ b/src/bunx.ts @@ -6,7 +6,11 @@ const bunx: Fig.Spec = { name: "command", isCommand: true, generators: { - script: `until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/`, + script: [ + "bash", + "-c", + "until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/`", + ], postProcess: function (out) { const cli = [...npxSuggestions].reduce( (acc, { name }) => [...acc, name], diff --git a/src/capacitor.ts b/src/capacitor.ts index 31fd5fd88501..eb0699a4555a 100644 --- a/src/capacitor.ts +++ b/src/capacitor.ts @@ -17,11 +17,12 @@ const targetGenerator: Fig.Generator = { return []; } - const out = await executeShellCommand( - `npx capacitor run ${platform} --list` - ); + const { stdout } = await executeShellCommand({ + command: "npx", + args: ["capacitor", "run", platform, "--list"], + }); - return out + return stdout .trim() .split("\n") .slice(2) // Ignore output header lines diff --git a/src/cargo.ts b/src/cargo.ts index dc05fce91274..6bcbb51c5476 100644 --- a/src/cargo.ts +++ b/src/cargo.ts @@ -47,37 +47,38 @@ const vcsOptions: { }, ]; -const testGenerator: Fig.Generator = { - cache: { - cacheByDirectory: true, - strategy: "stale-while-revalidate", - ttl: 1000 * 60 * 5, - }, - script: (context) => { - const base = context[context.length - 1]; - // allow split by single colon so that it triggers on a::b: - const indexIntoModPath = Math.max(base.split(/::?/).length, 1); - // split by :: so that tokens with a single colon are allowed - const moduleTokens = base.split("::"); - const lastModule = moduleTokens.pop(); - // check if the token has a : on the end - const hasColon = lastModule[lastModule.length - 1] == ":" ? ":" : ""; - return `cargo t -- --list | awk '/: test$/ { print substr($1, 1, length($1) - 1) }' | awk -F "::" '{ print "${hasColon}"$${indexIntoModPath},int( NF / ${indexIntoModPath} ) }'`; - }, - postProcess: (out) => { - return [...new Set(out.split("\n"))].map((line) => { - const [display, last] = line.split(" "); - const lastModule = parseInt(last); - const displayName = display.replaceAll(":", ""); - const name = displayName.length - ? `${display}${lastModule ? "" : "::"}` - : ""; - return { name, displayName }; - }); - }, - trigger: ":", - getQueryTerm: ":", -}; +// TODO(grant): add this back but better with no awk +// const testGenerator: Fig.Generator = { +// cache: { +// cacheByDirectory: true, +// strategy: "stale-while-revalidate", +// ttl: 1000 * 60 * 5, +// }, +// script: (context) => { +// const base = context[context.length - 1]; +// // allow split by single colon so that it triggers on a::b: +// const indexIntoModPath = Math.max(base.split(/::?/).length, 1); +// // split by :: so that tokens with a single colon are allowed +// const moduleTokens = base.split("::"); +// const lastModule = moduleTokens.pop(); +// // check if the token has a : on the end +// const hasColon = lastModule[lastModule.length - 1] == ":" ? ":" : ""; +// return `cargo t -- --list | awk '/: test$/ { print substr($1, 1, length($1) - 1) }' | awk -F "::" '{ print "${hasColon}"$${indexIntoModPath},int( NF / ${indexIntoModPath} ) }'`; +// }, +// postProcess: (out) => { +// return [...new Set(out.split("\n"))].map((line) => { +// const [display, last] = line.split(" "); +// const lastModule = parseInt(last); +// const displayName = display.replaceAll(":", ""); +// const name = displayName.length +// ? `${display}${lastModule ? "" : "::"}` +// : ""; +// return { name, displayName }; +// }); +// }, +// trigger: ":", +// getQueryTerm: ":", +// }; type Metadata = { packages: Package[]; @@ -126,7 +127,7 @@ const rootPackageOrLocal = (manifest: Metadata) => { }; const packageGenerator: Fig.Generator = { - script: "cargo metadata --format-version 1 --no-deps", + script: ["cargo", "metadata", "--format-version", "1", "--no-deps"], postProcess: (data) => { const manifest: Metadata = JSON.parse(data); return manifest.packages.map((pkg) => { @@ -142,7 +143,7 @@ const packageGenerator: Fig.Generator = { }; const directDependencyGenerator: Fig.Generator = { - script: "cargo metadata --format-version 1", + script: ["cargo", "metadata", "--format-version", "1"], postProcess: (data: string) => { const manifest: Metadata = JSON.parse(data); const packages = rootPackageOrLocal(manifest); @@ -160,10 +161,11 @@ const targetGenerator: ({ kind }: { kind?: TargetKind }) => Fig.Generator = ({ kind, }) => ({ custom: async (_, executeShellCommand, context) => { - const out = await executeShellCommand( - "cargo metadata --format-version 1 --no-deps" - ); - const manifest: Metadata = JSON.parse(out); + const { stdout } = await executeShellCommand({ + command: "cargo", + args: ["metadata", "--format-version", "1", "--no-deps"], + }); + const manifest: Metadata = JSON.parse(stdout); const packages = rootPackageOrLocal(manifest); let targets = packages.flatMap((pkg) => pkg.targets); @@ -184,7 +186,7 @@ const targetGenerator: ({ kind }: { kind?: TargetKind }) => Fig.Generator = ({ }); const dependencyGenerator: Fig.Generator = { - script: "cargo metadata --format-version 1", + script: ["cargo", "metadata", "--format-version", "1"], postProcess: (data: string) => { const metadata: Metadata = JSON.parse(data); return metadata.packages.map((pkg) => ({ @@ -195,7 +197,7 @@ const dependencyGenerator: Fig.Generator = { }; const featuresGenerator: Fig.Generator = { - script: "cargo read-manifest", + script: ["cargo", "read-manifest"], postProcess: (data: string) => { const manifest = JSON.parse(data); return Object.keys(manifest.features || {}).map((name) => ({ @@ -243,10 +245,11 @@ const searchGenerator: Fig.Generator = { if (lastToken.includes("@") && !lastToken.startsWith("@")) { const [crate, _version] = lastToken.split("@"); const query = encodeURIComponent(crate); - const out = await executeShellCommand( - `curl -sfL 'https://crates.io/api/v1/crates/${query}/versions'` - ); - const json: VersionSearchResults = JSON.parse(out); + const { stdout } = await executeShellCommand({ + command: "curl", + args: ["-sfL", `https://crates.io/api/v1/crates/${query}/versions`], + }); + const json: VersionSearchResults = JSON.parse(stdout); return json.versions.map((version) => ({ name: `${crate}@${version.num}`, @@ -258,14 +261,22 @@ const searchGenerator: Fig.Generator = { })); } else if (lastToken.length > 0) { const query = encodeURIComponent(lastToken); - const [remoteOut, localOut] = await Promise.all([ - executeShellCommand( - `curl -sfL 'https://crates.io/api/v1/crates?q=${query}&per_page=60'` - ), - executeShellCommand(`cargo metadata --format-version 1 --no-deps`), - ]); + const [{ stdout: remoteStdout }, { stdout: localStdout }] = + await Promise.all([ + executeShellCommand({ + command: "curl", + args: [ + "-sfL", + `https://crates.io/api/v1/crates?q=${query}&per_page=60`, + ], + }), + executeShellCommand({ + command: "cargo", + args: ["metadata", "--format-version", "1", "--no-deps"], + }), + ]); - const remoteJson: CrateSearchResults = JSON.parse(remoteOut); + const remoteJson: CrateSearchResults = JSON.parse(remoteStdout); const remoteSuggustions: Fig.Suggestion[] = remoteJson.crates .sort((a, b) => b.recent_downloads - a.recent_downloads) .map((crate) => ({ @@ -278,8 +289,8 @@ const searchGenerator: Fig.Generator = { })); let localSuggestions: Fig.Suggestion[] = []; - if (localOut.trim().length > 0) { - const localJson: Metadata = JSON.parse(localOut); + if (localStdout.trim().length > 0) { + const localJson: Metadata = JSON.parse(localStdout); localSuggestions = localJson.packages .filter((pkg) => !pkg.source) .map((pkg) => ({ @@ -308,7 +319,7 @@ const searchGenerator: Fig.Generator = { }; const tripleGenerator: Fig.Generator = { - script: "rustc --print target-list", + script: ["rustc", "--print", "target-list"], postProcess: (data: string) => { return data .split("\n") @@ -4696,7 +4707,6 @@ const completionSpec: (toolchain?: boolean) => Fig.Spec = ( name: "args", isOptional: true, isVariadic: true, - generators: testGenerator, }, ], }, @@ -5006,7 +5016,11 @@ const completionSpec: (toolchain?: boolean) => Fig.Spec = ( args: { name: "SPEC", generators: { - script: `cargo install --list | \\grep -E "^[a-zA-Z\\-]+\\sv" | cut -d ' ' -f 1`, + script: [ + "bash", + "-c", + `cargo install --list | \\grep -E "^[a-zA-Z\\-]+\\sv" | cut -d ' ' -f 1`, + ], splitOn: "\n", }, isVariadic: true, @@ -5785,12 +5799,17 @@ const completionSpec: (toolchain?: boolean) => Fig.Spec = ( }, ], generateSpec: async (_tokens, executeShellCommand) => { - const [toolchainOutput, listOutput] = await Promise.all([ - executeShellCommand("rustup toolchain list"), - executeShellCommand("cargo --list"), - ]); + const [{ stdout: toolchainStdout }, { stdout: listOutput }] = + await Promise.all([ + executeShellCommand({ + command: "rustup", + args: ["toolchain", "list"], + }), + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + executeShellCommand({ command: "cargo", args: ["--list"] }), + ]); - const toolchains: Fig.Option[] = toolchainOutput + const toolchains: Fig.Option[] = toolchainStdout .split("\n") .map((toolchain) => { return { diff --git a/src/cf.ts b/src/cf.ts index 648d3e93f086..58fc2ea82eb6 100644 --- a/src/cf.ts +++ b/src/cf.ts @@ -7,22 +7,22 @@ const postProcessCfList = .map((name) => ({ name, description })); const generateAppNames: Fig.Generator = { - script: `cf apps | cut -d " " -f1`, + script: ["bash", "-c", `cf apps | cut -d " " -f1`], postProcess: postProcessCfList("App name", 4), }; const generateOrgs: Fig.Generator = { - script: `cf orgs`, + script: ["cf", "orgs"], postProcess: postProcessCfList("Org", 3), }; const generateSpaces: Fig.Generator = { - script: `cf spaces`, + script: ["cf", "spaces"], postProcess: postProcessCfList("Space", 3), }; const generateServices: Fig.Generator = { - script: `cf services | cut -d " " -f1 `, + script: ["bash", "-c", `cf services | cut -d " " -f1 `], postProcess: postProcessCfList("Service", 4), }; diff --git a/src/checkov.ts b/src/checkov.ts index d56c0189c553..c9e28d66b749 100644 --- a/src/checkov.ts +++ b/src/checkov.ts @@ -1,5 +1,5 @@ const branches: Fig.Generator = { - script: "git branch --no-color", + script: ["git", "branch", "--no-color"], postProcess: (output) => { if (output.startsWith("fatal:")) { return []; diff --git a/src/chown.ts b/src/chown.ts index 02ec642d0bd9..c271be0bd401 100644 --- a/src/chown.ts +++ b/src/chown.ts @@ -8,13 +8,20 @@ export const existingUsersandGroups: Fig.Generator = { // in the current command. If it is, get the system groups // else retrieve the list of system users if (colonAdded) { - shell = await executeShellCommand( - "dscl . -list /Groups PrimaryGroupID | tr -s ' '| sort -r" - ); + const { stdout } = await executeShellCommand({ + command: "bash", + args: [ + "-c", + "dscl . -list /Groups PrimaryGroupID | tr -s ' '| sort -r", + ], + }); + shell = stdout; } else { - shell = await executeShellCommand( - "dscl . -list /Users UniqueID | tr -s ' '| sort -r" - ); + const { stdout } = await executeShellCommand({ + command: "bash", + args: ["-c", "dscl . -list /Users UniqueID | tr -s ' '| sort -r"], + }); + shell = stdout; } return ( diff --git a/src/chsh.ts b/src/chsh.ts index f67870193e92..ca52ef1a91be 100644 --- a/src/chsh.ts +++ b/src/chsh.ts @@ -1,6 +1,6 @@ // TODO: this does not work on macos const shells: Fig.Generator = { - script: "chsh -l", + script: ["chsh", "-l"], postProcess: (output) => { if (output.startsWith("fatal:")) { return []; diff --git a/src/coda.ts b/src/coda.ts index e4c07cb61810..61b36cd4c9b3 100644 --- a/src/coda.ts +++ b/src/coda.ts @@ -1,7 +1,11 @@ import { filepaths } from "@fig/autocomplete-generators"; const formulaNames: Fig.Generator = { - script: `grep -A5 --include=\*.ts --exclude-dir=node_modules -r 'addFormula\\|addSyncTable\\|makeFormula\\|makeSyncTable' . | grep -A3 -i formula | grep name: | grep -oE "['\\"]\\w*['\\"]"`, + script: [ + "bash", + "-c", + `grep -A5 --include=\*.ts --exclude-dir=node_modules -r 'addFormula\\|addSyncTable\\|makeFormula\\|makeSyncTable' . | grep -A3 -i formula | grep name: | grep -oE "['\\"]\\w*['\\"]"`, + ], postProcess: (output) => { if (output.trim().length === 0) { return []; diff --git a/src/composer.ts b/src/composer.ts index 9b89eaefa316..660efdfd3571 100644 --- a/src/composer.ts +++ b/src/composer.ts @@ -40,9 +40,15 @@ const PACKAGE_REGEXP = new RegExp("^.*/.*$"); const searchGenerator: Fig.Generator = { script: function (context) { - if (context[context.length - 1] === "") return ""; + if (context[context.length - 1] === "") return undefined; const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://packagist.org/search.json?q=${searchTerm}&per_page=20"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://packagist.org/search.json?q=${searchTerm}&per_page=20`, + ]; }, postProcess: function (out) { try { @@ -62,7 +68,7 @@ const searchGenerator: Fig.Generator = { // generate package list from composer.json file const packagesGenerator: Fig.Generator = { - script: "cat composer.json", + script: ["cat", "composer.json"], postProcess: function (out) { if (out.trim() == "") { return []; @@ -97,13 +103,22 @@ const completionSpec: Fig.Spec = { name: "composer", description: "Composer Command", generateSpec: async (tokens, executeShellCommand) => { - const jsonList = await executeShellCommand("composer list --format=json"); - const symfonyLock = await executeShellCommand(`file symfony.lock`); + const [jsonList, symfonyLock] = await Promise.all([ + executeShellCommand({ + command: "composer", + args: ["list", "--format=json"], + }), + executeShellCommand({ + command: "ls", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["symfony.lock"], + }), + ]); const subcommands: Fig.Subcommand[] = []; try { - const data: ComposerListOutput = JSON.parse(jsonList); + const data: ComposerListOutput = JSON.parse(jsonList.stdout); const packagesGeneratorTriggersCommands = ["update", "remove"]; for (const command of data.commands) { @@ -204,9 +219,7 @@ const completionSpec: Fig.Spec = { }, ]; - const symfonyLockExists = !symfonyLock.endsWith( - "(No such file or directory)" - ); + const symfonyLockExists = symfonyLock.status === 0; if (symfonyLockExists) { subcommands.push({ name: ["recipes", "symfony:recipes"], diff --git a/src/conda.ts b/src/conda.ts index d20bc9c499f4..01e66016aca0 100644 --- a/src/conda.ts +++ b/src/conda.ts @@ -1,5 +1,5 @@ const getInstalledPackages: Fig.Generator = { - script: "conda list", + script: ["conda", "list"], postProcess: function (out) { const lines = out.split("\n"); const installedPackages = []; @@ -14,7 +14,7 @@ const getInstalledPackages: Fig.Generator = { }; // const getAllCondaPackages: Fig.Generator = { -// //script: "conda search -q", +// //script: ["conda", "search", "-q"], // script: function (context) { // if (context[context.length - 1] === "") return ""; // const searchTerm = context[context.length - 1]; @@ -35,7 +35,7 @@ const getInstalledPackages: Fig.Generator = { // }; const getCondaEnvironments: Fig.Generator = { - script: "conda env list", + script: ["conda", "env", "list"], scriptTimeout: 10000, cache: { ttl: 10000, @@ -56,7 +56,7 @@ const getCondaEnvironments: Fig.Generator = { }; const getCondaConfigs: Fig.Generator = { - script: "conda config --show", + script: ["conda", "config", "--show"], postProcess: function (out) { const lines = out.split("\n"); const configs: Fig.Suggestion[] = []; diff --git a/src/copilot.ts b/src/copilot.ts index bd4e7af78b73..a292d9fce01c 100644 --- a/src/copilot.ts +++ b/src/copilot.ts @@ -1,7 +1,7 @@ import YAML from "yaml"; const applicationName: Fig.Generator = { - script: "cat copilot/.workspace", + script: ["cat", "copilot/.workspace"], // TODO: I feel like there's a better way to do this. // There's only ever expected to be one `application` key. postProcess: (output) => { diff --git a/src/cordova.ts b/src/cordova.ts index aac5d9dd4097..e7ae9a749b01 100644 --- a/src/cordova.ts +++ b/src/cordova.ts @@ -24,7 +24,7 @@ const commonOptions: Fig.Option[] = [ ]; const platformGenerator: Fig.Generator = { - script: "cat package.json", + script: ["cat", "package.json"], postProcess: function (out: string) { const suggestions = []; try { @@ -51,7 +51,7 @@ const platformGenerator: Fig.Generator = { }; const pluginGenerator: Fig.Generator = { - script: "cordova plugin list", + script: ["cordova", "plugin", "list"], postProcess: (out: string) => out.split("\n").map((pluginName) => ({ name: pluginName, diff --git a/src/dcli.ts b/src/dcli.ts index 9ddd566c303b..c172b67476ec 100644 --- a/src/dcli.ts +++ b/src/dcli.ts @@ -31,7 +31,7 @@ const helpCommand: Fig.Subcommand = { }; const deviceGenerator: Fig.Generator = { - script: "dcli devices list --json", + script: ["dcli", "devices", "list", "--json"], postProcess: function (out) { try { const devices = JSON.parse(out) as Device[]; @@ -51,7 +51,7 @@ const deviceGenerator: Fig.Generator = { }; const teamCredentialGenerator: Fig.Generator = { - script: "dcli team credentials list --json", + script: ["dcli", "team", "credentials", "list", "--json"], postProcess: function (out) { try { const credentials = JSON.parse(out) as TeamCredential[]; diff --git a/src/defaultbrowser.ts b/src/defaultbrowser.ts index 40f5b2460db8..fa5f0aa1d2e7 100644 --- a/src/defaultbrowser.ts +++ b/src/defaultbrowser.ts @@ -1,5 +1,5 @@ const getInstalledBrowsers: Fig.Generator = { - script: "defaultbrowser", + script: ["defaultbrowser"], postProcess: function (out) { return out.split("\n").map((line) => { /* We ignore the already set browser */ diff --git a/src/defaults.ts b/src/defaults.ts index 5354a31c2ff7..4350993c4ece 100644 --- a/src/defaults.ts +++ b/src/defaults.ts @@ -1,7 +1,7 @@ const domain: Fig.Arg = { name: "domain", generators: { - script: "defaults domains", + script: ["defaults", "domains"], postProcess: function (out) { return out.split(",").map((domain) => { return { diff --git a/src/degit.ts b/src/degit.ts index d3fa05c87f8c..116d32d527c0 100644 --- a/src/degit.ts +++ b/src/degit.ts @@ -120,10 +120,11 @@ const completionSpec: Fig.Spec = { const lastToken = tokens[tokens.length - 1]; if (lastToken.includes(":")) return []; const username = lastToken.slice(0, lastToken.indexOf("/")); - const json = await executeShellCommand( - `curl -sL 'https://api.github.com/users/${username}/repos'` - ); - const repos = JSON.parse(json) as Repository[]; + const { stdout } = await executeShellCommand({ + command: "curl", + args: ["-sL", `https://api.github.com/users/${username}/repos`], + }); + const repos = JSON.parse(stdout) as Repository[]; return repos.map((repo) => ({ name: repo.full_name, description: repo.description ?? "Repository", diff --git a/src/deno/generators.ts b/src/deno/generators.ts index a6ec1a429a35..6df0c2450fad 100644 --- a/src/deno/generators.ts +++ b/src/deno/generators.ts @@ -165,7 +165,7 @@ export const generateDocs: Fig.Generator = { !token.startsWith("(") ); command.push("--json"); - return command.join(" "); + return command; }, postProcess: (out, tokens) => { const docNodes = JSON.parse(out) as DocNode[]; @@ -191,7 +191,7 @@ type VersionsJSON = { }; export const generateVersions: Fig.Generator = { - script: `curl -sL 'https://cdn.deno.land/deno/meta/versions.json'`, + script: ["curl", "-sL", "https://cdn.deno.land/deno/meta/versions.json"], cache: { ttl: 1000 * 60 * 60 * 24 }, // 24 hours, in milliseconds postProcess: (out) => { const data = JSON.parse(out) as VersionsJSON; @@ -611,17 +611,26 @@ function getConfigPath(tokens: string[]): string | null { async function getDenoConfig( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ): Promise { const configPath = getConfigPath(tokens); let jsonString: string; if (configPath) { - jsonString = await executeShellCommand(`\\cat '${configPath}'`); + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [configPath], + }); + jsonString = stdout; } else { // Move backwards through the directory heirarchy until we find a config file (or hit the root) - jsonString = await executeShellCommand( - "until [[ ( -f deno.json || -f deno.jsonc || $PWD = '/' ) ]]; do cd ..; done; \\cat deno.json 2>/dev/null || \\cat deno.jsonc 2>/dev/null" - ); + const { stdout } = await executeShellCommand({ + command: "bash", + args: [ + "-c", + "until [[ ( -f deno.json || -f deno.jsonc || $PWD = '/' ) ]]; do cd ..; done; \\cat deno.json 2>/dev/null || \\cat deno.jsonc 2>/dev/null", + ], + }); } try { return JSON.parse(stripJsonComments(jsonString)); @@ -657,7 +666,11 @@ export const generateTasks: Fig.Generator = { // --- Generate installed deno scripts export const generateInstalledDenoScripts: Fig.Generator = { - script: "command find ~/.deno/bin -maxdepth 1 -perm -111 -type f", + script: [ + "bash", + "-c", + "command find ~/.deno/bin -maxdepth 1 -perm -111 -type f", + ], postProcess: (out) => out .split("\n") @@ -692,7 +705,7 @@ export const generateUrlScript: Fig.Generator = { // There's no simple solution for pasting on Linux, it depends on // whether you use X11 or Wayland. For Wayland on some (most?) distros, // you would have to manually install wl-paste. - script: `pbpaste`, + script: ["pbpaste"], postProcess: (clipboard) => { clipboard = clipboard.trim(); if (!clipboard) { diff --git a/src/deployctl.ts b/src/deployctl.ts index 101066ecbe41..62fc4593001f 100644 --- a/src/deployctl.ts +++ b/src/deployctl.ts @@ -67,7 +67,11 @@ const completionSpec: Fig.Spec = { name: "version", isOptional: true, generators: { - script: `curl -sL 'https://cdn.deno.land/deploy/meta/versions.json'`, + script: [ + "curl", + "-sL", + "https://cdn.deno.land/deploy/meta/versions.json", + ], cache: { ttl: 1000 * 60 * 60 * 24 }, // 24 hours, in milliseconds postProcess: (out) => { const data = JSON.parse(out) as VersionsJSON; diff --git a/src/deta.ts b/src/deta.ts index c0803eff4652..e86776d8c989 100644 --- a/src/deta.ts +++ b/src/deta.ts @@ -7,17 +7,15 @@ // Fig generator for runtime options. Manually coded from // https://docs.deta.sh/docs/cli/commands#deta-new -const runtimes: Fig.Generator = { - script: "echo node12, node14, python3.7, python3.9", - postProcess: (output) => { - return output.split(",").map((runtime) => { - return { - name: runtime, - description: "Runtime", - }; - }); - }, -}; +const runtimes: Fig.Suggestion[] = [ + "node12", + "node14", + "python3.7", + "python3.9", +].map((runtime) => ({ + name: runtime, + description: "Runtime", +})); const completionSpec: Fig.Spec = { name: "deta", @@ -115,7 +113,7 @@ const completionSpec: Fig.Spec = { args: { name: "runtime", description: "The selected runtime", - generators: runtimes, + suggestions: runtimes, }, }, ], @@ -325,7 +323,7 @@ const completionSpec: Fig.Spec = { args: { name: "runtime", description: "New runtime for the micro", - generators: runtimes, + suggestions: runtimes, }, }, { diff --git a/src/docker-compose.ts b/src/docker-compose.ts index 532e88c31235..af49fadb68ae 100644 --- a/src/docker-compose.ts +++ b/src/docker-compose.ts @@ -1,7 +1,7 @@ const getComposeCommand = (tokens: string[]) => - tokens[0] === "docker" ? "docker compose" : "docker-compose"; + tokens[0] === "docker" ? ["docker", "compose"] : ["docker-compose"]; -const extractFileArgs = (tokens: string[]): string => { +const extractFileArgs = (tokens: string[]): string[] => { const files: string[] = []; for (let i = 0; i < tokens.length - 1; i++) { if (tokens[i] === "-f") { @@ -9,14 +9,14 @@ const extractFileArgs = (tokens: string[]): string => { i += 1; } } - return files.map((f) => `-f ${f}`).join(" "); + return files.flatMap((f) => ["-f", f]); }; const servicesGenerator: Fig.Generator = { script: (tokens) => { const compose = getComposeCommand(tokens); const fileArgs = extractFileArgs(tokens); - return `${compose} ${fileArgs} config --services`; + return [...compose, ...fileArgs, "config", "--services"]; }, splitOn: "\n", }; @@ -25,7 +25,7 @@ const profilesGenerator: Fig.Generator = { script: (tokens) => { const compose = getComposeCommand(tokens); const fileArgs = extractFileArgs(tokens); - return `${compose} ${fileArgs} config --profiles`; + return [...compose, ...fileArgs, "config", "--profiles"]; }, splitOn: "\n", }; diff --git a/src/docker.ts b/src/docker.ts index 66a89a2dc4cf..99dff039066a 100644 --- a/src/docker.ts +++ b/src/docker.ts @@ -26,19 +26,26 @@ const sharedPostProcess: Fig.Generator["postProcess"] = (out) => { const dockerGenerators: Record = { runningDockerContainers: { - script: `docker ps --format '{{ json . }}'`, + script: ["docker", "ps", "--format", "{{ json . }}"], postProcess: postProcessDockerPs, }, allDockerContainers: { - script: `docker ps -a --format '{{ json . }}'`, + script: ["docker", "ps", "-a", "--format", "{{ json . }}"], postProcess: postProcessDockerPs, }, pausedDockerContainers: { - script: `docker ps --filter status=paused --format '{{ json . }}'`, + script: [ + "docker", + "ps", + "--filter", + "status=paused", + "--format", + "{{ json . }}", + ], postProcess: postProcessDockerPs, }, allLocalImages: { - script: `docker image ls --format '{{ json . }}'`, + script: ["docker", "image", "ls", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -51,7 +58,7 @@ const dockerGenerators: Record = { }, }, allLocalImagesWithRepository: { - script: `docker image ls --format '{{ json . }}'`, + script: ["docker", "image", "ls", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -65,9 +72,9 @@ const dockerGenerators: Record = { }, dockerHubSearch: { script: function (context) { - if (context[context.length - 1] === "") return ""; + if (context[context.length - 1] === "") return undefined; const searchTerm = context[context.length - 1]; - return `docker search ${searchTerm} --format '{{ json . }}'`; + return ["docker", "search", searchTerm, "--format", "{{ json . }}"]; }, postProcess: function (out) { return out @@ -83,7 +90,7 @@ const dockerGenerators: Record = { }, }, allDockerContexts: { - script: `docker context list --format '{{ json . }}'`, + script: ["docker", "context", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -96,11 +103,11 @@ const dockerGenerators: Record = { }, }, listDockerNetworks: { - script: `docker network list --format '{{ json . }}'`, + script: ["docker", "network", "list", "--format", "{{ json . }}"], postProcess: sharedPostProcess, }, listDockerSwarmNodes: { - script: `docker node list --format '{{ json . }}'`, + script: ["docker", "node", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -114,15 +121,15 @@ const dockerGenerators: Record = { }, }, listDockerPlugins: { - script: `docker plugin list --format '{{ json . }}'`, + script: ["docker", "plugin", "list", "--format", "{{ json . }}"], postProcess: sharedPostProcess, }, listDockerSecrets: { - script: `docker secret list --format '{{ json . }}'`, + script: ["docker", "secret", "list", "--format", "{{ json . }}"], postProcess: sharedPostProcess, }, listDockerServices: { - script: `docker service list --format '{{ json . }}'`, + script: ["docker", "service", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -135,7 +142,7 @@ const dockerGenerators: Record = { }, }, listDockerServicesReplicas: { - script: `docker service list --format '{{ json . }}'`, + script: ["docker", "service", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -148,7 +155,7 @@ const dockerGenerators: Record = { }, }, listDockerStacks: { - script: `docker stack list --format '{{ json . }}'`, + script: ["docker", "stack", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -160,7 +167,7 @@ const dockerGenerators: Record = { }, }, listDockerVolumes: { - script: `docker volume list --format '{{ json . }}'`, + script: ["docker", "volume", "list", "--format", "{{ json . }}"], postProcess: function (out) { return out .split("\n") @@ -346,10 +353,10 @@ const sharedCommands: Record = { fileFlagIndex = context.indexOf("--file"); dockerfilePath = context[fileFlagIndex + 1]; } else { - dockerfilePath = "$PWD/Dockerfile"; + dockerfilePath = "Dockerfile"; } - return `\\grep -iE 'FROM.*AS' "${dockerfilePath}"`; + return ["grep", "-iE", "FROM.*AS", dockerfilePath]; }, postProcess: function (out) { // This just searches the Dockerfile for the alias name after AS, @@ -1978,8 +1985,12 @@ default-cgroupns-mode option on the daemon (default)`, name: "image", description: "The Docker image to use", generators: { - script: - "docker images --format '{{.Repository}} {{.Size}} {{.Tag}} {{.ID}}'", + script: [ + "docker", + "images", + "--format", + "{{.Repository}} {{.Size}} {{.Tag}} {{.ID}}", + ], postProcess: function (out) { return out.split("\n").map((image) => { const [repo, size, tag, id] = image.split(" "); @@ -2599,7 +2610,7 @@ const completionSpec: Fig.Spec = { name: "Name or ID", generators: [ { - script: `docker ps -a --format '{{ json . }}'`, + script: ["docker", "ps", "-a", "--format", "{{ json . }}"], postProcess: function (out) { const allLines = out.split("\n").map((line) => JSON.parse(line)); return allLines.map((i) => ({ @@ -2609,7 +2620,7 @@ const completionSpec: Fig.Spec = { }, }, { - script: `docker images -a --format '{{ json . }}'`, + script: ["docker", "images", "-a", "--format", "{{ json . }}"], postProcess: function (out) { const allLines = out.split("\n").map((line) => JSON.parse(line)); return allLines.map((i) => { @@ -2631,7 +2642,7 @@ const completionSpec: Fig.Spec = { }, }, { - script: `docker volume ls --format '{{ json . }}'`, + script: ["docker", "volume", "ls", "--format", "{{ json . }}"], postProcess: function (out) { const allLines = out.split("\n").map((line) => JSON.parse(line)); return allLines.map((i) => ({ diff --git a/src/doppler.ts b/src/doppler.ts index 80a5cc4001bc..7d730c20fcbd 100644 --- a/src/doppler.ts +++ b/src/doppler.ts @@ -4,7 +4,7 @@ const enviornmentsGenerator: Fig.Generator = { cacheKey: "enviornments", cacheByDirectory: true, }, - script: "doppler environments --json", + script: ["doppler", "environments", "--json"], postProcess: (out) => { try { const obj = JSON.parse(out); @@ -24,7 +24,7 @@ const configGenerators: Fig.Generator = { cacheKey: "configs", cacheByDirectory: true, }, - script: "doppler configs --json", + script: ["doppler", "configs", "--json"], postProcess: (out) => { try { const obj = JSON.parse(out); @@ -44,7 +44,7 @@ const secretsGenerator: Fig.Generator = { cacheKey: "secrets", cacheByDirectory: true, }, - script: "doppler secrets --only-names --json", + script: ["doppler", "secrets", "--only-names", "--json"], postProcess: (out) => { try { const obj = JSON.parse(out); @@ -64,7 +64,7 @@ const projectsGenerator: Fig.Generator = { cacheKey: "projects", cacheByDirectory: true, }, - script: "doppler projects --json", + script: ["doppler", "projects", "--json"], postProcess: (out) => { try { const obj = JSON.parse(out); diff --git a/src/dotnet.ts b/src/dotnet.ts index c41ec1a37cd3..f519cc3e5692 100644 --- a/src/dotnet.ts +++ b/src/dotnet.ts @@ -211,9 +211,12 @@ const completionSpec: Fig.Spec = { const argRegex = /(([a-zA-Z \.\[\]#,/][^ ]{1,})+)/g; const subcommands: Fig.Subcommand[] = []; - const toolList = await executeShellCommand("dotnet tool list --global"); + const { stdout } = await executeShellCommand({ + command: "dotnet", + args: ["tool", "list", "--global"], + }); - const lines = toolList.split("\n").slice(2); + const lines = stdout.split("\n").slice(2); for (const line of lines) { const [_, __, command] = line diff --git a/src/dotnet/dotnet-add.ts b/src/dotnet/dotnet-add.ts index 72b7e141e288..0c9d8b8691f7 100644 --- a/src/dotnet/dotnet-add.ts +++ b/src/dotnet/dotnet-add.ts @@ -9,7 +9,13 @@ type PackageSearchResultData = { const packageSearchGenerator: Fig.Generator = { script(context) { const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://azuresearch-usnc.nuget.org/query?packageType=Dependency&q=${searchTerm}"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://azuresearch-usnc.nuget.org/query?packageType=Dependency&q=${searchTerm}`, + ]; }, postProcess(out) { const searchResults: PackageSearchResultData[] = JSON.parse(out).data; @@ -30,7 +36,13 @@ const versionSearchGenerator: Fig.Generator = { const idx = command.findIndex((ctx) => ctx === "package"); const searchTerm = command[idx + 1].toLowerCase(); - return `curl -s -H "Accept: application/json" "https://api.nuget.org/v3-flatcontainer/${searchTerm}/index.json"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://api.nuget.org/v3-flatcontainer/${searchTerm}/index.json`, + ]; }, postProcess(out) { const searchResults: string[] = JSON.parse(out).versions; diff --git a/src/dotnet/dotnet-new.ts b/src/dotnet/dotnet-new.ts index ff15f9659f6f..c5e8d3e1203b 100644 --- a/src/dotnet/dotnet-new.ts +++ b/src/dotnet/dotnet-new.ts @@ -7,7 +7,13 @@ type SearchResultData = { const searchGenerator: Fig.Generator = { script(context) { const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://azuresearch-usnc.nuget.org/query?packageType=Template&q=${searchTerm}"`; + return [ + "curl", + "-sfL", + "-H", + "Accept: application/json", + `https://azuresearch-usnc.nuget.org/query?packageType=Template&q=${searchTerm}`, + ]; }, postProcess(out) { const searchResults: SearchResultData[] = JSON.parse(out).data; @@ -182,7 +188,7 @@ const completionSpec: Fig.Spec = { description: "The template to instantiate when the command is invoked. Each template might have specific options you can pass", generators: { - script: "dotnet new --list", + script: ["dotnet", "new", "--list"], postProcess(out) { const lines = out.split("\n").slice(4); diff --git a/src/dotnet/dotnet-run.ts b/src/dotnet/dotnet-run.ts index 185093ee0dc9..b7a221f15ce0 100644 --- a/src/dotnet/dotnet-run.ts +++ b/src/dotnet/dotnet-run.ts @@ -58,7 +58,7 @@ const completionSpec: Fig.Spec = { name: "name", suggestions: ["Development", "Staging", "Production"], generators: { - script: "cat Properties/launchSettings.json", + script: ["cat", "Properties/launchSettings.json"], postProcess(out) { const profiles: LaunchProfiles = JSON.parse(out).profiles; diff --git a/src/dotnet/dotnet-tool.ts b/src/dotnet/dotnet-tool.ts index a6c9c2e50707..d7e53367ac0c 100644 --- a/src/dotnet/dotnet-tool.ts +++ b/src/dotnet/dotnet-tool.ts @@ -9,7 +9,13 @@ type SearchResultData = { const packageGenerator: Fig.Generator = { script(context) { const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://azuresearch-usnc.nuget.org/query?packageType=DotnetTool&q=${searchTerm}"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://azuresearch-usnc.nuget.org/query?packageType=DotnetTool&q=${searchTerm}`, + ]; }, postProcess(out) { const searchResults: SearchResultData[] = JSON.parse(out).data; @@ -31,7 +37,13 @@ const versionSearchGenerator: Fig.Generator = { const idx = command.findIndex((ctx) => commands.includes(ctx)); const searchTerm = command[idx + 1].toLowerCase(); - return `curl -s -H "Accept: application/json" "https://api.nuget.org/v3-flatcontainer/${searchTerm}/index.json"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://api.nuget.org/v3-flatcontainer/${searchTerm}/index.json`, + ]; }, postProcess(out) { const searchResults: string[] = JSON.parse(out).versions; @@ -52,10 +64,10 @@ const toolListGenerator: Fig.Generator = { const globalFlags = ["-g", "--global"]; if (context.some((ctx) => globalFlags.includes(ctx))) { - return "dotnet tool list --global"; + return ["dotnet", "tool", "list", "--global"]; } - return "dotnet tool list"; + return ["dotnet", "tool", "list"]; }, postProcess(out) { const lines = out.split("\n").slice(2); diff --git a/src/drush.ts b/src/drush.ts index 7574f6f1e87f..d7f7549ae5a2 100644 --- a/src/drush.ts +++ b/src/drush.ts @@ -38,7 +38,11 @@ const completionSpec: Fig.Spec = { description: "Drush is a command line shell and Unix scripting interface for Drupal", generateSpec: async (tokens, executeShellCommand) => { - const jsonList = await executeShellCommand("drush --format=json"); + const { stdout: jsonList } = await executeShellCommand({ + command: "drush", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--format=json"], + }); const subcommands: Fig.Subcommand[] = []; try { diff --git a/src/dscacheutil.ts b/src/dscacheutil.ts index 5e73d575719e..36728e695f3f 100644 --- a/src/dscacheutil.ts +++ b/src/dscacheutil.ts @@ -52,7 +52,12 @@ const dscacheutilGenerators: Record = { const attributeKey = tokens[tokens.length - 2]; const pp = postProcessQuery({ attributeKey }); return pp( - await executeShellCommand(`dscacheutil -q ${category}`), + ( + await executeShellCommand({ + command: "dscacheutil", + args: ["-q", category], + }) + ).stdout, tokens ); }, diff --git a/src/dscl.ts b/src/dscl.ts index eb4f0c5364ef..781a0db3cadf 100644 --- a/src/dscl.ts +++ b/src/dscl.ts @@ -85,8 +85,10 @@ const generateDsclPath: Fig.Generator = { } const lastSlashIndex = lastToken.lastIndexOf("/"); const path = lastToken.slice(0, lastSlashIndex < 0 ? 0 : lastSlashIndex); - const command = `dscl ${datasource} -list ${path || "/"}`; - const lines = await executeShellCommand(command); + const { stdout: lines } = await executeShellCommand({ + command: "dscl", + args: [datasource, "-list", path ?? "/"], + }); return lines .trim() .split("\n") diff --git a/src/dtm.ts b/src/dtm.ts index 846b0fe8827c..4066bb62f6be 100644 --- a/src/dtm.ts +++ b/src/dtm.ts @@ -1,7 +1,7 @@ import { filepaths } from "@fig/autocomplete-generators"; const dtmGenerators: Record = { plugins: { - script: "dtm list plugins", + script: ["dtm", "list", "plugins"], postProcess: (output) => { if (output.startsWith("fatal:")) { return []; diff --git a/src/eb.ts b/src/eb.ts index 88aa0e84a206..5ec3d2c96e63 100644 --- a/src/eb.ts +++ b/src/eb.ts @@ -1,5 +1,5 @@ const generateNames: Fig.Generator = { - script: "eb list", + script: ["eb", "list"], postProcess: (str) => { const lines: string[] = str .trim() diff --git a/src/elm-format.ts b/src/elm-format.ts index 81a6e01e345a..128780524ba7 100644 --- a/src/elm-format.ts +++ b/src/elm-format.ts @@ -1,16 +1,11 @@ -const supportedElmVersions: Fig.Generator = { - script: "echo", - postProcess: () => { - return [ - { - name: "0.19", - }, - { - name: "0.18", - }, - ]; +const supportedElmVersions = [ + { + name: "0.19", }, -}; + { + name: "0.18", + }, +]; /** * Based on [elm-format](https://github.com/avh4/elm-format), version 0.8.5. A cli tool for formatting Elm code. @@ -51,7 +46,7 @@ const completionSpec: Fig.Spec = { args: { name: "VERSION", description: "Valid values: 0.18, 0.19. Default: auto", - generators: supportedElmVersions, + suggestions: supportedElmVersions, isOptional: true, }, }, diff --git a/src/elm-json.ts b/src/elm-json.ts index 910c029407c7..a6f5fb944458 100644 --- a/src/elm-json.ts +++ b/src/elm-json.ts @@ -1,8 +1,13 @@ import { filepaths } from "@fig/autocomplete-generators"; const packageList: Fig.Generator = { - script: - "curl -sH 'accept-encoding: gzip' --compressed https://package.elm-lang.org/search.json", + script: [ + "curl", + "-sH", + "accept-encoding: gzip", + "--compressed", + "https://package.elm-lang.org/search.json", + ], cache: { ttl: 1000 * 24 * 60 * 60 * 3, // 3 days }, diff --git a/src/elm-review.ts b/src/elm-review.ts index 758d12c19829..f34e7966d0cb 100644 --- a/src/elm-review.ts +++ b/src/elm-review.ts @@ -1,21 +1,16 @@ /** * The report type is either `json` or `ndjson` */ -const reportType: Fig.Generator = { - script: "echo", - postProcess: () => { - return [ - { - name: "json", - description: "Prints a single JSON object", - }, - { - name: "ndjson", - description: "Print one JSON object per error each on a new line", - }, - ]; +const reportType = [ + { + name: "json", + description: "Prints a single JSON object", }, -}; + { + name: "ndjson", + description: "Print one JSON object per error each on a new line", + }, +]; /** * Based on [elm-review](https://github.com/jfmengels/node-elm-review), version 2.9.1. Cli tool for reviewing Elm code. @@ -198,7 +193,7 @@ const completionSpec: Fig.Spec = { description: "Error reports will be in JSON format", args: { name: "json or ndjson", - generators: reportType, + suggestions: reportType, }, }, { diff --git a/src/elm.ts b/src/elm.ts index 27f802f8981c..6903637d8c1a 100644 --- a/src/elm.ts +++ b/src/elm.ts @@ -1,6 +1,11 @@ const packageList: Fig.Generator = { - script: - "curl -sH 'accept-encoding: gzip' --compressed https://package.elm-lang.org/search.json", + script: [ + "curl", + "-sH", + "accept-encoding: gzip", + "--compressed", + "https://package.elm-lang.org/search.json", + ], cache: { ttl: 1000 * 24 * 60 * 60 * 3, // 3 days }, diff --git a/src/env.ts b/src/env.ts index 65ac5ccd66e5..de01be77f23d 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,11 +1,12 @@ const enviromentVariables: Fig.Generator = { - script: "env | cut -d '=' -f 1", - postProcess: (out) => { - return out.split("\n").map((envVar) => ({ - name: envVar, - description: "Environment variable", - icon: "🌎", - })); + custom: async (_tokens, _executeCommand, generatorContext) => { + return Object.values(generatorContext.environmentVariables).map( + (envVar) => ({ + name: envVar, + description: "Environment variable", + icon: "🌎", + }) + ); }, }; diff --git a/src/envchain.ts b/src/envchain.ts index 4ad6e057892a..bdba19294bc8 100644 --- a/src/envchain.ts +++ b/src/envchain.ts @@ -1,5 +1,5 @@ const namespaces: Fig.Generator = { - script: "envchain --list", + script: ["envchain", "--list"], postProcess: (output) => { return Array.from(new Set(output.split("\n"))).map((namespace) => { return { diff --git a/src/esbuild.ts b/src/esbuild.ts index 1fdba4d5c28a..53934f64c830 100644 --- a/src/esbuild.ts +++ b/src/esbuild.ts @@ -6,10 +6,14 @@ const icon = const ignoreExtensions = new Set(["", "sample", "env"]); const extensions: Fig.Generator["custom"] = async (_, executeShellCommand) => { - const out = await executeShellCommand( - "find . -depth 3 -type f -name '*.*' -not -path '*/node_modules/*' | sed 's/.*\\.//' | sort -u" - ); - const lines = out.trim().split("\n"); + const { stdout } = await executeShellCommand({ + command: "bash", + args: [ + "-c", + "find . -depth 3 -type f -name '*.*' -not -path '*/node_modules/*' | sed 's/.*\\.//' | sort -u", + ], + }); + const lines = stdout.trim().split("\n"); return lines .filter((line) => !ignoreExtensions.has(line)) .map((line) => ({ name: "." + line })); diff --git a/src/eslint.ts b/src/eslint.ts index 2653d6a9fd09..663f213154ae 100644 --- a/src/eslint.ts +++ b/src/eslint.ts @@ -115,8 +115,11 @@ const completionSpec: Fig.Spec = { args: { name: "Plugin", generators: { - script: + script: [ + "bash", + "-c", "{ ls node_modules ; ls $(npm root -g) ; ls $(yarn global dir)/node_modules/ ; } | cat", + ], postProcess: (out) => out .split("\n") diff --git a/src/example/trigger.ts b/src/example/trigger.ts index 0108abf86ca0..52c6b0210306 100644 --- a/src/example/trigger.ts +++ b/src/example/trigger.ts @@ -7,13 +7,13 @@ // NOTE: replace _prefix_string_for_file_and_folder_suggestions with whatever prefix you'd like e.g. "s3://" const _prefix_string_for_file_and_folder_suggestions = "file://"; -var customArgument = { +var customArgument: Fig.Arg = { name: "FILE/FOLDER", description: "must start with " + _prefix_string_for_file_and_folder_suggestions, generators: { script: (tokens) => { - var baseLSCommand = "\\ls -1ApL "; + var baseLsCommand = ["ls", "-1ApL"]; var whatHasUserTyped = tokens[tokens.length - 1]; if ( @@ -23,7 +23,7 @@ var customArgument = { ) { whatHasUserTyped = whatHasUserTyped.slice(7); } else { - return "echo 'file://'"; + return ["echo", "file://"]; } // Get the folder path to run ls from based on what user has typed @@ -45,7 +45,7 @@ var customArgument = { else folderPath = whatHasUserTyped.slice(0, lastSlashIndex + 1); } - return baseLSCommand + folderPath; + return [...baseLsCommand, folderPath]; }, postProcess: (out) => { if (out.trim() === _prefix_string_for_file_and_folder_suggestions) { diff --git a/src/expo-cli.ts b/src/expo-cli.ts index 3b5402c68d03..32a0620ce611 100644 --- a/src/expo-cli.ts +++ b/src/expo-cli.ts @@ -5,9 +5,15 @@ const _gen: Record = { npm: { script(context) { - if (context[context.length - 1] === "") return ""; + if (context[context.length - 1] === "") return undefined; const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://api.npms.io/v2/search?q=${searchTerm}&size=20"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://api.npms.io/v2/search?q=${searchTerm}&size=20`, + ]; }, postProcess(script: string) { try { @@ -28,17 +34,17 @@ const _gen: Record = { }, }, "xcode-configuration": { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["bash", "-c", "xcodebuild -project ios/*.xcodeproj -list -json"], postProcess: (script: string) => JSON.parse(script).project.configurations.map((name) => ({ name })), }, "xcode-scheme": { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["bash", "-c", "xcodebuild -project ios/*.xcodeproj -list -json"], postProcess: (script: string) => JSON.parse(script).project.schemes.map((name) => ({ name })), }, "xcode-devices": { - script: "xcrun xctrace list devices", + script: ["xcrun", "xctrace", "list", "devices"], postProcess: (script: string) => script .split("\n") @@ -53,7 +59,7 @@ const _gen: Record = { })), }, "max-workers": { - script: "sysctl -n hw.ncpu", + script: ["sysctl", "-n", "hw.ncpu"], postProcess: (script: string) => { const count = Number(script); return Array.from({ length: count }, (_, i) => { diff --git a/src/expo.ts b/src/expo.ts index 270890b22979..06e87df4dd03 100644 --- a/src/expo.ts +++ b/src/expo.ts @@ -5,9 +5,15 @@ const _gen: Record = { npm: { script(context) { - if (context[context.length - 1] === "") return ""; + if (context[context.length - 1] === "") return undefined; const searchTerm = context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://api.npms.io/v2/search?q=${searchTerm}&size=20"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://api.npms.io/v2/search?q=${searchTerm}&size=20`, + ]; }, postProcess(script: string) { try { @@ -28,17 +34,17 @@ const _gen: Record = { }, }, "xcode-configuration": { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["xcodebuild", "-project", "ios/*.xcodeproj", "-list", "-json"], postProcess: (script: string) => JSON.parse(script).project.configurations.map((name) => ({ name })), }, "xcode-scheme": { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["xcodebuild", "-project", "ios/*.xcodeproj", "-list", "-json"], postProcess: (script: string) => JSON.parse(script).project.schemes.map((name) => ({ name })), }, "xcode-devices": { - script: "xcrun xctrace list devices", + script: ["xcrun", "xctrace", "list", "devices"], postProcess: (script: string) => script .split("\n") @@ -53,7 +59,7 @@ const _gen: Record = { })), }, "max-workers": { - script: "sysctl -n hw.ncpu", + script: ["sysctl", "-n", "hw.ncpu"], postProcess: (script: string) => { const count = Number(script); return Array.from({ length: count }, (_, i) => { diff --git a/src/expressots.ts b/src/expressots.ts index f4069e3b2f56..7c972f899051 100644 --- a/src/expressots.ts +++ b/src/expressots.ts @@ -17,7 +17,7 @@ const completionSpec: Fig.Spec = { name: "template", description: "Choose a template", generators: { - script: "expressots templates", + script: ["expressots", "templates"], postProcess: function (out) { return [ { @@ -40,7 +40,7 @@ const completionSpec: Fig.Spec = { name: "package-manager", description: "Choose a package manager", generators: { - script: "expressots package manager", + script: ["expressots", "package", "manager"], postProcess: function (out) { return [ { diff --git a/src/ffmpeg.ts b/src/ffmpeg.ts index a6df9c56817e..3992d115e9ce 100644 --- a/src/ffmpeg.ts +++ b/src/ffmpeg.ts @@ -122,7 +122,7 @@ const completionSpec: Fig.Spec = { args: { name: "device", generators: { - script: "ffmpeg -devices", + script: ["ffmpeg", "-devices"], postProcess: (out) => { return out .split("\n") @@ -143,7 +143,7 @@ const completionSpec: Fig.Spec = { args: { name: "device", generators: { - script: "ffmpeg -devices", + script: ["ffmpeg", "-devices"], postProcess: (out) => { return out .split("\n") @@ -387,7 +387,7 @@ const completionSpec: Fig.Spec = { args: { name: "device", generators: { - script: "ffmpeg -devices", + script: ["ffmpeg", "-devices"], postProcess: (out) => { return out .split("\n") @@ -413,7 +413,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") @@ -434,7 +434,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") @@ -715,7 +715,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") @@ -765,7 +765,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") @@ -924,7 +924,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") @@ -990,7 +990,7 @@ const completionSpec: Fig.Spec = { args: { name: "codec", generators: { - script: "ffmpeg -codecs", + script: ["ffmpeg", "-codecs"], postProcess: (out) => { return out .split("\n") diff --git a/src/fig-teams.ts b/src/fig-teams.ts deleted file mode 100644 index 77dab05bbb1f..000000000000 --- a/src/fig-teams.ts +++ /dev/null @@ -1,8 +0,0 @@ -import fig_teams from "./fig-teams@latest"; - -const completionSpec: Fig.Spec = { - ...fig_teams, - name: "fig-teams@latest", -}; - -export default completionSpec; diff --git a/src/fig-teams@latest.ts b/src/fig-teams@latest.ts deleted file mode 100644 index 5cd7bf02754c..000000000000 --- a/src/fig-teams@latest.ts +++ /dev/null @@ -1,119 +0,0 @@ -const getTeamsGenerator: Fig.Generator = { - script: "npx -y fig-teams@latest teams ls --json", - postProcess: (output) => { - try { - const teams = JSON.parse(output) as Array; - return teams.map((name) => ({ - name, - })); - } catch (e) { - return []; - } - }, -}; - -const getUsersGenerator: Fig.Generator = { - script: (context) => { - const teamOption = context.findIndex( - (ctx) => ctx === "-t" || ctx === "--team" - ); - // try getting the value of the team option - if (teamOption !== -1 && context[teamOption + 1] !== undefined) { - const teamName = context[teamOption + 1]; - return `npx -y fig-teams@latest users get -t ${teamName} --json`; - } - return ""; - }, - postProcess: (output) => { - try { - const teams = JSON.parse(output) as Array<{ - email: string; - role: string; - }>; - return teams.map(({ email }) => ({ - name: email, - icon: "fig://icon?type=invite", - })); - } catch (e) { - return []; - } - }, -}; - -const teamOption: Fig.Option = { - name: ["-t", "--team"], - description: "Team to use", - args: { - name: "teamname", - generators: getTeamsGenerator, - }, -}; - -const jsonOption: Fig.Option = { - name: "--json", - description: "Output as JSON", -}; - -const completionSpec: Fig.Spec = { - name: "fig-teams", - description: "Fig for teams", - subcommands: [ - { - name: "teams", - subcommands: [ - { - name: "ls", - description: "Get all available teams for the current user", - options: [jsonOption], - }, - { - name: "create", - description: "Create a new team", - args: { - name: "team_name", - }, - }, - { - name: "ls:user", - description: "Get all users for a given team", - options: [teamOption, jsonOption], - }, - { - name: "add:user", - description: "Add a new user to a team", - options: [teamOption], - args: { - name: "email", - generators: getUsersGenerator, - }, - }, - { - name: "remove:user", - description: "Remove a user from a team", - options: [teamOption], - args: { - name: "email", - generators: getUsersGenerator, - }, - }, - ], - }, - { - name: "deploy", - description: - "Push your locally compiled completion specs to Fig's server based on the mapping defined in the .fig/manifest file", - }, - { - name: "manifest", - description: - "Create or update the .fig/manifest file. Use this command to link your locally created completion specs to your team", - }, - { - name: "whoami", - description: - "Get information about the current user and their associated teams", - }, - ], -}; - -export default completionSpec; diff --git a/src/fig/index.ts b/src/fig/index.ts index c1162e841c81..9eca40bcea23 100644 --- a/src/fig/index.ts +++ b/src/fig/index.ts @@ -3,7 +3,11 @@ const versionFiles = ["1.0.0", "2.0.0"]; export const getVersionCommand: Fig.GetVersionCommand = async ( executeShellCommand ) => { - const out = await executeShellCommand("fig --version"); - return out.slice(out.indexOf(" ") + 1); + const { stdout } = await executeShellCommand({ + command: "fig", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--version"], + }); + return stdout.slice(stdout.indexOf(" ") + 1); }; export default createVersionedSpec("fig", versionFiles); diff --git a/src/fig/shared.ts b/src/fig/shared.ts index 8e3c1e812f27..6beca5c8baa8 100644 --- a/src/fig/shared.ts +++ b/src/fig/shared.ts @@ -18,35 +18,29 @@ const graphql = async ({ exec, query, }: { - exec: Fig.ExecuteShellCommandFunction; + exec: Fig.ExecuteCommandFunction; query: string; }) => { - const response = await exec( - `fig _ request --route '/graphql' --method POST --body '{ "query": "${query - .split(/\s+/) - .join(" ")}" }'` - ); - - return JSON.parse(response).data; -}; - -const devCompletionsFolderGenerator: Fig.Generator = { - script: '\\ls -d -1 "$PWD/"**/', - postProcess: (out) => - out.split("\n").map((folder) => { - const paths = folder.split("/"); - paths.pop(); + const { stdout } = await exec({ + command: "fig", + args: [ + "_", + "request", + "--route", + "/graphql", + "--method", + "--body", + JSON.stringify({ + query, + }), + ], + }); - return { - name: paths.pop(), - insertValue: folder, - icon: `fig://path/${folder}`, - }; - }), + return JSON.parse(stdout).data; }; const disableForCommandsGenerator: Fig.Generator = { - script: "fig settings autocomplete.disableForCommands", + script: ["fig", "settings", "autocomplete.disableForCommands"], postProcess: (out) => { const existing = out.split("\n").filter((item) => item.length > 0); @@ -78,7 +72,7 @@ const disableForCommandsGenerator: Fig.Generator = { }; export const themesGenerator: Fig.Generator = { - script: "fig theme --list", + script: ["fig", "theme", "--list"], postProcess: (output) => { const builtinThemes: Fig.Suggestion[] = [ { @@ -111,25 +105,29 @@ export const themesGenerator: Fig.Generator = { }; export const SETTINGS_GENERATOR: Record = { - "autocomplete.devCompletionsFolder": devCompletionsFolderGenerator, "autocomplete.disableForCommands": disableForCommandsGenerator, "autocomplete.theme": themesGenerator, }; export const subsystemsGenerator: Fig.Generator = { - script: "\\ls ~/.fig/logs", - trigger: (curr, prev) => { - // trigger on new token - return curr.length === 0 && prev.length > 0; - }, - postProcess: (out, tokens) => { - const insertedLogFiles = new Set(tokens.slice(0, -1)); - return out - .split("\n") - .map((name) => name.replace(".log", "")) - .concat("figterm") - .map((name) => ({ name, icon: "🪵" })) - .filter((suggestion) => !insertedLogFiles.has(suggestion.name)); + // script: "\\ls ~/.fig/logs", + // trigger: (curr, prev) => { + // // trigger on new token + // return curr.length === 0 && prev.length > 0; + // }, + // postProcess: (out, tokens) => { + // const insertedLogFiles = new Set(tokens.slice(0, -1)); + // return out + // .split("\n") + // .map((name) => name.replace(".log", "")) + // .concat("figterm") + // .map((name) => ({ name, icon: "🪵" })) + // .filter((suggestion) => !insertedLogFiles.has(suggestion.name)); + // }, + custom: async () => { + return ["figterm", "fig_cli", "fig_desktop", "daemon"].map((name) => ({ + name, + })); }, }; @@ -137,10 +135,11 @@ export const settingsSpecGenerator: Fig.Subcommand["generateSpec"] = async ( _, executeShellCommand ) => { - const text = await executeShellCommand( - "fig _ request --method GET --route '/settings/all'" - ); - const { settings, actions } = JSON.parse(text) as { + const { stdout } = await executeShellCommand({ + command: "fig", + args: ["_", "request", "--method", "GET", "--route", "/settings/all"], + }); + const { settings, actions } = JSON.parse(stdout) as { settings: Setting[]; actions: Action[]; }; @@ -195,7 +194,7 @@ export const settingsSpecGenerator: Fig.Subcommand["generateSpec"] = async ( }; export const stateGenerator: Fig.Generator = { - script: "fig internal local-state all --format json", + script: ["fig", "internal", "local-state", "all", "--format", "json"], postProcess: (out) => { const state = JSON.parse(out); return Object.keys(state).map((key) => ({ @@ -218,11 +217,14 @@ export const pluginsGenerator = (init: { strategy: "stale-while-revalidate", }, custom: async (_tokens, executeShellCommand) => { - const script = init.installed - ? "fig plugins list --format json --installed" - : "fig plugins list --format json"; - const out = await executeShellCommand(script); - const json = JSON.parse(out) as Plugin[]; + const args = init.installed + ? ["plugins", "list", "--format", "json", "--installed"] + : ["plugins", "list", "--format", "json"]; + const { stdout } = await executeShellCommand({ + command: "fig", + args, + }); + const json = JSON.parse(stdout) as Plugin[]; return json.map((plugin) => ({ name: plugin.name, icon: !plugin.icon?.startsWith("https://") ? plugin.icon : "📦", @@ -252,9 +254,20 @@ export const tokensGenerators: Fig.Generator = { teamName = tokens[teamOptionIndex + 1]; } const out = JSON.parse( - await executeShellCommand( - `fig user tokens list --team ${teamName} --format json` - ) + ( + await executeShellCommand({ + command: "fig", + args: [ + "user", + "tokens", + "list", + "--team", + teamName, + "--format", + "json", + ], + }) + ).stdout ) as { createdAt: string; description?: string; @@ -278,7 +291,7 @@ export const teamsGenerators: Fig.Generator = { cache: { strategy: "stale-while-revalidate", }, - script: "fig team --list --format json", + script: ["fig", "team", "--list", "--format", "json"], postProcess: (out) => { return ( JSON.parse(out) as { id: number; name: string; specs: string[] }[] @@ -295,7 +308,12 @@ export const membersGenerators: Fig.Generator = { custom: async (tokens, executeShellCommand) => { const teamName = tokens.at(-3); const out = JSON.parse( - await executeShellCommand(`fig team --format json ${teamName} members`) + ( + await executeShellCommand({ + command: "fig", + args: ["team", "--format", "json", teamName, "members"], + }) + ).stdout ) as { email: string; role: string }[]; return out.map((member) => { return { @@ -315,9 +333,12 @@ export const invitationsGenerators: Fig.Generator = { custom: async (tokens, executeShellCommand) => { const teamName = tokens.at(-3); const out = JSON.parse( - await executeShellCommand( - `fig team --format json ${teamName} invitations` - ) + ( + await executeShellCommand({ + command: "fig", + args: ["team", "--format", "json", teamName, "invitations"], + }) + ).stdout ) as { email: string; role: string }[]; return out.map((invitation) => { return { @@ -451,7 +472,7 @@ const scriptOptions = (script: ScriptFields) => { generators = param?.selector?.generators .filter((generator) => generator.type === "ShellScript") .map((generator) => ({ - script: generator?.shellScript?.script, + script: ["bash", "-c", generator?.shellScript?.script], splitOn: "\n", })); } @@ -732,7 +753,15 @@ export const commandLineToolSpecGenerator: Fig.Subcommand["generateSpec"] = }; export const sshHostsGenerator: Fig.Generator = { - script: "fig _ request --method GET --route /access/hosts/all", + script: [ + "fig", + "_", + "request", + "--method", + "GET", + "--route", + "/access/hosts/all", + ], cache: { strategy: "stale-while-revalidate", }, @@ -759,7 +788,12 @@ export const sshIdentityGenerator: Fig.Generator = { return []; } const hosts = JSON.parse( - await executeShellCommand(`fig ssh ${host} --get-identities`) + ( + await executeShellCommand({ + command: "fig", + args: ["ssh", host, "--get-identities"], + }) + ).stdout ) as { displayName: string; username: string }[]; return hosts.map((host) => ({ @@ -769,7 +803,7 @@ export const sshIdentityGenerator: Fig.Generator = { }; export const userGenerator: Fig.Generator = { - script: "fig user list-accounts", + script: ["fig", "user", "list-accounts"], postProcess: (out) => { if (out.startsWith("error: ")) { return []; diff --git a/src/fin.ts b/src/fin.ts index 86c411a06c74..c6f42bf8b65f 100644 --- a/src/fin.ts +++ b/src/fin.ts @@ -1,5 +1,5 @@ const databases: Fig.Generator = { - script: "fin db list", + script: ["fin", "db", "list"], postProcess: (output) => { return output.split("\n").map((db) => { return { name: db.trim(), description: "Database" }; @@ -8,7 +8,7 @@ const databases: Fig.Generator = { }; const hosts: Fig.Generator = { - script: "fin hosts", + script: ["fin", "hosts"], postProcess: (output) => { return output.split("\n").map((host) => { if (host.startsWith("#")) { @@ -20,7 +20,7 @@ const hosts: Fig.Generator = { }; const aliasGenerator: Fig.Generator = { - script: "fin alias list", + script: ["fin", "alias", "list"], postProcess: (output) => { return output .split("\n") @@ -32,7 +32,7 @@ const aliasGenerator: Fig.Generator = { }; const serviceGenerator: Fig.Generator = { - script: "\\command fin docker ps --format '{{.Names}}'", + script: ["fin", "docker", "ps", "--format", "{{.Names}}"], splitOn: "\n", }; @@ -373,8 +373,11 @@ const completionSpec: Fig.Spec = { name: "key-name", isOptional: true, generators: { - script: + script: [ + "bash", + "-c", "\\command ls $HOME/.ssh | \\command grep --color=never -v 'pub'", + ], splitOn: "\n", }, }, @@ -943,9 +946,10 @@ const completionSpec: Fig.Spec = { // Adding dynamic subcommands generateSpec: async (tokens, executeShellCommand) => { var new_subcommands = []; - const available_commands = await executeShellCommand( - "ls -1 ~/.docksal/commands/" - ); + const { stdout: available_commands } = await executeShellCommand({ + command: "bash", + args: ["-c", "ls -1 ~/.docksal/commands/"], + }); for (const command of available_commands.split("\n")) { if (command) { new_subcommands.push({ diff --git a/src/firebase.ts b/src/firebase.ts index e640e18743ea..2747db8f1bba 100644 --- a/src/firebase.ts +++ b/src/firebase.ts @@ -1,5 +1,5 @@ const projectAliasesGenerator: Fig.Generator = { - script: "firebase projects:list", // this calls to a firebase server and is therefore slow + script: ["firebase", "projects:list"], // this calls to a firebase server and is therefore slow postProcess: (out) => { const getAliasRegex = /^│ (\w.*?)│/gm; const aliasesRaw = Array.from(out.matchAll(getAliasRegex)); diff --git a/src/fisher.ts b/src/fisher.ts index 0370177e288e..dbd60c3c26b7 100644 --- a/src/fisher.ts +++ b/src/fisher.ts @@ -70,7 +70,7 @@ const pluginList = [ ]; const installedPlugins: Fig.Generator = { - script: "fish -c 'fisher list'", + script: ["fish", "-c", "fisher list"], postProcess: (output: string) => { if (!output) { return []; diff --git a/src/flutter.ts b/src/flutter.ts index 6a0504c1d4f5..a873363e28b4 100644 --- a/src/flutter.ts +++ b/src/flutter.ts @@ -4,7 +4,7 @@ import { filepaths } from "@fig/autocomplete-generators"; const flutterGenerators: Record = { emulators: { - script: "flutter emulators", + script: ["flutter", "emulators"], postProcess: function (out) { return out .match(/.*•.*/gi) @@ -863,7 +863,7 @@ const completionSpec = { description: "Switch to . Leave this blank to see available channels", generators: { - script: "flutter channel", + script: ["flutter", "channel"], postProcess: function (out) { return out .split("\n") diff --git a/src/flyctl.ts b/src/flyctl.ts index d0df53b2af40..40680fb75ccc 100644 --- a/src/flyctl.ts +++ b/src/flyctl.ts @@ -15,7 +15,7 @@ type FlyApp = { // Autocompletion generator for Fly apps using flyctl list apps // https://fly.io/docs/flyctl/apps-list/ const flyAppsGenerator: Fig.Generator = { - script: "flyctl apps list --json", + script: ["flyctl", "apps", "list", "--json"], postProcess: (output) => { const json: FlyApp[] = JSON.parse(output); @@ -38,7 +38,7 @@ const flyAppsGenerator: Fig.Generator = { // Autocompletion generator for Fly apps using flyctl list orgs // https://fly.io/docs/flyctl/orgs-list/ const flyOrgsGenerator: Fig.Generator = { - script: "fly orgs list --json", + script: ["fly", "orgs", "list", "--json"], postProcess: (output) => { const json: Record = JSON.parse(output); diff --git a/src/fnm.ts b/src/fnm.ts index ecd30a9d0f94..cbcf48a3a616 100644 --- a/src/fnm.ts +++ b/src/fnm.ts @@ -8,7 +8,7 @@ interface NodejsVersion { // Generators const versionGenerator: Fig.Generator = { - script: "fnm list", + script: ["fnm", "list"], postProcess: function (out) { return out .split("\n") @@ -49,7 +49,7 @@ const uniqBy = (arr: T[], callback: (a: T, b: T) => boolean) => * - Every other version, sorted; */ const remoteVersionGenerator: Fig.Generator = { - script: "fnm list-remote", + script: ["fnm", "list-remote"], postProcess: function (out) { const parsed = out .split("\n") diff --git a/src/fvm.ts b/src/fvm.ts index 4ef576bfb300..a8298415e3eb 100644 --- a/src/fvm.ts +++ b/src/fvm.ts @@ -103,7 +103,7 @@ const completionSpec: Fig.Spec = { }, ], generators: { - script: "fvm releases", + script: ["fvm", "releases"], postProcess: function (out): Fig.Suggestion[] { const matches = out.match(semverRegex); const matchesSet = [...new Set(matches)]; diff --git a/src/gem.ts b/src/gem.ts index e484366bdaef..83d84e5e1252 100644 --- a/src/gem.ts +++ b/src/gem.ts @@ -2,13 +2,19 @@ const gems: Fig.Generator = { trigger: () => true, custom: async (tokens, executeShellCommand) => { const searchTerm = tokens[tokens.length - 1]; - const out = await executeShellCommand( - `gem search --both --no-versions --no-details --quiet --norc '${searchTerm.replace( - "'", - `'"'"'` - )}'` - ); - return out + const { stdout } = await executeShellCommand({ + command: "gem", + args: [ + "search", + "--both", + "--no-versions", + "--no-details", + "--quiet", + "--norc", + searchTerm, + ], + }); + return stdout .trim() .split("\n") .filter((line) => line && !line.startsWith("*")) diff --git a/src/gh.ts b/src/gh.ts index 4a41a053701e..9dc0dd09b3b6 100644 --- a/src/gh.ts +++ b/src/gh.ts @@ -89,15 +89,24 @@ const ghGenerators: Record = { if (!userOrOrg) return []; //run `gh repo list` cmd - const res = await execute( - `gh repo list ${userOrOrg} --limit 9999 --json "nameWithOwner,description,isPrivate" ` - ); + const { stdout, status } = await execute({ + command: "gh", + args: [ + "repo", + "list", + userOrOrg, + "--limit", + "9999", + "--json", + "nameWithOwner,description,isPrivate", + ], + }); // make sure it has some existence. - if (!res) return []; + if (status !== 0) return []; //parse the JSON string output of the command - const repoArr: RepoDataType[] = JSON.parse(res); + const repoArr: RepoDataType[] = JSON.parse(stdout); return repoArr.map(listRepoMapFunction); }, @@ -109,8 +118,16 @@ const ghGenerators: Record = { * * --jq https://cli.github.com/manual/gh_help_formatting https://www.baeldung.com/linux/jq-command-json */ - script: - "gh api graphql --paginate -f query='query($endCursor: String) { viewer { repositories(first: 100, after: $endCursor) { nodes { isPrivate, nameWithOwner, description } pageInfo { hasNextPage endCursor }}}}' --jq '.data.viewer.repositories.nodes[]'", + script: [ + "gh", + "api", + "graphql", + "--paginate", + "-f", + "query='query($endCursor: String) { viewer { repositories(first: 100, after: $endCursor) { nodes { isPrivate, nameWithOwner, description } pageInfo { hasNextPage endCursor }}}}'", + "--jq", + ".data.viewer.repositories.nodes[]", + ], postProcess: (out) => { if (out) { /** @@ -139,7 +156,7 @@ const ghGenerators: Record = { }, listPR: { cache: { strategy: "stale-while-revalidate" }, - script: "gh pr list --json=number,title,headRefName,state", + script: ["gh", "pr", "list", "--json=number,title,headRefName,state"], postProcess: (out) => { interface PR { headRefName: string; @@ -160,7 +177,7 @@ const ghGenerators: Record = { }, }, listAlias: { - script: "gh alias list", + script: ["gh", "alias", "list"], postProcess: (out) => { const aliases = out.split("\n").map((line) => { const [name, content] = line.split(":"); @@ -176,8 +193,14 @@ const ghGenerators: Record = { }, }, remoteBranches: { - script: - "git --no-optional-locks branch -r --no-color --sort=-committerdate", + script: [ + "git", + "--no-optional-locks", + "branch", + "-r", + "--no-color", + "--sort=-committerdate", + ], postProcess: postProcessRemoteBranches, }, }; @@ -239,8 +262,11 @@ const completionSpec: Fig.Spec = { generators: ghGenerators.listAlias, parserDirectives: { alias: async (token, executeShellCommand) => { - const out = await executeShellCommand(`gh alias list`); - const alias = out + const { stdout } = await executeShellCommand({ + command: "gh", + args: ["alias", "list"], + }); + const alias = stdout .split("\n") .find((line) => line.startsWith(`${token}:\t`)); diff --git a/src/gibo.ts b/src/gibo.ts index d2301ad93fbb..eabd092b55f7 100644 --- a/src/gibo.ts +++ b/src/gibo.ts @@ -1,5 +1,5 @@ const boilerplates: Fig.Generator = { - script: "gibo list", + script: ["gibo", "list"], splitOn: "\n", }; diff --git a/src/git-cliff.ts b/src/git-cliff.ts index 01060bb363c9..c8d8557ed541 100644 --- a/src/git-cliff.ts +++ b/src/git-cliff.ts @@ -154,7 +154,7 @@ const completionSpec: Fig.Spec = { generators: { trigger: "..", getQueryTerm: ".", - script: "git rev-list --all --oneline --abbrev-commit", + script: ["git", "rev-list", "--all", "--oneline", "--abbrev-commit"], postProcess: (out, tokens) => { if (out.startsWith("fatal:")) { return []; diff --git a/src/git-flow.ts b/src/git-flow.ts index 76db78727e94..a7c51eb7ae26 100644 --- a/src/git-flow.ts +++ b/src/git-flow.ts @@ -23,22 +23,30 @@ const postProcessBranches: Fig.Generator["postProcess"] = (out, tokens) => { async function getGitFlowPrefix( type: string, - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ): Promise { - const prefix: string = await executeShellCommand( - `git config --get gitflow.prefix.${type}` - ); - return prefix; + const { stdout } = await executeShellCommand({ + command: "git", + args: ["config", "--get", `gitflow.prefix.${type}`], + }); + return stdout; } export const gitFlowGenerators: Record = { typeBranches: { custom: async (tokens, executeShellCommand) => { const prefix = await getGitFlowPrefix(tokens[1], executeShellCommand); - const out = await executeShellCommand( - "git --no-optional-locks branch -a --no-color --sort=-committerdate" - ); - return postProcessBranches(out, [prefix]); + const { stdout } = await executeShellCommand({ + command: "git", + args: [ + "--no-optional-locks", + "branch", + "-a", + "--no-color", + "--sort=-committerdate", + ], + }); + return postProcessBranches(stdout, [prefix]); }, }, }; diff --git a/src/git-profile.ts b/src/git-profile.ts index 7224a79ef361..e4c8d2f15eaa 100644 --- a/src/git-profile.ts +++ b/src/git-profile.ts @@ -1,6 +1,6 @@ // https://github.com/dotzero/git-profile const profiles: Fig.Generator = { - script: "git-profile list", + script: ["git-profile", "list"], postProcess: (output) => { return Array.from(output.matchAll(/^\[(.+?)\]$/gm)).map((result) => ({ name: result[1], diff --git a/src/git.ts b/src/git.ts index cd641afc77bc..44ce452a7af4 100644 --- a/src/git.ts +++ b/src/git.ts @@ -117,7 +117,7 @@ const postProcessBranches = export const gitGenerators: Record = { // Commit history commits: { - script: "git --no-optional-locks log --oneline", + script: ["git", "--no-optional-locks", "log", "--oneline"], postProcess: function (out) { const output = filterMessages(out); @@ -137,7 +137,7 @@ export const gitGenerators: Record = { // user aliases aliases: { - script: "git --no-optional-locks config --get-regexp '^alias.'", + script: ["git", "--no-optional-locks", "config", "--get-regexp", "^alias."], cache: { strategy: "stale-while-revalidate", }, @@ -163,7 +163,7 @@ export const gitGenerators: Record = { }, revs: { - script: "git rev-list --all --oneline", + script: ["git", "rev-list", "--all", "--oneline"], postProcess: function (out) { const output = filterMessages(out); @@ -184,7 +184,7 @@ export const gitGenerators: Record = { // Saved stashes // TODO: maybe only print names of stashes stashes: { - script: "git --no-optional-locks stash list", + script: ["git", "--no-optional-locks", "stash", "list"], postProcess: function (out) { const output = filterMessages(out); @@ -210,7 +210,7 @@ export const gitGenerators: Record = { // https://mirrors.edge.kernel.org/pub/software/scm/git/docs/#_identifier_terminology treeish: { - script: "git --no-optional-locks diff --cached --name-only", + script: ["git", "--no-optional-locks", "diff", "--cached", "--name-only"], postProcess: function (out, tokens) { const output = filterMessages(out); @@ -231,13 +231,25 @@ export const gitGenerators: Record = { // All branches remoteLocalBranches: { - script: - "git --no-optional-locks branch -a --no-color --sort=-committerdate", + script: [ + "git", + "--no-optional-locks", + "branch", + "-a", + "--no-color", + "--sort=-committerdate", + ], postProcess: postProcessBranches({ insertWithoutRemotes: true }), }, localBranches: { - script: "git --no-optional-locks branch --no-color --sort=-committerdate", + script: [ + "git", + "--no-optional-locks", + "branch", + "--no-color", + "--sort=-committerdate", + ], postProcess: postProcessBranches({ insertWithoutRemotes: true }), }, @@ -248,16 +260,32 @@ export const gitGenerators: Record = { const pp = postProcessBranches({ insertWithoutRemotes: true }); if (tokens.includes("-r")) { return pp( - await executeShellCommand( - "git --no-optional-locks branch -r --no-color --sort=-committerdate" - ), + ( + await executeShellCommand({ + command: "git", + args: [ + "--no-optional-locks", + "-r", + "--no-color", + "--sort=-committerdate", + ], + }) + ).stdout, tokens ); } else { return pp( - await executeShellCommand( - "git --no-optional-locks branch --no-color --sort=-committerdate" - ), + ( + await executeShellCommand({ + command: "git", + args: [ + "--no-optional-locks", + "branch", + "--no-color", + "--sort=-committerdate", + ], + }) + ).stdout, tokens ); } @@ -265,7 +293,7 @@ export const gitGenerators: Record = { }, remotes: { - script: "git --no-optional-locks remote -v", + script: ["git", "--no-optional-locks", "remote", "-v"], postProcess: function (out) { const remoteURLs = out.split("\n").reduce((dict, line) => { const pair = line.split("\t"); @@ -300,7 +328,13 @@ export const gitGenerators: Record = { }, tags: { - script: "git --no-optional-locks tag --list --sort=-committerdate", + script: [ + "git", + "--no-optional-locks", + "tag", + "--list", + "--sort=-committerdate", + ], postProcess: function (output) { return output.split("\n").map((tag) => ({ name: tag, @@ -311,7 +345,7 @@ export const gitGenerators: Record = { // Files for staging files_for_staging: { - script: "git --no-optional-locks status --short", + script: ["git", "--no-optional-locks", "status", "--short"], postProcess: (out, context) => { // This whole function is a mess @@ -410,22 +444,33 @@ export const gitGenerators: Record = { }, getStagedFiles: { - script: + script: [ + "bash", + "-c", "git --no-optional-locks status --short | sed -ne '/^M /p' -e '/A /p'", + ], postProcess: postProcessTrackedFiles, }, getUnstagedFiles: { - script: "git --no-optional-locks diff --name-only", + script: ["git", "--no-optional-locks", "diff", "--name-only"], splitOn: "\n", }, getChangedTrackedFiles: { script: function (context) { if (context.includes("--staged") || context.includes("--cached")) { - return `git --no-optional-locks status --short | sed -ne '/^M /p' -e '/A /p'`; + return [ + "bash", + "-c", + `git --no-optional-locks status --short | sed -ne '/^M /p' -e '/A /p'`, + ]; } else { - return `git --no-optional-locks status --short | sed -ne '/M /p' -e '/A /p'`; + return [ + "bash", + "-c", + `git --no-optional-locks status --short | sed -ne '/M /p' -e '/A /p'`, + ]; } }, postProcess: postProcessTrackedFiles, @@ -3980,8 +4025,11 @@ const completionSpec: Fig.Spec = { name: "git", description: "The stupid content tracker", generateSpec: async (_, executeShellCommand) => { - const out = await executeShellCommand("git help -a"); - const lines = out.trim().split("\n"); + const { stdout } = await executeShellCommand({ + command: "git", + args: ["help", "-a"], + }); + const lines = stdout.trim().split("\n"); const start = lines.findIndex((val) => val.match(/external commands/i)); const commands: string[] = []; for (let i = start + 1; i < lines.length; i += 1) { @@ -4005,11 +4053,14 @@ const completionSpec: Fig.Spec = { description: "Custom user defined git alias", parserDirectives: { alias: async (token, exec) => { - const result = await exec(`git config --get alias.${token}`); - if (!result) { + const { stdout, status } = await exec({ + command: "git", + args: ["config", "--get", `alias.${token}`], + }); + if (status !== 0) { throw new Error("Failed parsing alias"); } - return result; + return stdout; }, }, isOptional: true, @@ -4349,19 +4400,30 @@ const completionSpec: Fig.Spec = { name: "message", generators: ai({ name: "git commit -m", - prompt: ({ executeShellCommand }) => { - const gitLogShortMessages = executeShellCommand( - "git log --pretty=format:%s --abbrev-commit --max-count=20" - ); + prompt: async ({ executeCommand }) => { + const { stdout } = await executeCommand({ + command: "git", + args: [ + "log", + "--pretty=format:%s", + "--abbrev-commit", + "--max-count=20", + ], + }); return ( 'Generate a git commit message summary based on this git diff, the "summary" must be no more ' + "than 70-75 characters, and it must describe both what the patch changes, as well as why the " + - `patch might be necessary.\n\nHere are some examples from the repo:\n${gitLogShortMessages}` + `patch might be necessary.\n\nHere are some examples from the repo:\n${stdout}` ); }, - message: ({ executeShellCommand }) => - executeShellCommand("git diff --staged"), + message: async ({ executeCommand }) => + ( + await executeCommand({ + command: "git", + args: ["diff", "--staged"], + }) + ).stdout, splitOn: "\n", }), }, @@ -4856,7 +4918,7 @@ const completionSpec: Fig.Spec = { icon: "⚙️", })), generators: { - script: "git config --get-regexp '.*'", + script: ["git", "config", "--get-regexp", ".*"], // This is inefficient but it doesn't need to be faster - most // of the time, you don't need to run `git config` commands, // and when you do it's typically one or two at most. diff --git a/src/go.ts b/src/go.ts index 30ad0ce7053a..3d48fb6a67a1 100644 --- a/src/go.ts +++ b/src/go.ts @@ -871,7 +871,7 @@ const completionSpec: Fig.Spec = { args: { name: "tool", generators: { - script: "go tool", + script: ["go", "tool"], splitOn: "\n", }, }, diff --git a/src/goto.ts b/src/goto.ts index 10e0e2b19b24..81d30584a527 100644 --- a/src/goto.ts +++ b/src/goto.ts @@ -1,10 +1,14 @@ const listTargets: Fig.Generator = { - custom: async (tokens, executeShellCommand) => { - const targets = await executeShellCommand("command cat ~/.config/goto"); + custom: async (tokens, executeShellCommand, context) => { + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${context.environmentVariables["HOME"]}/.config/goto`], + }); const targetSuggestions = new Map(); - for (const target of targets.split("\n")) { + for (const target of stdout.split("\n")) { const splits = target.split(" "); targetSuggestions.set(target, { name: splits[0], diff --git a/src/gource.ts b/src/gource.ts index 853cac492d41..fd7c765fe88b 100644 --- a/src/gource.ts +++ b/src/gource.ts @@ -79,7 +79,7 @@ export interface SpdisplaysDisplayportDevice { const screenNumbers: Fig.Generator = { // one thing to note is that this is MacOS specific - script: "system_profiler SPDisplaysDataType -json", + script: ["system_profiler", "SPDisplaysDataType", "-json"], postProcess: (output) => { if (output.includes("command not found")) { return []; diff --git a/src/gpg.ts b/src/gpg.ts index e702226fa2b1..1bee4eb9027b 100644 --- a/src/gpg.ts +++ b/src/gpg.ts @@ -1,5 +1,5 @@ const getCipherAlgorithms: Fig.Generator = { - script: "gpg --version", + script: ["gpg", "--version"], postProcess: (out, context) => { // Get the substring 2of cyphers, remove whitespace and split by commas let cyphers = out.substring( @@ -15,7 +15,7 @@ const getCipherAlgorithms: Fig.Generator = { }; const getDigestAlgorithms: Fig.Generator = { - script: "gpg --version", + script: ["gpg", "--version"], postProcess: (out, context) => { // Get the substring of digests, remove whitespace and split by commas let digests = out.substring( diff --git a/src/heroku.ts b/src/heroku.ts index b1c85a5d46d5..eb2404c4876a 100644 --- a/src/heroku.ts +++ b/src/heroku.ts @@ -1,5 +1,5 @@ const getAppGenerator: Fig.Generator = { - script: "heroku apps --all --json", + script: ["heroku", "apps", "--all", "--json"], cache: { strategy: "stale-while-revalidate", }, diff --git a/src/hexo.ts b/src/hexo.ts index 47d56cf0dd66..b3e2d4b6a903 100644 --- a/src/hexo.ts +++ b/src/hexo.ts @@ -1,5 +1,5 @@ const draftGenerator: Fig.Generator = { - script: "hexo list post | grep -E ^Draft", + script: ["bash", "-c", "hexo list post | grep -E ^Draft"], postProcess: (out) => { return out.split("\n").map(function (file) { const title = file diff --git a/src/hugo.ts b/src/hugo.ts index e921139b59fe..f1488beb9b27 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -874,7 +874,7 @@ const completionSpec: Fig.Spec = { { name: "archetype|default", generators: { - script: "ls ./archetypes/", + script: ["ls", "./archetypes/"], postProcess: (output) => output.split("\n").map((fileName) => ({ name: fileName.slice(0, fileName.lastIndexOf(".")), diff --git a/src/hyper.ts b/src/hyper.ts index 5c014c8dfa45..e28b4f1214bb 100644 --- a/src/hyper.ts +++ b/src/hyper.ts @@ -47,7 +47,7 @@ const completionSpec: Fig.Spec = { name: "plugin", description: "Plugin to uninstall", generators: { - script: "hyper list", + script: ["hyper", "list"], postProcess: function (out) { return out.split("\n").map((p) => { return { name: p, description: "Plugin name" }; diff --git a/src/ibus.ts b/src/ibus.ts index 1509af559823..0ad64e1dc95c 100644 --- a/src/ibus.ts +++ b/src/ibus.ts @@ -7,7 +7,7 @@ const completionSpec: Fig.Spec = { args: { isOptional: true, generators: { - script: "ibus list-engine", + script: ["ibus", "list-engine"], postProcess: (out) => out .split("\n") diff --git a/src/iconv.ts b/src/iconv.ts index 69e571eef1bf..abcd0b314cc2 100644 --- a/src/iconv.ts +++ b/src/iconv.ts @@ -1,5 +1,5 @@ const encodingGenerator: Fig.Generator = { - script: "iconv -l | command tr ' ' '\\n' | sort", + script: ["bash", "-c", "iconv -l | command tr ' ' '\\n' | sort"], postProcess: (out) => out.split("\n").map((encoding) => ({ name: encoding, diff --git a/src/id.ts b/src/id.ts index 7540a484071f..48e98373e8ea 100644 --- a/src/id.ts +++ b/src/id.ts @@ -59,7 +59,7 @@ const completionSpec: Fig.Spec = { name: "user", isOptional: true, generators: { - script: "dscl . -list /Users | grep -v '^_'", + script: ["bash", "-c", "dscl . -list /Users | grep -v '^_'"], postProcess: (out) => out .trim() diff --git a/src/ignite-cli.ts b/src/ignite-cli.ts index 5143ea118306..fe42d866a5dc 100644 --- a/src/ignite-cli.ts +++ b/src/ignite-cli.ts @@ -1,5 +1,5 @@ const generatorsGenerator: Fig.Generator = { - script: "ls ignite/templates", + script: ["ls", "ignite/templates"], postProcess: (out) => { if (out.trim() === "") return []; return out.split("\n").map((gen) => ({ diff --git a/src/infracost/index.ts b/src/infracost/index.ts index 709cd06be1bb..3a2c28572500 100644 --- a/src/infracost/index.ts +++ b/src/infracost/index.ts @@ -5,8 +5,12 @@ const versionFiles = ["0.9.0"]; export const getVersionCommand: Fig.GetVersionCommand = async ( executeShellCommand ) => { - const out = await executeShellCommand("infracost --version"); - return clean(out.slice(out.indexOf(" ") + 1)); + const { stdout } = await executeShellCommand({ + command: "infracost", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--version"], + }); + return clean(stdout.slice(stdout.indexOf(" ") + 1)); }; export default createVersionedSpec("infracost", versionFiles); diff --git a/src/ipatool.ts b/src/ipatool.ts index 70fb70187397..c398edc0a838 100644 --- a/src/ipatool.ts +++ b/src/ipatool.ts @@ -16,9 +16,17 @@ type App = { const bundleIdentifierGenerator: Fig.Generator = { script: (context) => { const identifier = context[context.length - 1]; - if (!identifier) return ""; + if (!identifier) return undefined; - return `ipatool search ${identifier} --limit 10 --format json`; + return [ + "ipatool", + "search", + identifier, + "--limit", + "10", + "--format", + "json", + ]; }, postProcess: (output) => { if (!output) return []; diff --git a/src/j.ts b/src/j.ts index 16b6fd668452..e2726ca08381 100644 --- a/src/j.ts +++ b/src/j.ts @@ -8,9 +8,15 @@ const completionSpec: Fig.Spec = { description: "Directory to jump to", isVariadic: true, generators: { - script: 'cat "$HOME"/Library/autojump/autojump.txt', - postProcess: (out, ctx) => { - const lines = out.split("\n").map((line) => { + custom: async (tokens, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [ + `${context.environmentVariables["HOME"]}/Library/autojump/autojump.txt`, + ], + }); + const lines = stdout.split("\n").map((line) => { const [weight, dir] = line.split("\t"); return { @@ -19,7 +25,7 @@ const completionSpec: Fig.Spec = { }; }); - const args = ctx.slice(1, ctx.length - 1); + const args = tokens.slice(1, tokens.length - 1); // directory arg is variadic with each subsequent arg being an // additional filter. filtered will filter directories by all args. diff --git a/src/jenv.ts b/src/jenv.ts index 9d6bb4e7c2ea..4c24a1ac5ae7 100644 --- a/src/jenv.ts +++ b/src/jenv.ts @@ -1,5 +1,9 @@ const programGenerator: Fig.Generator = { - script: `for i in $(echo $PATH | tr ":" "\\n"); do [[ -d "$i" ]] && find "$i" -maxdepth 1 -type f -perm -111 && find "$i" -maxdepth 1 -type l -perm -111; done`, + script: [ + "bash", + "-c", + `for i in $(echo $PATH | tr ":" "\\n"); do [[ -d "$i" ]] && find "$i" -maxdepth 1 -type f -perm -111 && find "$i" -maxdepth 1 -type l -perm -111; done`, + ], postProcess: (out) => out .split("\n") @@ -12,7 +16,7 @@ const programGenerator: Fig.Generator = { })), }; const generateAllShims: Fig.Generator = { - script: "jenv shims --short", + script: ["jenv", "shims", "--short"], postProcess: function (out) { return out .split("\n") @@ -25,7 +29,7 @@ const generateAllShims: Fig.Generator = { }, }; const generateAllCommands: Fig.Generator = { - script: "jenv commands", + script: ["jenv", "commands"], postProcess: function (out) { return out .split("\n") @@ -40,7 +44,7 @@ const generateAllCommands: Fig.Generator = { }, }; const generateAllPlugins: Fig.Generator = { - script: "jenv plugins", + script: ["jenv", "plugins"], postProcess: function (out) { return out .split("\n") @@ -54,7 +58,7 @@ const generateAllPlugins: Fig.Generator = { }, }; const generateJEnvVersions: Fig.Generator = { - script: "jenv versions --bare", + script: ["jenv", "versions", "--bare"], postProcess: function (out) { return out .split("\n") diff --git a/src/just.ts b/src/just.ts index ae72d8d104c9..172e3dd817dd 100644 --- a/src/just.ts +++ b/src/just.ts @@ -85,10 +85,18 @@ function getJustfilePath(tokens: string[]): string | null { * Get the command to dump the justfile at the given path, or let `just` handle * searching for the file if the path is null. */ -function getJustfileDumpCommand(justfilePath: string | null): string { +function getJustfileDumpCommand(justfilePath: string | null): string[] { return justfilePath - ? `just --unstable --dump --dump-format json --justfile '${justfilePath}'` - : `just --unstable --dump --dump-format json`; + ? [ + "just", + "--unstable", + "--dump", + "--dump-format", + "json", + "--justfile", + justfilePath, + ] + : ["just", "--unstable", "--dump", "--dump-format", "json"]; } /** diff --git a/src/k3d.ts b/src/k3d.ts index 2a649c26c031..9cf64c293762 100644 --- a/src/k3d.ts +++ b/src/k3d.ts @@ -1,5 +1,5 @@ const ClusterGenerator: Fig.Generator = { - script: "k3d cluster list --no-headers", + script: ["k3d", "cluster", "list", "--no-headers"], postProcess: (out) => { return out.split("\n").map((line) => { const [name, servers, agents] = line.split(/\s+/); @@ -34,7 +34,7 @@ const ShellCompletions: Fig.Suggestion[] = [ // Docker Image Generator const DockerImageGenerator: Fig.Generator = { - script: "docker image ls --format '{{.Repository}}:{{.Tag}}'", + script: ["docker", "image", "ls", "--format", "{{.Repository}}:{{.Tag}}"], postProcess: (out) => { return out.split("\n").map((image) => ({ name: image, @@ -46,7 +46,7 @@ const DockerImageGenerator: Fig.Generator = { // Node Generator const NodeGenerator: Fig.Generator = { - script: "k3d node list --no-headers", + script: ["k3d", "node", "list", "--no-headers"], postProcess: (out) => { return out.split("\n").map((line) => { const [name, role, cluster] = line.split(/\s+/); @@ -61,7 +61,7 @@ const NodeGenerator: Fig.Generator = { // Registry Generator const RegistryGenerator: Fig.Generator = { - script: "k3d registry list --no-headers", + script: ["k3d", "registry", "list", "--no-headers"], postProcess: (out) => { return out.split("\n").map((line) => { const [name, cluster] = line.split(/\s+/); diff --git a/src/k9s.ts b/src/k9s.ts index e32d21f07c6c..f13c859e3744 100644 --- a/src/k9s.ts +++ b/src/k9s.ts @@ -1,5 +1,5 @@ const namespaces: Fig.Generator = { - script: "kubectl get namespaces", + script: ["kubectl", "get", "namespaces"], postProcess: (out) => { return out .split("\n") diff --git a/src/kill.ts b/src/kill.ts index 17a4db2b65ea..ded07672e2e7 100644 --- a/src/kill.ts +++ b/src/kill.ts @@ -15,7 +15,7 @@ const completionSpec: Fig.Spec = { name: "pid", isVariadic: true, generators: { - script: "ps axo pid,comm | sed 1d", + script: ["bash", "-c", "ps axo pid,comm | sed 1d"], postProcess: (result: string) => { return result.split("\n").map((line) => { const [pid, path] = line.trim().split(/\s+/); @@ -38,7 +38,7 @@ const completionSpec: Fig.Spec = { name: "signal_name", generators: { // Bash's `kill` builtin has different output to /bin/kill - script: "env kill -l", + script: ["env", "kill", "-l"], postProcess: (out) => out.match(/\w+/g).map((name) => ({ name, diff --git a/src/killall.ts b/src/killall.ts index 8375cf075969..c22e55dd6a4f 100644 --- a/src/killall.ts +++ b/src/killall.ts @@ -43,7 +43,7 @@ const completionSpec: Fig.Spec = { isVariadic: true, generators: { // All processes, only display the path - script: "ps -A -o comm | sort -u", + script: ["bash", "-c", "ps -A -o comm | sort -u"], postProcess: (out) => out .trim() @@ -113,7 +113,7 @@ const completionSpec: Fig.Spec = { args: { name: "user", generators: { - script: "dscl . -list /Users | grep -v '^_'", + script: ["bash", "-c", "dscl . -list /Users | grep -v '^_'"], postProcess: (out) => out .trim() diff --git a/src/kind.ts b/src/kind.ts index 6f4794ceea15..848571cd9a57 100644 --- a/src/kind.ts +++ b/src/kind.ts @@ -1,5 +1,5 @@ const ClusterGenerator: Fig.Generator = { - script: "kind get clusters", + script: ["kind", "get", "clusters"], postProcess: (out) => { return out.split("\n").map((cluster) => ({ name: cluster, @@ -9,7 +9,7 @@ const ClusterGenerator: Fig.Generator = { }; const NodeGenerator: Fig.Generator = { - script: "kind get nodes -A", + script: ["kind", "get", "nodes", "-A"], postProcess: (out) => { return out.split("\n").map((node) => ({ name: node, diff --git a/src/kool.ts b/src/kool.ts index 0392bd8871b9..85c68e7424c3 100644 --- a/src/kool.ts +++ b/src/kool.ts @@ -1,5 +1,5 @@ const getScripts: Fig.Generator = { - script: "kool run --help", + script: ["kool", "run", "--help"], postProcess: (output) => { const lines = output.split("\n"); const scriptsIndex = lines.findIndex( @@ -14,7 +14,7 @@ const getScripts: Fig.Generator = { }; const getServices: Fig.Generator = { - script: "docker-compose config --services", + script: ["docker-compose", "config", "--services"], splitOn: "\n", }; diff --git a/src/kubectl.ts b/src/kubectl.ts index dbd092a511b1..06dc2740e879 100644 --- a/src/kubectl.ts +++ b/src/kubectl.ts @@ -1,8 +1,8 @@ // Internal scripts for this spec, not to be confused with the script property const scripts = { - types: "kubectl api-resources -o name", + types: ["kubectl", "api-resources", "-o", "name"], typeWithoutName: function (type) { - return `kubectl get ${type} -o custom-columns=:.metadata.name`; + return ["kubectl", "get", type, "-o", "custom-columns=:.metadata.name"]; }, }; @@ -43,7 +43,14 @@ const sharedArgs: Record = { runningPodsArg: { name: "Running Pods", generators: { - script: "kubectl get pods --field-selector=status.phase=Running -o name", + script: [ + "kubectl", + "get", + "pods", + "--field-selector=status.phase=Running", + "-o", + "name", + ], postProcess: sharedPostProcess, }, }, @@ -68,11 +75,16 @@ const sharedArgs: Record = { script: function (context) { const index = context.indexOf("--kubeconfig"); if (index !== -1) { - return `kubectl config --kubeconfig=${ - context[index + 1] - } get-contexts -o name`; + return [ + "kubectl", + "config", + `--kubeconfig=${context[index + 1]}`, + "get-contexts", + "-o", + "name", + ]; } - return "kubectl config get-contexts -o name"; + return ["kubectl", "config", "get-contexts", "-o", "name"]; }, postProcess: sharedPostProcess, }, @@ -94,11 +106,14 @@ const sharedArgs: Record = { script: function (context) { const index = context.indexOf("--kubeconfig"); if (index !== -1) { - return `kubectl config --kubeconfig=${ - context[index + 1] - } get-clusters`; + return [ + "kubectl", + "config", + `--kubeconfig=${context[index + 1]}`, + "get-clusters", + ]; } - return "kubectl config get-clusters"; + return ["kubectl", "config", "get-clusters"]; }, postProcess: function (out) { if ( @@ -174,7 +189,7 @@ const sharedArgs: Record = { const podName = context[podIndex].includes("/") ? context[podIndex] : `${context[podIndex]} + ${context[podIndex + 1]}`; - return `kubectl get ${podName} -o json`; + return ["kubectl", "get", podName, "-o", "json"]; }, postProcess: function (out) { if ( diff --git a/src/kubectx.ts b/src/kubectx.ts index 02343994410e..c1f26d819e68 100644 --- a/src/kubectx.ts +++ b/src/kubectx.ts @@ -33,7 +33,7 @@ const completionSpec: Fig.Spec = { name: "context", isVariadic: true, generators: { - script: `kubectx`, + script: ["kubectx"], postProcess: (out) => { const contexts = out.split("\n").map((item) => ({ name: item, @@ -59,7 +59,7 @@ const completionSpec: Fig.Spec = { name: "context", generators: [ { - script: `kubectx | grep -v $(kubectx -c)`, + script: ["bash", "-c", "kubectx | grep -v $(kubectx -c)"], postProcess: (out) => out.split("\n").map((item) => ({ name: item, @@ -68,7 +68,7 @@ const completionSpec: Fig.Spec = { })) as Fig.Suggestion[], }, { - script: `kubectx -c`, + script: ["kubectx", "-c"], postProcess: (out) => { return !out ? [] diff --git a/src/kubens.ts b/src/kubens.ts index 72518d979a29..f3112c2465db 100644 --- a/src/kubens.ts +++ b/src/kubens.ts @@ -26,7 +26,7 @@ const completionSpec: Fig.Spec = { name: "namespace", generators: [ { - script: "kubens | grep -v $(kubens -c)", + script: ["bash", "-c", "kubens | grep -v $(kubens -c)"], postProcess: (out) => out.split("\n").map((item) => ({ name: item, @@ -35,7 +35,7 @@ const completionSpec: Fig.Spec = { })) as Fig.Suggestion[], }, { - script: "kubens -c", + script: ["kubens", "-c"], postProcess: (out) => { return !out ? [] diff --git a/src/launchctl.ts b/src/launchctl.ts index fedbb680370f..957910e8354e 100644 --- a/src/launchctl.ts +++ b/src/launchctl.ts @@ -54,7 +54,7 @@ const limitArgs = [ ]; const listGenerator: Fig.Generator = { - script: "launchctl list", + script: ["launchctl", "list"], // The list command outputs 3 columns: PID Status Label // we want the last column ([2]) postProcess: function (out) { diff --git a/src/lerna.ts b/src/lerna.ts index d47b354de055..b3ffc82f6065 100644 --- a/src/lerna.ts +++ b/src/lerna.ts @@ -1,7 +1,5 @@ -const SPLIT_CHAR = "END"; - const getPackages: Fig.Generator = { - script: "lerna ls", + script: ["lerna", "ls"], postProcess: (output) => output.split("\n").map((packageName) => ({ name: packageName, @@ -10,7 +8,7 @@ const getPackages: Fig.Generator = { }; const getBranches: Fig.Generator = { - script: "git branch --no-color", + script: ["git", "branch", "--no-color"], postProcess: function (out) { if (out.startsWith("fatal:")) { return []; @@ -27,10 +25,14 @@ const getBranches: Fig.Generator = { const getAllScriptsFromPackages: Fig.Generator = { // Get all lerna packages, loop over them and get content of package.json - script: `lerna list -p | while read p; do\n \\cat $p/package.json && echo ${SPLIT_CHAR}\ndone`, + script: [ + "bash", + "-c", + "lerna list -p | while read p; do\n \\cat $p/package.json && echo END\ndone", + ], postProcess: (output) => { // Split output by the divider and remove empty entry - const packages = output.split(SPLIT_CHAR).filter((e) => e.trim() !== ""); + const packages = output.split("END").filter((e) => e.trim() !== ""); let scripts: string[] = []; packages.forEach((packageContent) => { @@ -536,7 +538,7 @@ const completionSpec: Fig.Spec = { args: { name: "remote", generators: { - script: "git remote", + script: ["git", "remote"], postProcess: (output) => { return output.split("\n").map((remoteName) => ({ name: remoteName, diff --git a/src/limactl.ts b/src/limactl.ts index 2a21b9bff54b..d771a1735878 100644 --- a/src/limactl.ts +++ b/src/limactl.ts @@ -16,7 +16,7 @@ const generateGlobalFlags = (subcommandName: string): Fig.Option[] => [ const instanceNameGenerator = ( suggestOptions?: Partial ): Fig.Generator => ({ - script: "limactl list --quiet", + script: ["limactl", "list", "--quiet"], postProcess: (output) => output.split("\n").map((instanceName) => ({ name: `${instanceName}`, diff --git a/src/login.ts b/src/login.ts index f5d24068b03d..8eaabc4991f0 100644 --- a/src/login.ts +++ b/src/login.ts @@ -25,7 +25,7 @@ const completionSpec: Fig.Spec = { args: { name: "username", generators: { - script: "cat /etc/passwd", + script: ["cat", "/etc/passwd"], postProcess: (out) => { return out.split("\n").map((line) => { const [username] = line.split(":"); diff --git a/src/lsof.ts b/src/lsof.ts index f25dcf338c22..d77498909763 100644 --- a/src/lsof.ts +++ b/src/lsof.ts @@ -244,7 +244,7 @@ const completionSpec: Fig.Spec = { name: "options", generators: [ { - script: "echo", + script: ["echo"], postProcess: function () { const startParams = ["4", "6"]; return startParams.map((param) => ({ @@ -253,7 +253,7 @@ const completionSpec: Fig.Spec = { }, }, { - script: "echo", + script: ["echo"], postProcess: function (out, tokens) { const startParams = ["tcp", "udp", "TCP", "UDP"]; const token = @@ -267,7 +267,7 @@ const completionSpec: Fig.Spec = { }, }, { - script: "ifconfig", + script: ["ifconfig"], postProcess: function (out, tokens) { const ips = out .split("\n") @@ -291,7 +291,7 @@ const completionSpec: Fig.Spec = { trigger: "@", }, { - script: "echo", + script: ["echo"], postProcess: function (out, tokens) { const colonParams = ["http", "https", "who", "time"]; let token = ":"; diff --git a/src/m.ts b/src/m.ts index dc6f328a0498..1c18b68d02f1 100644 --- a/src/m.ts +++ b/src/m.ts @@ -1,10 +1,10 @@ const generateDisks: Fig.Generator = { - // ? is a bash/fish/zsh glob pattern for "any character, exactly once" - script: "command ls /dev/disk?", + script: ["ls", "/dev"], postProcess: (out) => out .trim() .split("\n") + .filter((disk) => disk.match(/\/dev\/disk\w/)) .map((disk) => ({ name: disk, icon: "💽", @@ -13,21 +13,21 @@ const generateDisks: Fig.Generator = { }; const generateVolumes: Fig.Generator = { - script: "command ls -d /Volumes/*", + script: ["ls", "/Volumes"], postProcess: (out) => out .trim() .split("\n") .filter((volume) => volume !== "Macintosh HD") .map((volume) => ({ - name: volume, + name: `/Volumes/${volume}`, type: "file", priority: 100, })), }; const generateUsers: Fig.Generator = { - script: "m user list | awk '{ print $1 }'", + script: ["bash", "-c", "m user list | awk '{ print $1 }'"], postProcess: (out) => out .trim() @@ -40,7 +40,7 @@ const generateUsers: Fig.Generator = { }; const generateGroups: Fig.Generator = { - script: "m group list | awk '{ print $1 }'", + script: ["bash", "-c", "m group list | awk '{ print $1 }'"], postProcess: (out) => out .trim() @@ -53,12 +53,12 @@ const generateGroups: Fig.Generator = { }; const generateNetworkLocations: Fig.Generator = { - script: "m network location list | tail -n +2", + script: ["bash", "-c", "m network location list | tail -n +2"], splitOn: "\n", }; const generateServices: Fig.Generator = { - script: "launchctl list | awk '{ print $3 }'", + script: ["bash", "-c", "launchctl list | awk '{ print $3 }'"], splitOn: "\n", }; @@ -70,7 +70,7 @@ function getPidIcon(path: string): string { return "fig://" + path.slice(0, idx + 4); } const generatePids: Fig.Generator = { - script: "ps axo pid,comm | sed 1d", + script: ["bash", "-c", "ps axo pid,comm | sed 1d"], postProcess: (result) => { return result.split("\n").map((line) => { const [pid, path] = line.trim().split(/\s+/); @@ -86,8 +86,11 @@ const generatePids: Fig.Generator = { }; const generateWifiNetworks: Fig.Generator = { - script: + script: [ + "bash", + "-c", "networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $2}' | xargs networksetup -listpreferredwirelessnetworks | tail -n +2", + ], postProcess: (out) => out .trim() diff --git a/src/mackup.ts b/src/mackup.ts index c09bc97bfb12..90e19fb4659e 100644 --- a/src/mackup.ts +++ b/src/mackup.ts @@ -1,5 +1,5 @@ const applicationGenerator: Fig.Generator = { - script: "mackup list", + script: ["mackup", "list"], postProcess: (output) => { return output .split("\n") diff --git a/src/magento.ts b/src/magento.ts index 40a4d5cd2256..ae4f35c30898 100644 --- a/src/magento.ts +++ b/src/magento.ts @@ -49,9 +49,11 @@ const completionSpec: Fig.Spec = { name: "magento", description: "Open-source E-commerce", generateSpec: async (tokens, executeShellCommand) => { - const command = "bin/magento list --format=json --raw"; - const out = await executeShellCommand(command); - const magento = JSON.parse(out) as BinConsoleJSON; + const { stdout } = await executeShellCommand({ + command: "bin/magento", + args: ["list", "--format=json", "--raw"], + }); + const magento = JSON.parse(stdout) as BinConsoleJSON; const cacheTypes = await getCacheTypes(executeShellCommand); return { diff --git a/src/make.ts b/src/make.ts index 6200bd72a96b..a53ee1b94ca1 100644 --- a/src/make.ts +++ b/src/make.ts @@ -1,13 +1,17 @@ const listTargets: Fig.Generator = { custom: async (tokens, executeShellCommand) => { // Plain target suggestions. These will be overridden if we can find a description for them. - const targets = await executeShellCommand( - "make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\\/\\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | sort -u" - ); + const { stdout } = await executeShellCommand({ + command: "bash", + args: [ + "-c", + "make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\\/\\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | sort -u", + ], + }); const targetSuggestions = new Map(); - for (const target of targets.split("\n")) { + for (const target of stdout.split("\n")) { if (target === "Makefile") continue; targetSuggestions.set(target, { name: target.trim(), @@ -17,9 +21,12 @@ const listTargets: Fig.Generator = { }); } - const out = await executeShellCommand("cat [Mm]akefile"); + const { stdout: makefile } = await executeShellCommand({ + command: "cat", + args: ["Makefile", "makefile"], + }); - const matches = out.matchAll( + const matches = makefile.matchAll( /((?:^#.*\n)*)(?:^\.[A-Z_]+:.*\n)*(^\S*?):.*?(?:\s#+[ \t]*(.+))?$/gm ); const specialTargets = new Set([ diff --git a/src/mamba.ts b/src/mamba.ts index 9e43c54c9ebc..f0894dd089f5 100644 --- a/src/mamba.ts +++ b/src/mamba.ts @@ -37,7 +37,7 @@ interface SearchItem { const getMambaEnvs: Fig.Generator = { // For some reason the json version of this command // does not give out the names, so here we are - script: "conda env list", + script: ["conda", "env", "list"], scriptTimeout: 10000, cache: { strategy: "stale-while-revalidate", @@ -61,7 +61,7 @@ const getMambaEnvs: Fig.Generator = { }; const getInstalledPackages: Fig.Generator = { - script: "conda list --json", + script: ["conda", "list", "--json"], scriptTimeout: 10000, cache: { strategy: "stale-while-revalidate", @@ -87,7 +87,7 @@ const getInstalledPackages: Fig.Generator = { const condaSearchGenerator: Fig.Generator = { script: (context) => { const searchTerm = context[context.length - 1]; - return `conda search ${searchTerm} --json`; + return ["conda", "search", searchTerm, "--json"]; }, scriptTimeout: 10000, postProcess(out) { diff --git a/src/man.ts b/src/man.ts index d163f0af48c7..eb4c913006d0 100644 --- a/src/man.ts +++ b/src/man.ts @@ -51,11 +51,14 @@ const generateManualPages: Fig.Generator = { isGeneratingSuggestions = true; // Same as `apropos .`, lists all manual pages with a brief description - const lines = await executeShellCommand("man -k . 2>/dev/null"); + const { stdout } = await executeShellCommand({ + command: "man", + args: ["-k", "."], + }); const seenPageNameCache = new Set(); // Guaranteed to be one per line - for (const line of lines.split("\n")) { + for (const line of stdout.split("\n")) { const splitIndex = line.indexOf(" - "); const pageNames = line.slice(0, splitIndex); diff --git a/src/mask.ts b/src/mask.ts index 0b164225d7d4..660321b75d5e 100644 --- a/src/mask.ts +++ b/src/mask.ts @@ -9,17 +9,25 @@ const completionSpec: Fig.Spec = { var maskfileLocationIdx = tokens.indexOf("--maskfile"); - var out; + var out: string; // mask --maskfile path/tp/thing build if (maskfileLocationIdx < 0 || maskfileLocationIdx + 3 > tokens.length) { - out = await executeShellCommand("cat maskfile.md 2> /dev/null"); + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["maskfile.md"], + }); + out = stdout; } else { - out = await executeShellCommand( - `\\cat ${tokens[maskfileLocationIdx + 1]} 2> /dev/null` - ); + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [tokens[maskfileLocationIdx + 1]], + }); + out = stdout; } - if (!out) return { name: "null" }; + if (out === "") return { name: "null" }; return { name: "mask", diff --git a/src/mdfind.ts b/src/mdfind.ts index d9839fb59a13..449d35c1ec2e 100644 --- a/src/mdfind.ts +++ b/src/mdfind.ts @@ -1,17 +1,28 @@ const smartFolderGenerator: Fig.Generator = { // `mdfind -s` only accepts smart folders in ~/Library/Saved\ Searches/ - script: `ls -1A ~/Library/Saved\\ Searches/*.savedSearch`, - postProcess: function (files) { - return files.split("\n").map((path) => { - const components = path.split("/"); - const filename = components[components.length - 1]; - return { - name: filename.substring(0, filename.indexOf(".")), // .savedSearch automatically added to the query, so remove it - displayName: filename, - icon: "fig://" + path, - description: "Smart folder", - }; + + custom: async (_, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "ls", + args: [ + "-1A", + `${context.environmentVariables["HOME"]}/Library/Saved Searches/`, + ], }); + + return stdout + .split("\n") + .filter((file) => file.endsWith("savedSearch")) + .map((path) => { + const components = path.split("/"); + const filename = components[components.length - 1]; + return { + name: filename.substring(0, filename.indexOf(".")), // .savedSearch automatically added to the query, so remove it + displayName: filename, + icon: "fig://" + path, + description: "Smart folder", + }; + }); }, trigger: "/", }; diff --git a/src/meteor.ts b/src/meteor.ts index a41452bb1a07..76db94b3a771 100644 --- a/src/meteor.ts +++ b/src/meteor.ts @@ -1,7 +1,7 @@ import { filepaths } from "@fig/autocomplete-generators"; const examplesGenerator: Fig.Generator = { - script: "meteor create --list", + script: ["meteor", "create", "--list"], postProcess: (output) => { return output .split("\n") @@ -13,7 +13,7 @@ const examplesGenerator: Fig.Generator = { }; const packagesGenerator: Fig.Generator = { - script: "cat ./.meteor/packages", + script: ["cat", "./.meteor/packages"], postProcess: (output) => { if (output.includes("No such file or directory")) { return []; @@ -32,7 +32,7 @@ const packagesGenerator: Fig.Generator = { }; const platformGenerator: Fig.Generator = { - script: "meteor list-platforms", + script: ["meteor", "list-platforms"], postProcess: (output) => { return output.split("\n").map((platform) => { return { name: platform }; diff --git a/src/mix.ts b/src/mix.ts index 128ceb6d8e89..d09fe995cc4a 100644 --- a/src/mix.ts +++ b/src/mix.ts @@ -139,7 +139,7 @@ const completionSpec: Fig.Spec = { description: "Prints documentation for a given task", generators: { cache: { ttl: 10000 }, - script: "mix help", + script: ["mix", "help"], postProcess: makeTaskSuggestions, }, }, @@ -165,7 +165,7 @@ const completionSpec: Fig.Spec = { isOptional: true, generators: { cache: { ttl: 10000 }, - script: "mix help", + script: ["mix", "help"], postProcess: makeTaskSuggestions, }, }, diff --git a/src/mkinitcpio.ts b/src/mkinitcpio.ts index a6a2dc658c5e..ec9673336fb2 100644 --- a/src/mkinitcpio.ts +++ b/src/mkinitcpio.ts @@ -93,7 +93,7 @@ const completionSpec: Fig.Spec = { args: { name: "preset", generators: { - script: "ls /etc/mkinitcpio.d", + script: ["ls", "/etc/mkinitcpio.d"], postProcess: (out) => out .trim() diff --git a/src/mount.ts b/src/mount.ts index 86077f508300..9464c22f3637 100644 --- a/src/mount.ts +++ b/src/mount.ts @@ -7,7 +7,7 @@ const completionSpec: Fig.Spec = { template: "filepaths", generators: [ { - script: "cat /proc/partitions", // this way we don't depend on lsblk + script: ["cat", "/proc/partitions"], // this way we don't depend on lsblk postProcess: (out) => { return out .trim() @@ -21,7 +21,7 @@ const completionSpec: Fig.Spec = { }, }, { - script: "\\command ls -1 /dev/mapper", // usually LUKS encrypted partitions are here + script: ["ls", "-1", "/dev/mapper"], // usually LUKS encrypted partitions are here postProcess: (out) => { return out .trim() diff --git a/src/multipass.ts b/src/multipass.ts index f48a269c4cbb..6b7cbffa8f80 100644 --- a/src/multipass.ts +++ b/src/multipass.ts @@ -44,7 +44,7 @@ const sharedOpts: Record = { const multipassGenerators: Record = { allAvailableImages: { - script: "multipass find --format=json", + script: ["multipass", "find", "--format=json"], postProcess: (out) => { const images = JSON.parse(out).images; return Object.keys(images).map((key) => { @@ -56,7 +56,7 @@ const multipassGenerators: Record = { }, }, allAvailableInstances: { - script: "multipass list --format=json", + script: ["multipass", "list", "--format=json"], postProcess: (out) => { return JSON.parse(out).list.map((instance) => { if (instance.state !== "Deleted") { @@ -69,7 +69,7 @@ const multipassGenerators: Record = { }, }, allRunningInstances: { - script: "multipass list --format=json", + script: ["multipass", "list", "--format=json"], postProcess: (out) => { return JSON.parse(out).list.map((instance) => { if (instance.state === "Running") { @@ -82,7 +82,7 @@ const multipassGenerators: Record = { }, }, allStoppedInstances: { - script: "multipass list --format=json", + script: ["multipass", "list", "--format=json"], postProcess: (out) => { return JSON.parse(out).list.map((instance) => { if (instance.state === "Stopped") { @@ -95,7 +95,7 @@ const multipassGenerators: Record = { }, }, allDeletedInstances: { - script: "multipass list --format=json", + script: ["multipass", "list", "--format=json"], postProcess: (out) => { return JSON.parse(out).list.map((instance) => { if (instance.state === "Deleted") { diff --git a/src/n.ts b/src/n.ts index 2eba2e4500d6..1d58f0d7fd84 100644 --- a/src/n.ts +++ b/src/n.ts @@ -22,7 +22,7 @@ const versionArg: Fig.Arg = { }, ], generators: { - script: "n lsr --all", + script: ["n", "lsr", "--all"], postProcess: function (out) { const set = new Set(); const versions = out.split("\n").slice(1); diff --git a/src/networkQuality.ts b/src/networkQuality.ts index a2c77d043ba2..938a88ba6123 100644 --- a/src/networkQuality.ts +++ b/src/networkQuality.ts @@ -31,7 +31,7 @@ const completionSpec: Fig.Spec = { args: { name: "interface", generators: { - script: "networksetup -listallhardwareports", + script: ["networksetup", "-listallhardwareports"], postProcess: (out) => { const suggestions: Fig.Suggestion[] = []; const re = /^Hardware Port: (.*?)\n.*?Device: (.*?)$/gms; diff --git a/src/nextflow.ts b/src/nextflow.ts index 1b993ac28113..4894cee25486 100644 --- a/src/nextflow.ts +++ b/src/nextflow.ts @@ -1,5 +1,5 @@ const sessionid: Fig.Generator = { - script: "cat .nextflow/history | awk '{ print $7 }'", + script: ["bash", "-c", "cat .nextflow/history | awk '{ print $7 }'"], postProcess: (output) => { if (output == "") { return []; @@ -14,7 +14,7 @@ const sessionid: Fig.Generator = { }; const runname: Fig.Generator = { - script: "cat .nextflow/history | awk '{ print $4 }'", + script: ["bash", "-c", "cat .nextflow/history | awk '{ print $4 }'"], postProcess: (output) => { if (output == "") { return []; @@ -26,7 +26,11 @@ const runname: Fig.Generator = { }; const projectname: Fig.Generator = { - script: `/bin/sh -c "{ find * -maxdepth 0 -type f -name '*.nf' 2> /dev/null && find $HOME/.nextflow/assets/* -maxdepth 1 -type d | cut -d/ -f6,7 | grep / | grep -v assets; } 2> /dev/null"`, + script: [ + "bash", + "-c", + `{ find * -maxdepth 0 -type f -name '*.nf' 2> /dev/null && find $HOME/.nextflow/assets/* -maxdepth 1 -type d | cut -d/ -f6,7 | grep / | grep -v assets; } 2> /dev/null`, + ], postProcess: (output) => { if (output == "") { return []; @@ -41,7 +45,7 @@ const projectname: Fig.Generator = { }; const dockerimage: Fig.Generator = { - script: `docker images | cut -w -f 1 | grep -v REPOSITORY`, + script: ["bash", "-c", "docker images | cut -w -f 1 | grep -v REPOSITORY"], postProcess: (output) => { if (output == "") { return []; @@ -56,7 +60,11 @@ const dockerimage: Fig.Generator = { }; const secretname: Fig.Generator = { - script: `grep -o '"name": *"[^"]*"' $HOME/.nextflow/secrets/store.json | grep -o '"[^"]*"$' | tr -d \\"`, + script: [ + "bash", + "-c", + `grep -o '"name": *"[^"]*"' $HOME/.nextflow/secrets/store.json | grep -o '"[^"]*"$' | tr -d \\"`, + ], postProcess: (output) => { if (output == "") { return []; diff --git a/src/ng.ts b/src/ng.ts index 2c03fa0f3213..95ac2dc9cf53 100644 --- a/src/ng.ts +++ b/src/ng.ts @@ -3,7 +3,7 @@ interface ProjectDetails { } const projectsGenerator = { - script: "ng config projects", + script: ["ng", "config", "projects"], postProcess: function (out) { try { const projects = JSON.parse(out); diff --git a/src/node.ts b/src/node.ts index 9ec32fd5785e..48207fa70974 100644 --- a/src/node.ts +++ b/src/node.ts @@ -55,8 +55,15 @@ const completionSpec: Fig.Subcommand = { }, ], generateSpec: async (tokens, executeShellCommand) => { - const isAdonisJsonPresentCommand = "test -f .adonisrc.json && echo '1'"; - if ((await executeShellCommand(isAdonisJsonPresentCommand)) === "1") { + const isAdonisJsonPresentCommand = "test -f .adonisrc.json"; + if ( + ( + await executeShellCommand({ + command: "bash", + args: ["-c", "isAdonisJsonPresentCommand"], + }) + ).status === 0 + ) { return { name: "node", subcommands: [ diff --git a/src/npm.ts b/src/npm.ts index e37eaa3b46e7..0ea2647e9f9e 100644 --- a/src/npm.ts +++ b/src/npm.ts @@ -18,7 +18,7 @@ export const createNpmSearchHandler = (keywords?: string[]) => async ( context: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, shellContext: Fig.ShellContext ): Promise => { const searchTerm = context[context.length - 1]; @@ -34,19 +34,26 @@ export const createNpmSearchHandler = : `https://api.npms.io/v2/search/suggestions?q=${searchTerm}&size=20`; // Query the API with the package name - const queryPackages = `curl -s -H "Accept: application/json" "${queryPackagesUrl}"`; + const queryPackages = [ + "-s", + "-H", + "Accept: application/json", + queryPackagesUrl, + ]; // We need to remove the '@' at the end of the searchTerm before querying versions - const queryVersions = `curl -s -H "Accept: application/vnd.npm.install-v1+json" https://registry.npmjs.org/${searchTerm.slice( - 0, - -1 - )}`; + const queryVersions = [ + "-s", + "-H", + "Accept: application/vnd.npm.install-v1+json", + `https://registry.npmjs.org/${searchTerm.slice(0, -1)}`, + ]; // If the end of our token is '@', then we want to generate version suggestions // Otherwise, we want packages const out = (query: string) => - query[query.length - 1] === "@" - ? executeShellCommand(queryVersions) - : executeShellCommand(queryPackages); - + executeShellCommand({ + command: "curl", + args: query[query.length - 1] === "@" ? queryVersions : queryPackages, + }); // If our token starts with '@', then a 2nd '@' tells us we want // versions. // Otherwise, '@' anywhere else in the string will indicate the same. @@ -55,7 +62,7 @@ export const createNpmSearchHandler = : searchTerm.includes("@"); try { - const data = JSON.parse(await out(searchTerm)); + const data = JSON.parse((await out(searchTerm)).stdout); if (shouldGetVersion) { // create dist tags suggestions const versions = Object.entries(data["dist-tags"] || {}).map( @@ -107,10 +114,21 @@ export const npmSearchGenerator: Fig.Generator = { }; const workspaceGenerator: Fig.Generator = { - script: "cat $(npm prefix)/package.json", - postProcess: function (out: string) { - const suggestions = []; + // script: "cat $(npm prefix)/package.json", + custom: async (tokens, executeShellCommand) => { + const { stdout: npmPrefix } = await executeShellCommand({ + command: "npm", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["prefix"], + }); + + const { stdout: out } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${npmPrefix}/package.json`], + }); + const suggestions = []; try { if (out.trim() == "") { return suggestions; @@ -139,7 +157,16 @@ export const dependenciesGenerator: Fig.Generator = { trigger: (newToken) => newToken === "-g" || newToken === "--global", custom: async function (tokens, executeShellCommand) { if (!tokens.includes("-g") && !tokens.includes("--global")) { - const out = await executeShellCommand("cat $(npm prefix)/package.json"); + const { stdout: npmPrefix } = await executeShellCommand({ + command: "npm", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["prefix"], + }); + const { stdout: out } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${npmPrefix}/package.json`], + }); const packageContent = JSON.parse(out); const dependencies = packageContent["dependencies"] ?? {}; const devDependencies = packageContent["devDependencies"]; @@ -161,8 +188,11 @@ export const dependenciesGenerator: Fig.Generator = { : "devDependency", })); } else { - const out = await executeShellCommand("ls -1 `npm root -g`"); - return out.split("\n").map((name) => ({ + const { stdout } = await executeShellCommand({ + command: "bash", + args: ["-c", "ls -1 `npm root -g`"], + }); + return stdout.split("\n").map((name) => ({ name, icon: "📦", description: "Global dependency", @@ -177,8 +207,11 @@ export const npmScriptsGenerator: Fig.Generator = { strategy: "stale-while-revalidate", cacheByDirectory: true, }, - script: + script: [ + "bash", + "-c", "until [[ -f package.json ]] || [[ $PWD = '/' ]]; do cd ..; done; cat package.json", + ], postProcess: function (out, [npmClient]) { if (out.trim() == "") { return []; diff --git a/src/npx.ts b/src/npx.ts index f84cbd030ccb..6ddd1844565e 100644 --- a/src/npx.ts +++ b/src/npx.ts @@ -166,7 +166,11 @@ const completionSpec: Fig.Spec = { name: "command", isCommand: true, generators: { - script: `until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/`, + script: [ + "bash", + "-c", + "until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/", + ], postProcess: function (out) { const cli = [...npxSuggestions].reduce( (acc, { name }) => [...acc, name], diff --git a/src/ns.ts b/src/ns.ts index c30be334ce9f..c4518f2d3c0e 100644 --- a/src/ns.ts +++ b/src/ns.ts @@ -27,7 +27,7 @@ const deviceOption: Fig.Option = { name: "device id", // TODO: create a generator of ns device --available-devices // generators: { - // script: "ns devices --json", + // script: ["ns", "devices", "--json"], // postProcess: (output) => { // return [{ // name: "test1", @@ -545,8 +545,11 @@ const createCommand: Fig.Subcommand = { args: { name: "template", generators: { - script: - "curl https://api.github.com/repos/NativeScript/nativescript-app-templates/contents/packages", + script: [ + "curl", + "-sfL", + "https://api.github.com/repos/NativeScript/nativescript-app-templates/contents/packages", + ], cache: { ttl: 100 * 24 * 60 * 60 * 1000, // 100days }, @@ -1178,7 +1181,7 @@ const deviceCommand: Fig.Subcommand = { name: "application id", description: "The application identifier", //TODO: generator $ tns device list-applications. // generators: { - // script: "ns device list-applications", + // script: ["ns", "device", "list-applications"], // postProcess: (output) => { // return JSON.parse(output).map((branch) => { // const template = branch?.name; diff --git a/src/nx.ts b/src/nx.ts index 77e522883906..81c56966577b 100644 --- a/src/nx.ts +++ b/src/nx.ts @@ -121,7 +121,7 @@ const fillProjectCaches = (projectJson: NxProject) => { }; const preProcessProjects = async ( - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ) => { if (!nxProjectPathCache.length) { // get project json paths @@ -129,13 +129,24 @@ const preProcessProjects = async ( const { appsDir, libsDir }: { appsDir: string; libsDir: string } = { appsDir: "apps", libsDir: "libs", - ...JSON.parse(await executeShellCommand("cat nx.json")).workspaceLayout, + ...JSON.parse( + ( + await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["nx.json"], + }) + ).stdout + ).workspaceLayout, }; const searchFolders = appsDir === libsDir ? appsDir : `${appsDir} ${libsDir}`; nxProjectPathCache = ( - await executeShellCommand(`find ${searchFolders} -name "project.json"`) - ) + await executeShellCommand({ + command: "find", + args: [searchFolders, "-name", "project.json"], + }) + ).stdout .split("\n") .filter((path) => !!path); } catch (error) { @@ -149,7 +160,13 @@ const preProcessProjects = async ( if (!projectJson) { try { projectJson = JSON.parse( - await executeShellCommand(`cat "${projectJsonPath}"`) + ( + await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [projectJsonPath], + }) + ).stdout ); nxProjectPathWithJsonCache.set(projectJsonPath, projectJson); @@ -167,7 +184,13 @@ const preProcessProjects = async ( if (!nxProjectPathCache.length) { try { nxWorkspaceJsonCache = JSON.parse( - await executeShellCommand(`cat "workspace.json"`) + ( + await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["workspace.json"], + }) + ).stdout ); // fill project caches @@ -191,7 +214,7 @@ const listMapKeysGenerator = (map: Map): Fig.Generator => { getQueryTerm: (token) => token.split(",").pop(), custom: async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, generatorContext: Fig.GeneratorContext ) => { const suggestions: Fig.Suggestion[] = []; @@ -214,7 +237,7 @@ const nxGenerators: NxGenerators = { cache: oneDayCache, custom: async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ) => { const suggestions: Fig.Suggestion[] = []; @@ -245,9 +268,9 @@ const nxGenerators: NxGenerators = { script: (context) => { const argument = context.slice(-1)[0]; if (argument.indexOf(":") > -1) { - return `nx list ${argument.split(":")[0]}`; + return ["nx", "list", argument.split(":")[0]]; } else { - return "nx list"; + return ["nx", "list"]; } }, trigger: (newToken, oldToken) => @@ -274,7 +297,7 @@ const nxGenerators: NxGenerators = { }, }, list: { - script: "nx list", + script: ["nx", "list"], cache: oneDayCache, postProcess: (out) => { if (out.indexOf("Installed plugins") > -1) { @@ -295,7 +318,7 @@ const nxGenerators: NxGenerators = { // the custom generator custom: async ( _: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ) => { // suggestions to be returned const suggestions: Fig.Suggestion[] = []; @@ -323,7 +346,7 @@ const nxGenerators: NxGenerators = { // the custom generator custom: async ( tokens: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction, + executeShellCommand: Fig.ExecuteCommandFunction, generatorContext: Fig.GeneratorContext ) => { // suggestions to be returned @@ -370,7 +393,7 @@ const nxGenerators: NxGenerators = { }, targets: listMapKeysGenerator(nxTargetWithProjectsCache), workspaceGenerator: { - script: "ls -d tools/generators/*/", + script: ["bash", "-c", "ls -d tools/generators/*/"], cache: oneDayCache, postProcess: (out) => out @@ -665,7 +688,7 @@ const RUN_DERIVED_BASE_TARGETS_WITH_CONFIGURATION = ["build", "serve"]; */ const runDerivedSubcommands = async ( _: string[], - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ): Promise => { const subcommands: Fig.Subcommand[] = []; diff --git a/src/okteto.ts b/src/okteto.ts index 030c60fdae95..afb98fdd32c8 100644 --- a/src/okteto.ts +++ b/src/okteto.ts @@ -1,5 +1,5 @@ const contexts: Fig.Generator = { - script: "okteto context list", + script: ["okteto", "context", "list"], cache: { ttl: 1000 * 60 * 30, // 30 minutes }, @@ -19,7 +19,7 @@ const contexts: Fig.Generator = { }; const namespaces: Fig.Generator = { - script: "okteto namespace list", + script: ["okteto", "namespace", "list"], cache: { ttl: 1000 * 60 * 30, // 30 minutes }, diff --git a/src/op.ts b/src/op.ts index 8a51c6e012ab..319ffc1e8bee 100644 --- a/src/op.ts +++ b/src/op.ts @@ -9,7 +9,7 @@ interface Account { } const suggestAccounts: Fig.Generator = { - script: "op account list --format json", + script: ["op", "account", "list", "--format", "json"], postProcess: (out) => { const json = JSON.parse(out) as Account[]; return json.map((account) => ({ diff --git a/src/open.ts b/src/open.ts index 4b03fd1bd68d..66aec9be424d 100644 --- a/src/open.ts +++ b/src/open.ts @@ -1,6 +1,11 @@ export const generateApps = (unquotedPath: string): Fig.Generator => ({ cache: { strategy: "stale-while-revalidate" }, - script: `mdfind kMDItemContentTypeTree=com.apple.application-bundle -onlyin ${unquotedPath}`, + script: [ + "mdfind", + "kMDItemContentTypeTree=com.apple.application-bundle", + "-onlyin", + unquotedPath, + ], postProcess: (out) => { return out.split("\n").map((path) => { const basename = path.slice(path.lastIndexOf("/") + 1); @@ -21,7 +26,11 @@ export const generateApps = (unquotedPath: string): Fig.Generator => ({ export const generateBundleIds = (unquotedPath: string): Fig.Generator => ({ scriptTimeout: 15000, cache: { strategy: "stale-while-revalidate" }, - script: `bash -c 'mdfind kMDItemContentTypeTree=com.apple.application-bundle -onlyin ${unquotedPath} | while read line; do echo $(mdls -name kMDItemCFBundleIdentifier -r "$line") $line; done'`, + script: [ + "bash", + "-c", + `mdfind kMDItemContentTypeTree=com.apple.application-bundle -onlyin ${unquotedPath} | while read line; do echo $(mdls -name kMDItemCFBundleIdentifier -r "$line") $line; done`, + ], postProcess: (out) => { const ids = new Map( out.split("\n").map((line) => { diff --git a/src/pandoc.ts b/src/pandoc.ts index 530507d0db3a..e2509252dc19 100644 --- a/src/pandoc.ts +++ b/src/pandoc.ts @@ -1,36 +1,52 @@ import { filepaths } from "@fig/autocomplete-generators"; -const pandocGenerators: Record = { - inputFormats: { - script: "pandoc --list-input-formats", - postProcess: function (out) { - return out.split("\n").map((format) => ({ - name: format, - icon: `fig://icon?type=${format}`, - })); +const pandocGenerators: Record = { + inputFormats: [ + { + script: ["pandoc", "--list-input-formats"], + postProcess: function (out) { + return out.split("\n").map((format) => ({ + name: format, + icon: `fig://icon?type=${format}`, + })); + }, }, - }, - outputFormats: { - script: "pandoc --list-output-formats", - postProcess: function (out) { - return out.split("\n").map((format) => ({ - name: format, - icon: `fig://icon?type=${format}`, - })); + ], + outputFormats: [ + { + script: ["pandoc", "--list-output-formats"], + postProcess: function (out) { + return out.split("\n").map((format) => ({ + name: format, + icon: `fig://icon?type=${format}`, + })); + }, }, - }, - formats: { - script: "pandoc --list-input-formats && pandoc --list-output-formats", - postProcess: function (out) { - const uniqueFormats = Array.from(new Set(out.split("\n"))); - return uniqueFormats.map((format) => ({ - name: format, - icon: `fig://icon?type=${format}`, - })); + ], + formats: [ + { + script: ["pandoc", "--list-input-formats"], + postProcess: function (out) { + const uniqueFormats = Array.from(new Set(out.split("\n"))); + return uniqueFormats.map((format) => ({ + name: format, + icon: `fig://icon?type=${format}`, + })); + }, }, - }, - yamlFiles: filepaths({ extensions: ["yaml"] }), - yamlJSONFiles: filepaths({ extensions: ["yaml", "json"] }), + { + script: ["pandoc", "--list-output-formats"], + postProcess: function (out) { + const uniqueFormats = Array.from(new Set(out.split("\n"))); + return uniqueFormats.map((format) => ({ + name: format, + icon: `fig://icon?type=${format}`, + })); + }, + }, + ], + yamlFiles: [filepaths({ extensions: ["yaml"] })], + yamlJSONFiles: [filepaths({ extensions: ["yaml", "json"] })], }; const styleFileArg: Fig.Arg = { diff --git a/src/pass.ts b/src/pass.ts index b1f57990fc4d..fbfce12b569a 100644 --- a/src/pass.ts +++ b/src/pass.ts @@ -1,9 +1,16 @@ const listPasswords: Fig.Generator = { - script: function () { - return `grep -r -l '' $HOME/.password-store --exclude-dir=.git`; - }, - postProcess: (output) => { - return output.split("\n").map((password) => ({ + custom: async (_tokens, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "grep", + args: [ + "-r", + "-l", + "", + `${context.environmentVariables["HOME"]}/.password-store`, + "--exclude-dir=.git", + ], + }); + return stdout.split("\n").map((password) => ({ name: password.split(".password-store/").pop().replace(".gpg", ""), icon: "🔐", })); @@ -11,11 +18,15 @@ const listPasswords: Fig.Generator = { }; const listDirectories: Fig.Generator = { - script: function () { - return `ls -dR1a $HOME/.password-store/*/`; - }, - postProcess: (output) => { - return output.split("\n").map((dir) => ({ + custom: async (_tokens, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "ls", + args: [ + "-dR1a", + `${context.environmentVariables["HOME"]}/.password-store`, + ], + }); + return stdout.split("\n").map((dir) => ({ name: dir.split(".password-store/").pop(), icon: "📁", })); diff --git a/src/passwd.ts b/src/passwd.ts index 83092153268a..92a80dcad1ab 100644 --- a/src/passwd.ts +++ b/src/passwd.ts @@ -1,5 +1,5 @@ const generateUsers: Fig.Generator = { - script: "dscl . -list /Users | grep -E -v '^_'", + script: ["bash", "-c", "dscl . -list /Users | grep -E -v '^_'"], postProcess: (out) => out .trim() diff --git a/src/php.ts b/src/php.ts index f8e1497cf3e6..ab600468cfea 100644 --- a/src/php.ts +++ b/src/php.ts @@ -1,22 +1,41 @@ // To learn more about Fig's autocomplete standard visit: https://fig.io/docs/concepts/cli-skeleton +const fileExists = async ( + executeCommand: Fig.ExecuteCommandFunction, + file: string +) => { + return ( + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + (await executeCommand({ command: "ls", args: [file] })).status === 0 + ); +}; + const completionSpec: Fig.Spec = { name: "php", description: "Run the PHP interpreter", generateSpec: async (tokens, executeShellCommand) => { const subcommands = []; - if ((await executeShellCommand("ls -1 artisan")) === "artisan") { - subcommands.push({ name: "artisan", loadSpec: "php/artisan" }); - } - - if ((await executeShellCommand("ls -1 please")) === "please") { - subcommands.push({ name: "please", loadSpec: "php/please" }); - } - - if ((await executeShellCommand("ls -1 bin/console")) === "bin/console") { - subcommands.push({ name: "bin/console", loadSpec: "php/bin-console" }); - } + await Promise.all([ + async () => { + if (await fileExists(executeShellCommand, "artisan")) { + subcommands.push({ name: "artisan", loadSpec: "php/artisan" }); + } + }, + async () => { + if (await fileExists(executeShellCommand, "please")) { + subcommands.push({ name: "please", loadSpec: "php/please" }); + } + }, + async () => { + if (await fileExists(executeShellCommand, "bin/console")) { + subcommands.push({ + name: "bin/console", + loadSpec: "php/bin-console", + }); + } + }, + ]); return { name: "php", diff --git a/src/php/artisan.ts b/src/php/artisan.ts index ba590100719c..1f2e6c2ee428 100644 --- a/src/php/artisan.ts +++ b/src/php/artisan.ts @@ -1,12 +1,15 @@ const completionSpec: Fig.Spec = { name: "artisan", description: "Laravel Artisan Command", - generateSpec: async (tokens, executeShellCommand) => { - var out = await executeShellCommand("php artisan list --format=json"); + generateSpec: async (_, executeShellCommand) => { + var { stdout } = await executeShellCommand({ + command: "php", + args: ["artisan", "list", "--format=json"], + }); const subcommands = []; try { - const commandDefinition = JSON.parse(out); + const commandDefinition = JSON.parse(stdout); commandDefinition.commands.map((command) => { subcommands.push({ diff --git a/src/php/bin-console.ts b/src/php/bin-console.ts index 1eb7238c2eff..03feb0e69976 100644 --- a/src/php/bin-console.ts +++ b/src/php/bin-console.ts @@ -36,11 +36,14 @@ const completionSpec: Fig.Spec = { name: "bin-console", description: "Symfony bin/console command", generateSpec: async (_, executeShellCommand) => { - const out = await executeShellCommand("php bin/console list --format=json"); + const { stdout } = await executeShellCommand({ + command: "php", + args: ["bin/console", "list", "--format=json"], + }); let subcommands = []; try { - const commandDefinitions = JSON.parse(out) as BinConsoleJSON; + const commandDefinitions = JSON.parse(stdout) as BinConsoleJSON; subcommands = commandDefinitions.commands.map((command) => ({ name: command.name, diff --git a/src/php/please.ts b/src/php/please.ts index 79000ec4af24..1f4dad98c3a3 100644 --- a/src/php/please.ts +++ b/src/php/please.ts @@ -20,11 +20,14 @@ const completionSpec: Fig.Spec = { name: "please", description: "Statamic Please command", generateSpec: async (tokens, executeShellCommand) => { - const out = await executeShellCommand("php please list --format=json"); + const { stdout } = await executeShellCommand({ + command: "php", + args: ["please", "list", "--format=json"], + }); const subcommands = []; try { - const commandDefinition = JSON.parse(out); + const commandDefinition = JSON.parse(stdout); commandDefinition.commands.map((command) => { subcommands.push({ diff --git a/src/phpunit-watcher.ts b/src/phpunit-watcher.ts index 1ec677ca40cd..84973160ee21 100644 --- a/src/phpunit-watcher.ts +++ b/src/phpunit-watcher.ts @@ -1,5 +1,5 @@ const tests: Fig.Generator = { - script: "phpunit --list-tests", + script: ["phpunit", "--list-tests"], postProcess: function (out) { if (out.startsWith("fatal:")) { return []; diff --git a/src/pip.ts b/src/pip.ts index 5c6372490356..4f17c053a019 100644 --- a/src/pip.ts +++ b/src/pip.ts @@ -1,5 +1,5 @@ const listPackages: Fig.Generator = { - script: "pip list", + script: ["pip", "list"], postProcess: function (out) { const lines = out.split("\n"); const packages = []; diff --git a/src/pipx.ts b/src/pipx.ts index a11437a07763..20ae187e1156 100644 --- a/src/pipx.ts +++ b/src/pipx.ts @@ -1,5 +1,5 @@ const packagesGenerator: Fig.Generator = { - script: "pipx list --short", + script: ["pipx", "list", "--short"], postProcess: (out) => { return out.split("\n").map((line) => { return { diff --git a/src/pkgutil.ts b/src/pkgutil.ts index 38420e213940..52cc1be98228 100644 --- a/src/pkgutil.ts +++ b/src/pkgutil.ts @@ -25,7 +25,7 @@ const postProcessPkgFilenames = export const pkgutilGenerators: Record = { // BOM files bom: { - script: "find . -type f -name '*.bom' -maxdepth 1", + script: ["find", ".", "-type", "f", "-name", "*.bom", "-maxdepth", "1"], postProcess: function (out) { return out.split("\n").map((filepath) => ({ name: filepath.replace("./", ""), @@ -34,12 +34,12 @@ export const pkgutilGenerators: Record = { }, // Installed package ids packageIds: { - script: "pkgutil --pkgs", + script: ["pkgutil", "--pkgs"], splitOn: "\n", }, // .pkg files pkgs: { - script: "find . -type f -name '*.pkg' -maxdepth 1", + script: ["find", ".", "-type", "f", "-name", "*.pkg", "-maxdepth", "1"], postProcess: function (out) { return out.split("\n").map((filepath) => ({ name: filepath.replace("./", ""), @@ -48,7 +48,7 @@ export const pkgutilGenerators: Record = { }, // group ids groupIds: { - script: "pkgutil --groups", + script: ["pkgutil", "--groups"], splitOn: "\n", }, // filenames within a package @@ -63,7 +63,15 @@ export const pkgutilGenerators: Record = { const pkgId = tokens[pkgIdIndex]; const pathPrefix = tokens[tokens.length - 1]; const pp = postProcessPkgFilenames({ pathPrefix }); - return pp(await executeShellCommand(`pkgutil --files ${pkgId}`), tokens); + return pp( + ( + await executeShellCommand({ + command: "pkgutil", + args: ["--files", pkgId], + }) + ).stdout, + tokens + ); }, trigger: "/", }, diff --git a/src/pnpm.ts b/src/pnpm.ts index 16147931c155..1278c2f99430 100644 --- a/src/pnpm.ts +++ b/src/pnpm.ts @@ -10,7 +10,7 @@ const filterMessages = (out: string): string => { }; const searchBranches: Fig.Generator = { - script: "git branch --no-color", + script: ["git", "branch", "--no-color"], postProcess: function (out) { const output = filterMessages(out); @@ -45,7 +45,7 @@ const searchBranches: Fig.Generator = { }; const generatorInstalledPackages: Fig.Generator = { - script: "pnpm ls", + script: ["pnpm", "ls"], postProcess: function (out) { /** * out @@ -964,10 +964,17 @@ const completionSpec: Fig.Spec = { }, filterStrategy: "fuzzy", generateSpec: async (tokens, executeShellCommand) => { - const { script, postProcess } = dependenciesGenerator; + const { script, postProcess } = dependenciesGenerator as Fig.Generator & { + script: string[]; + }; const packages = postProcess( - await executeShellCommand(script as string), + ( + await executeShellCommand({ + command: script[0], + args: script.slice(1), + }) + ).stdout, tokens ).map(({ name }) => name as string); diff --git a/src/pre-commit.ts b/src/pre-commit.ts index 2afd9cf7933c..3d384122a139 100644 --- a/src/pre-commit.ts +++ b/src/pre-commit.ts @@ -2,7 +2,7 @@ import YAML from "yaml"; import { gitGenerators } from "./git"; const hooksInConfig: Fig.Generator = { - script: "cat .pre-commit-config.yaml", + script: ["cat", ".pre-commit-config.yaml"], postProcess: (output) => { const suggestions: Fig.Suggestion[] = []; diff --git a/src/projj.ts b/src/projj.ts index 0894066cfacb..3dae6e5fa186 100644 --- a/src/projj.ts +++ b/src/projj.ts @@ -1,7 +1,11 @@ const repoGenerator: Fig.Generator = { - script: "cat ~/.projj/cache.json", - postProcess: function (out) { - const cache = JSON.parse(out); + custom: async (_, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${context.environmentVariables["HOME"]}/.projj/cache.json`], + }); + const cache = JSON.parse(stdout); return Object.keys(cache).map((key) => ({ name: key.split("/").pop(), description: cache[key].repo, @@ -10,9 +14,13 @@ const repoGenerator: Fig.Generator = { }; const hookGenerator: Fig.Generator = { - script: "cat ~/.projj/config.json", - postProcess: function (out) { - const cache = JSON.parse(out); + custom: async (_, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${context.environmentVariables["HOME"]}/.projj/config.json`], + }); + const cache = JSON.parse(stdout); const hooks = cache.hooks; return Object.keys(hooks).map((key) => ({ name: key, diff --git a/src/pulumi.ts b/src/pulumi.ts index ed47d4127973..4069341456f6 100644 --- a/src/pulumi.ts +++ b/src/pulumi.ts @@ -2,7 +2,7 @@ const stacksGenerator: Fig.Generator = { cache: { cacheByDirectory: true, }, - script: "pulumi stack ls --json", + script: ["pulumi", "stack", "ls", "--json"], postProcess: (out) => { try { return JSON.parse(out).map((stack) => ({ diff --git a/src/pyenv.ts b/src/pyenv.ts index f0ad760452ee..89032fe75e86 100644 --- a/src/pyenv.ts +++ b/src/pyenv.ts @@ -1,5 +1,5 @@ const versionList: Fig.Generator = { - script: "pyenv install -l", + script: ["pyenv", "install", "-l"], postProcess: function (out) { return out .trim() @@ -10,7 +10,7 @@ const versionList: Fig.Generator = { }; const globalList: Fig.Generator = { - script: "pyenv versions", + script: ["pyenv", "versions"], postProcess: function (out) { return out .trim() diff --git a/src/python.ts b/src/python.ts index 555dbfb0c012..e8ad1793d0e3 100644 --- a/src/python.ts +++ b/src/python.ts @@ -4,11 +4,14 @@ const completionSpec: Fig.Spec = { name: "python", description: "Run the python interpreter", generateSpec: async (tokens, executeShellCommand) => { - const isDjangoManagePyFilePresentCommand = - "cat manage.py | grep -q django; echo $?"; - + const isDjangoManagePyFilePresentCommand = "cat manage.py | grep -q django"; if ( - (await executeShellCommand(isDjangoManagePyFilePresentCommand)) === "0" + ( + await executeShellCommand({ + command: "bash", + args: ["-c", isDjangoManagePyFilePresentCommand], + }) + ).status === 0 ) { return { name: "python", diff --git a/src/python3.ts b/src/python3.ts index a898a4545dd4..7e763c3906d2 100644 --- a/src/python3.ts +++ b/src/python3.ts @@ -4,11 +4,15 @@ const completionSpec: Fig.Spec = { name: "python3", description: "Run the python interpreter", generateSpec: async (tokens, executeShellCommand) => { - const isDjangoManagePyFilePresentCommand = - "cat manage.py | grep -q django; echo $?"; + const isDjangoManagePyFilePresentCommand = "cat manage.py | grep -q django"; if ( - (await executeShellCommand(isDjangoManagePyFilePresentCommand)) === "0" + ( + await executeShellCommand({ + command: "bash", + args: ["-c", isDjangoManagePyFilePresentCommand], + }) + ).status === 0 ) { return { name: "python3", diff --git a/src/quickmail.ts b/src/quickmail.ts index 95f8c3b3b044..e3e43085672b 100644 --- a/src/quickmail.ts +++ b/src/quickmail.ts @@ -1,5 +1,5 @@ const bodyTempalates: Fig.Generator = { - script: "quickmail template listall", + script: ["quickmail", "template", "listall"], postProcess: (output) => { const items = output.split("\n"); return items.map((item) => { diff --git a/src/r.ts b/src/r.ts index cf7a61d8d074..4cf252fe25c2 100644 --- a/src/r.ts +++ b/src/r.ts @@ -19,7 +19,7 @@ const RFileGenerator = filepaths({ }); const RLibGenerator: Fig.Generator = { - script: "Rscript -e '.libPaths()'", + script: ["Rscript", "-e", ".libPaths()"], postProcess: (output) => { if (output.includes("not found")) { return []; diff --git a/src/rails.ts b/src/rails.ts index f35895a3b23f..74952848a192 100644 --- a/src/rails.ts +++ b/src/rails.ts @@ -483,7 +483,7 @@ const defaultCommands: Fig.Subcommand[] = [ { name: "generator", generators: { - script: "rails g --help", + script: ["rails", "g", "--help"], postProcess(out) { const lines = out.split("Rails:")[1].trim().split("\n"); @@ -581,7 +581,10 @@ const defaultCommands: Fig.Subcommand[] = [ isOptional: true, }, async generateSpec(_, executeShellCommand) { - const helpText = await executeShellCommand("rails test --help"); + const { stdout: helpText } = await executeShellCommand({ + command: "rails", + args: ["test", "--help"], + }); const argRegex = /(?:(-[a-zA-Z]), )?(--[^ ]+?)[ =]([A-Z_]+)?[ \r\n]+([^\n]+)/g; @@ -606,7 +609,11 @@ export const railsCommandsGenerator: Fig.Generator = { // parse help text to find more commands let commands: Fig.Subcommand[] = []; try { - const helpText = await executeShellCommand("rails --tasks"); + const { stdout: helpText } = await executeShellCommand({ + command: "rails", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--tasks"], + }); const defaultCommandNames = defaultCommands.map((c) => c.name); const matches = Array.from(helpText.matchAll(/rails ([^ ]+)/g)); @@ -631,9 +638,16 @@ const completionSpec: Fig.Spec = { description: "Ruby on Rails CLI", icon: "https://avatars.githubusercontent.com/u/4223?s=48&v=4", generateSpec: async (_, executeShellCommand) => { - const isRailsDirectory = !!(await executeShellCommand( - `until [[ -f Gemfile ]] || [[ $PWD = '/' ]]; do cd ..; done; if [ -f Gemfile ]; then cat Gemfile | \\grep "gem ['\\"]rails['\\"]"; fi` - )); + const isRailsDirectory = + ( + await executeShellCommand({ + command: "bash", + args: [ + "-c", + `until [[ -f Gemfile ]] || [[ $PWD = '/' ]]; do cd ..; done; if [ -f Gemfile ]; then cat Gemfile | \\grep "gem ['\\"]rails['\\"]"; fi`, + ], + }) + ).status === 0; if (!isRailsDirectory) { return { diff --git a/src/rake.ts b/src/rake.ts index f525172aa0f0..838128c2b569 100644 --- a/src/rake.ts +++ b/src/rake.ts @@ -7,7 +7,7 @@ const completionSpec: Fig.Spec = { isVariadic: true, isOptional: true, generators: { - script: "rake --tasks --silent", + script: ["rake", "--tasks", "--silent"], cache: { strategy: "stale-while-revalidate", cacheByDirectory: true, diff --git a/src/rancher.ts b/src/rancher.ts index 7f3878c981ef..3dfc6a920e19 100644 --- a/src/rancher.ts +++ b/src/rancher.ts @@ -1,7 +1,7 @@ import { filepaths } from "@fig/autocomplete-generators"; const serverList: Fig.Generator = { - script: "rancher server ls", + script: ["rancher", "server", "ls"], postProcess: function (out) { const lines = out.split("\n"); const serversList = []; diff --git a/src/rbenv.ts b/src/rbenv.ts index d09688b902cd..59ea346966f5 100644 --- a/src/rbenv.ts +++ b/src/rbenv.ts @@ -1,12 +1,12 @@ const installVersionsGenerator: Fig.Generator = { - script: "rbenv install -L", + script: ["rbenv", "install", "-L"], postProcess: function (out) { return out.split("\n").map((name) => ({ name })); }, }; const installedVersionsGenerator: Fig.Generator = { - script: "rbenv versions --bare", + script: ["rbenv", "versions", "--bare"], postProcess: function (out) { return out.split("\n").map((name) => ({ name })); }, diff --git a/src/rclone.ts b/src/rclone.ts index 228e3593422f..5cfb345825a3 100644 --- a/src/rclone.ts +++ b/src/rclone.ts @@ -2,7 +2,7 @@ const remote: Fig.Arg = { name: "remote:", generators: { - script: "rclone listremotes", + script: ["rclone", "listremotes"], postProcess: (list) => list.split("\n").map((remote) => ({ name: remote })), }, }; diff --git a/src/react-native.ts b/src/react-native.ts index 08c0db3437a6..3aaa0ff99598 100644 --- a/src/react-native.ts +++ b/src/react-native.ts @@ -14,7 +14,7 @@ const getJsFilesAndFolders = filepaths({ }); const workerGenerator = { - script: "sysctl -n hw.ncpu", + script: ["sysctl", "-n", "hw.ncpu"], postProcess: (scriptOutput: string) => { return Array.from({ length: Number(scriptOutput) }, (_x, i) => ({ name: `${i}`, @@ -22,7 +22,7 @@ const workerGenerator = { }, }; const xcodeConfigGenerator = { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["bash", "-c", "xcodebuild -project ios/*.xcodeproj -list -json"], postProcess: (scriptOutput: string) => { const configurations = JSON.parse(scriptOutput).project.configurations; @@ -31,7 +31,7 @@ const xcodeConfigGenerator = { }; const xcodeSchemeGenerator = { - script: "xcodebuild -project ios/*.xcodeproj -list -json", + script: ["bash", "-c", "xcodebuild -project ios/*.xcodeproj -list -json"], postProcess: (scriptOutput: string) => { const configurations = JSON.parse(scriptOutput).project.schemes; @@ -40,7 +40,7 @@ const xcodeSchemeGenerator = { }; const androidGetDevicesGenerator = { - script: "adb devices", + script: ["adb", "devices"], postProcess: (scriptOutput: string) => { const devices = scriptOutput .split("\n") @@ -58,7 +58,7 @@ const androidGetDevicesGenerator = { type IosRecordType = { name: string }; const iosGetDevicesSimulatorGenerator = { - script: "xcrun simctl list --json devices available", + script: ["xcrun", "simctl", "list", "--json", "devices", "available"], postProcess: (scriptOutput: string) => { const devices = JSON.parse(scriptOutput).devices; @@ -76,7 +76,7 @@ const iosGetDevicesSimulatorGenerator = { }; const iosGetDevicesGenerator = { - script: "xcrun xctrace list devices", + script: ["xcrun", "xctrace", "list", "devices"], postProcess: (scriptOutput: string) => { const devices = scriptOutput .split("\n") @@ -90,7 +90,7 @@ const iosGetDevicesGenerator = { }; const iosGetDevicesUdidGenerator = { - script: "xcrun xctrace list devices", + script: ["xcrun", "xctrace", "list", "devices"], postProcess: (scriptOutput: string) => { const devices = scriptOutput .split("\n") @@ -106,8 +106,8 @@ const iosGetDevicesUdidGenerator = { }, }; -const gradleTasksGenerator = { - script: "cd android/ && ./gradlew tasks", +const gradleTasksGenerator: Fig.Generator = { + script: ["bash", "-c", "cd android/ && ./gradlew tasks"], postProcess: (scriptOutput: string) => { const tasks = scriptOutput .split("\n") diff --git a/src/redwood.ts b/src/redwood.ts index 42d8a246f2e6..21c56ca78d91 100644 --- a/src/redwood.ts +++ b/src/redwood.ts @@ -3,8 +3,11 @@ import prismaSpec from "./prisma"; const icon = "https://avatars.githubusercontent.com/u/45050444?s=200&v=4"; const scripts: Fig.Generator = { - script: + script: [ + "bash", + "-c", "until [[ -f redwood.toml ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1p scripts/", + ], postProcess: (output) => { if (output.trim() === "") { return []; diff --git a/src/robot.ts b/src/robot.ts index 426a2cf40cd5..a0c42ec02a88 100644 --- a/src/robot.ts +++ b/src/robot.ts @@ -1,8 +1,11 @@ import { filepaths } from "@fig/autocomplete-generators"; const tagsGenerator: Fig.Generator = { - script: + script: [ + "bash", + "-c", 'for i in $(find -E . -regex ".*.robot" -type f); do cat -s $i ; done', + ], postProcess: (out) => { // find all lines with tags // regex: line that starts with 2+ spaces, than '[Tags] ' and words @@ -34,10 +37,14 @@ const variablesGenerator: Fig.Generator = { const finalToken = tokens[tokens.length - 1]; const isKey = !finalToken.includes(":"); if (!isKey) return []; - const out = await executeShellCommand( - 'for i in $(find -E . -regex ".*.(robot|resource)" -type f); do cat -s $i ; done' - ); - const iter = out.matchAll(/^\$\{(.*?)\}/gm); + const { stdout } = await executeShellCommand({ + command: "bash", + args: [ + "-c", + 'for i in $(find -E . -regex ".*.(robot|resource)" -type f); do cat -s $i ; done', + ], + }); + const iter = stdout.matchAll(/^\$\{(.*?)\}/gm); return [...iter] .map((item) => item[1]) .map((variable) => ({ @@ -48,8 +55,11 @@ const variablesGenerator: Fig.Generator = { }; const testCasesGenerator: Fig.Generator = { - script: + script: [ + "bash", + "-c", 'for i in $(find -E . -regex ".*.robot" -type f); do cat -s $i ; done', + ], postProcess: (out) => { // find all parts of the code with test cases // regex: everything after '***Test Cases***' until '***???***') diff --git a/src/rugby.ts b/src/rugby.ts index 83e40e7ec754..93c70824c3d3 100644 --- a/src/rugby.ts +++ b/src/rugby.ts @@ -1,6 +1,6 @@ // Print plans list if there is .rugby/plans.yml file const planList: Fig.Generator = { - script: "rugby plan list", + script: ["rugby", "plan", "list"], postProcess: (output) => { if (output === "") { return []; @@ -21,14 +21,17 @@ const completionSpec: Fig.Spec = { "Cache Cocoa 🌱 pods for faster rebuild and indexing Xcode project. https://github.com/swiftyfinch/Rugby", name: "rugby", generateSpec: async (tokens, executeShellCommand) => { - const output = await executeShellCommand("rugby plan list"); - if (output === "") { + const { stdout } = await executeShellCommand({ + command: "rugby", + args: ["plan", "list"], + }); + if (stdout === "") { return null; } // Handle `rugby umbrella` command return { name: "plan", - subcommands: output.split("\n").map((plan) => { + subcommands: stdout.split("\n").map((plan) => { return { name: plan, description: `Run plan \"${plan}\"`, diff --git a/src/rush.ts b/src/rush.ts index 2a6d75b128a7..dece2fcfd7bf 100644 --- a/src/rush.ts +++ b/src/rush.ts @@ -8,8 +8,11 @@ interface IRushConfigurationJson { projects: IRushConfigurationProjectJson[]; } const projectGenerator: Fig.Generator = { - script: + script: [ + "bash", + "-c", "until [[ -f rush.json ]] || [[ $PWD = '/' ]]; do cd ..; done; cat rush.json", + ], postProcess: function (out: string) { const suggestions = []; diff --git a/src/rustup.ts b/src/rustup.ts index a2eb81c70b3d..5f861d56e8ae 100644 --- a/src/rustup.ts +++ b/src/rustup.ts @@ -6,7 +6,7 @@ type ToolchainLocalGeneratorOptions = { const toolchainLocalGenertor: ( args?: ToolchainLocalGeneratorOptions ) => Fig.Generator = ({ excludeShort } = {}) => ({ - script: "rustup toolchain list", + script: ["rustup", "toolchain", "list"], postProcess: (out) => { const toolchains = out .split("\n") @@ -29,12 +29,15 @@ const toolchainLocalGenertor: ( const toolchainAllGenerator: Fig.Generator = { // Grab the latest versions of rust from github, try the gh cli first as it has a higher rate limit - script: + script: [ + "bash", + "-c", 'if command -v gh > /dev/null; then \ gh api -H "Accept: application/vnd.github+json" /repos/rust-lang/rust/releases; \ else \ curl -sfL -H "Accept: application/vnd.github+json" https://api.github.com/repos/rust-lang/rust/releases; \ fi', + ], cache: { // 1 hour, the github api is rate limited per hour ttl: 60 * 60 * 1000, @@ -75,7 +78,7 @@ type TripleGeneratorOptions = { const tripleGenerator: (args?: TripleGeneratorOptions) => Fig.Generator = ({ installed, } = {}) => ({ - script: "rustup target list", + script: ["rustup", "target", "list"], postProcess: (data: string) => { return data .split("\n") @@ -690,7 +693,11 @@ const completionSpec: Fig.Spec = { description: "Topic such as 'core', 'fn', 'usize', 'eprintln!', 'core::arch', 'alloc::format!', 'std::fs', 'std::fs::read_dir', 'std::io::Bytes', 'std::iter::Sum', 'std::io::error::Result' etc", generators: { - script: `find $(rustup docs --path | sed -e "s|index\\.html|std|") $(rustup docs --path | sed -e "s|index\\.html|alloc|") $(rustup docs --path | sed -e "s|index\\.html|core|") | grep "\\.html" | sed -E -e "s|^(.*)/html/||" -e "s|\\.html||" -e "s|/|::|g" -e "s/constant\\.|trait\\.|struct\\.|macro\\.|fn\\.|keyword\\.|primitive\\.|type\\.|enum\\.|union\\.|traitalias\\.|::index$|^(.*)::all$//" -e "/^$/d"`, + script: [ + "bash", + "-c", + `find $(rustup docs --path | sed -e "s|index\\.html|std|") $(rustup docs --path | sed -e "s|index\\.html|alloc|") $(rustup docs --path | sed -e "s|index\\.html|core|") | grep "\\.html" | sed -E -e "s|^(.*)/html/||" -e "s|\\.html||" -e "s|/|::|g" -e "s/constant\\.|trait\\.|struct\\.|macro\\.|fn\\.|keyword\\.|primitive\\.|type\\.|enum\\.|union\\.|traitalias\\.|::index$|^(.*)::all$//" -e "/^$/d"`, + ], splitOn: "\n", }, }, @@ -880,10 +887,10 @@ const completionSpec: Fig.Spec = { isOptional: true, }, generateSpec: async (_tokens, executeShellCommand) => { - const [toolchainOutput] = await Promise.all([ - executeShellCommand("rustup toolchain list"), - ]); - + const { stdout: toolchainOutput } = await executeShellCommand({ + command: "rustup", + args: ["toolchain", "list"], + }); const toolchains: Fig.Option[] = toolchainOutput .split("\n") .map((toolchain) => { diff --git a/src/scarb.ts b/src/scarb.ts index bb5775f944d5..fdff1751d98d 100644 --- a/src/scarb.ts +++ b/src/scarb.ts @@ -29,7 +29,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; @@ -105,7 +111,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; @@ -145,7 +157,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; @@ -313,7 +331,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; @@ -477,7 +501,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; @@ -550,7 +580,13 @@ const completionSpec: Fig.Spec = { description: "Packages to run this command on, can be a concrete package name (`foobar`) or a prefix glob (`foo*`) [default: *]", generators: { - script: "scarb metadata --format-version 1 --no-deps", + script: [ + "scarb", + "metadata", + "--format-version", + "1", + "--no-deps", + ], postProcess: function (out) { const jsonOut = JSON.parse(out); const members = jsonOut.workspace.members; diff --git a/src/scc.ts b/src/scc.ts index 06bfc1da6ea6..3c75f420b27c 100644 --- a/src/scc.ts +++ b/src/scc.ts @@ -36,8 +36,12 @@ const generateLanguages: KeyValueSuggestions = async ( _, executeShellCommand ) => { - const out = await executeShellCommand("scc --language"); - const { languages } = processSccLanguages(out); + const { stdout } = await executeShellCommand({ + command: "scc", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--language"], + }); + const { languages } = processSccLanguages(stdout); return languages.map((language) => ({ name: language })); }; @@ -125,8 +129,12 @@ const completionSpec: Fig.Spec = { cache: true, separator: ":", keys: async (_, executeShellCommand) => { - const out = await executeShellCommand("scc --languages"); - const { extensions } = processSccLanguages(out); + const { stdout } = await executeShellCommand({ + command: "scc", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--language"], + }); + const { extensions } = processSccLanguages(stdout); return Object.entries(extensions).map(([extension, language]) => ({ name: extension, description: language, @@ -178,8 +186,12 @@ const completionSpec: Fig.Spec = { separator: ":", keys: suggestOutputFormats, values: async (_, executeShellCommand) => { - const out = await executeShellCommand("ls -lAF1"); - const suggestions: Fig.Suggestion[] = out + const { stdout } = await executeShellCommand({ + command: "ls", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["-lAF1"], + }); + const suggestions: Fig.Suggestion[] = stdout .split("\n") .map((path) => ({ name: path.slice(path.lastIndexOf("/") + 1), @@ -217,8 +229,12 @@ const completionSpec: Fig.Spec = { generators: valueList({ cache: true, values: async (_, executeShellCommand) => { - const out = await executeShellCommand("scc --languages"); - const { extensions } = processSccLanguages(out); + const { stdout } = await executeShellCommand({ + command: "scc", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--language"], + }); + const { extensions } = processSccLanguages(stdout); return Object.entries(extensions).map(([extension, language]) => ({ name: extension, description: language, diff --git a/src/serverless.ts b/src/serverless.ts index afc0e864b6a5..1507575e1c18 100644 --- a/src/serverless.ts +++ b/src/serverless.ts @@ -404,10 +404,12 @@ const completionSpec: Fig.Spec = { }, ], generateSpec: async (tokens, executeShellCommand) => { - const serverlessCompose = await executeShellCommand( - "cat serverless-compose.yml" - ); - const servicesObject = YAML.parse(serverlessCompose).services; + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["serverless-compose.yml"], + }); + const servicesObject = YAML.parse(stdout).services; const services: string[] = Object.keys(servicesObject); // Avoid infinite recursion of generated subcommands if (services.includes(tokens[0])) { diff --git a/src/shadcn-ui.ts b/src/shadcn-ui.ts index 80d97bb554b7..c2c8bafdbc22 100644 --- a/src/shadcn-ui.ts +++ b/src/shadcn-ui.ts @@ -7,10 +7,14 @@ interface RegistryItem { const componentGenerator: Fig.Generator = { custom: async (_tokens, executeShellCommand) => { - const json = await executeShellCommand( - `curl -sL 'https://raw.githubusercontent.com/shadcn/ui/main/apps/www/public/registry/index.json'` - ); - const components = JSON.parse(json) as RegistryItem[]; + const { stdout } = await executeShellCommand({ + command: "curl", + args: [ + "-sL", + "https://raw.githubusercontent.com/shadcn/ui/main/apps/www/public/registry/index.json", + ], + }); + const components = JSON.parse(stdout) as RegistryItem[]; return components.map((component) => ({ name: component.name, description: component.type, diff --git a/src/shopify/index.ts b/src/shopify/index.ts index 8ad3cd2c8eb5..b2ac44d5111b 100644 --- a/src/shopify/index.ts +++ b/src/shopify/index.ts @@ -4,7 +4,11 @@ export const getVersionCommand: Fig.GetVersionCommand = async ( executeShellCommand ) => { const versionRegex = /\d+\.\d+\.\d+/; - const out = await executeShellCommand("shopify version"); - return out.match(versionRegex)?.[0] ?? ""; + const { stdout } = await executeShellCommand({ + command: "shopify", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["version"], + }); + return stdout.match(versionRegex)?.[0] ?? ""; }; export default createVersionedSpec("shopify", versionFiles); diff --git a/src/shortcuts.ts b/src/shortcuts.ts index b03c44be9796..a73237030b5c 100644 --- a/src/shortcuts.ts +++ b/src/shortcuts.ts @@ -2,7 +2,7 @@ import { filepaths } from "@fig/autocomplete-generators"; const shortcut: Fig.Arg = { generators: { - script: "shortcuts list", + script: ["shortcuts", "list"], postProcess: (list) => list.split("\n").map((shortcut) => ({ name: shortcut, @@ -85,7 +85,7 @@ const subcommands: Fig.Subcommand[] = [ args: { name: "folder-name", generators: { - script: "shortcuts list --folders", + script: ["shortcuts", "list", "--folders"], postProcess: (list) => list.split("\n").map((folder) => ({ name: folder, diff --git a/src/snaplet.ts b/src/snaplet.ts index 4eca5ed10e09..7ff572a1b1e3 100644 --- a/src/snaplet.ts +++ b/src/snaplet.ts @@ -65,7 +65,7 @@ function parsePreviewDatabaseList(output: string): PreviewDatabase[] { } const snapshotsGenerator: Fig.Generator = { - script: "snaplet snapshot ls", + script: ["snaplet", "snapshot", "ls"], postProcess: (output) => { const result: Fig.Suggestion[] = []; const snapshotList = parseSnapshotList(output); @@ -83,7 +83,7 @@ const snapshotsGenerator: Fig.Generator = { // Only suggest successful snapshots on the cloud const snapshotsSuccessCloudGenerator: Fig.Generator = { - script: "snaplet snapshot ls", + script: ["snaplet", "snapshot", "ls"], postProcess: (output) => { const result: Fig.Suggestion[] = []; const snapshotList = parseSnapshotList(output).filter( @@ -102,7 +102,7 @@ const snapshotsSuccessCloudGenerator: Fig.Generator = { }; const databaseGenerator: Fig.Generator = { - script: "snaplet database ls", + script: ["snaplet", "database", "ls"], postProcess: (output) => { const result: Fig.Suggestion[] = []; const databases = parsePreviewDatabaseList(output); diff --git a/src/softwareupdate.ts b/src/softwareupdate.ts index 5d462ca807c8..647507fbb9c5 100644 --- a/src/softwareupdate.ts +++ b/src/softwareupdate.ts @@ -1,5 +1,5 @@ const updatesGenerator: Fig.Generator = { - script: "softwareupdate --list", + script: ["softwareupdate", "--list"], postProcess: (out) => { return out .split("\n") diff --git a/src/spring.ts b/src/spring.ts index 8a6d6973ce1d..44b9fbfb5f09 100644 --- a/src/spring.ts +++ b/src/spring.ts @@ -29,16 +29,23 @@ type Dependency = Option & { const memoizedFetchData = () => { let data: Data | undefined; return async ( - executeShellCommand: Fig.ExecuteShellCommandFunction + executeShellCommand: Fig.ExecuteCommandFunction ): Promise => { if (data) { return data; } try { - const query = `curl -sfL -H "Accept: application/json" "https://start.spring.io/metadata/client"`; - const response = await executeShellCommand(query); - data = JSON.parse(response); + const { stdout } = await executeShellCommand({ + command: "curl", + args: [ + "-sfL", + "-H", + "Accept: application/json", + "https://start.spring.io/metadata/client", + ], + }); + data = JSON.parse(stdout); return data; } catch (error) { return undefined; diff --git a/src/ssh.ts b/src/ssh.ts index 43550e214c4e..7b1be51a30fb 100644 --- a/src/ssh.ts +++ b/src/ssh.ts @@ -1,8 +1,12 @@ const knownHostRegex = /(?:[a-zA-Z0-9-]+\.)+[a-zA-Z0-9]+/; // will match numerical IPs as well as domains/subdomains -const resolveAbsolutePath = (path: string, basePath: string): string => { +const resolveAbsolutePath = ( + path: string, + basePath: string, + home: string +): string => { if (path.startsWith("/") || path.startsWith("~/") || path === "~") { - return path; + return path.replace("~", home); } return basePath + (basePath.endsWith("/") ? "" : "/") + path; @@ -10,13 +14,18 @@ const resolveAbsolutePath = (path: string, basePath: string): string => { const getConfigLines = async ( file: string, - executeShellCommand: Fig.ExecuteShellCommandFunction, - basePath + executeShellCommand: Fig.ExecuteCommandFunction, + home: string, + basePath: string ) => { - const absolutePath = resolveAbsolutePath(file, basePath); + const absolutePath = resolveAbsolutePath(file, basePath, home); - const out = await executeShellCommand(`cat ${absolutePath}`); - const configLines = out.split("\n").map((line) => line.trim()); + const { stdout } = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [absolutePath], + }); + const configLines = stdout.split("\n").map((line) => line.trim()); // Get list of includes in the config file const includes = configLines @@ -25,7 +34,9 @@ const getConfigLines = async ( // Get the lines of every include file const includeLines = await Promise.all( - includes.map((file) => getConfigLines(file, executeShellCommand, basePath)) + includes.map((file) => + getConfigLines(file, executeShellCommand, home, basePath) + ) ); // Combine config lines with includes config lines @@ -33,9 +44,14 @@ const getConfigLines = async ( }; export const knownHosts: Fig.Generator = { - script: "cat ~/.ssh/known_hosts", - postProcess: function (out, tokens) { - return out + custom: async (tokens, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${context.environmentVariables["HOME"]}/.ssh/known_hosts`], + }); + + return stdout .split("\n") .map((line) => { const match = knownHostRegex.exec(line); @@ -53,10 +69,11 @@ export const knownHosts: Fig.Generator = { }; export const configHosts: Fig.Generator = { - custom: async (tokens, executeShellCommand) => { + custom: async (tokens, executeShellCommand, context) => { const configLines = await getConfigLines( "config", executeShellCommand, + context.environmentVariables["HOME"], "~/.ssh" ); diff --git a/src/stepzen.ts b/src/stepzen.ts index fe5ea8b27473..4ce381dd6cb1 100644 --- a/src/stepzen.ts +++ b/src/stepzen.ts @@ -3,7 +3,7 @@ // Coded on stepzen/0.9.33 CLI version const endpointsGenerator: Fig.Generator = { - script: "stepzen list schemas", + script: ["stepzen", "list", "schemas"], postProcess: (output) => { try { return JSON.parse(output).map((endpoint: string) => { @@ -19,7 +19,10 @@ const endpointsGenerator: Fig.Generator = { }; const importSchemasGenerator: Fig.Generator = { - script: "curl https://api.github.com/repos/steprz/stepzen-schemas/contents", + script: [ + "curl", + "https://api.github.com/repos/steprz/stepzen-schemas/contents", + ], postProcess: (output) => { try { return JSON.parse(output) diff --git a/src/svtplay-dl.ts b/src/svtplay-dl.ts index b4ef148a267b..77927226be4e 100644 --- a/src/svtplay-dl.ts +++ b/src/svtplay-dl.ts @@ -1,6 +1,6 @@ const svtplayDlGenerators: Record = { listClipboard: { - script: "pbpaste", + script: ["pbpaste"], postProcess: function (out) { const regex = new RegExp( "^(https?://)?(www.)?(aftonbladet.se|dbtv.no|di.se|dn.se|dr.dk|efn.se|expressen.se|filmarkivet.se|flowonline.tv|nickelodeon.nl|nickelodeon.no|nickelodeon.se|nrk.se|oppetarkiv.se|pokemon.com|ruv.is|riksdagen.se|svd.se|sverigesradio.se|svtplay.se|viafree.se|viafree.no|viafree.dk|tv3play.ee|tv3play.it|tv3play.lv|tv4.se|tv4play.se|twitch.tv|ur.se|urplay.se|vg.no|viagame.com|viasat4play.no|viasatsport.se)/.+$" diff --git a/src/sysctl.ts b/src/sysctl.ts index 88a0f2be950f..d60f34c37d6e 100644 --- a/src/sysctl.ts +++ b/src/sysctl.ts @@ -1,5 +1,5 @@ const generateSysctlNames: Fig.Generator = { - script: "sysctl -A -N", + script: ["sysctl", "-A", "-N"], postProcess: (out) => { return out.split("\n").map((line) => { return { diff --git a/src/systemctl.ts b/src/systemctl.ts index d02dd6aa1f1f..2cd5af02dd0c 100644 --- a/src/systemctl.ts +++ b/src/systemctl.ts @@ -17,10 +17,18 @@ type Unit = { const unitGenerator: Fig.Generator = { custom: async (tokens, executeShellCommand) => { const user = tokens.includes("--user"); - const out = await executeShellCommand( - `systemctl list-units -o json --all --full ${user ? " --user" : ""}` - ); - const units: Unit[] = JSON.parse(out); + const { stdout } = await executeShellCommand({ + command: "systemctl", + args: [ + "list-units", + "-o", + "json", + "--all", + "--full", + ...(user ? ["--user"] : []), + ], + }); + const units: Unit[] = JSON.parse(stdout); const suggustions = units.map((unit) => { let activeEmoji: string; @@ -65,10 +73,18 @@ type UnitFile = { const unitFileGenerator: Fig.Generator = { custom: async (tokens, executeShellCommand) => { const user = tokens.includes("--user"); - const out = await executeShellCommand( - `systemctl list-unit-files -o json --all --full ${user ? " --user" : ""}` - ); - const units: UnitFile[] = JSON.parse(out); + const { stdout } = await executeShellCommand({ + command: "systemctl", + args: [ + "list-unit-files", + "-o", + "json", + "--all", + "--full", + ...(user ? ["--user"] : []), + ], + }); + const units: UnitFile[] = JSON.parse(stdout); const suggustions = units.map((unit) => { let loadedEmoji: string; if (unit.state === "enabled") { diff --git a/src/tailscale.ts b/src/tailscale.ts index c6be5e2f2705..0653d1965d1e 100644 --- a/src/tailscale.ts +++ b/src/tailscale.ts @@ -3,7 +3,7 @@ type HostsGeneratorOptions = { }; const hostsGenerator = ({ append }: HostsGeneratorOptions = {}) => ({ - script: "tailscale status --json", + script: ["tailscale", "status", "--json"], postProcess: (output: string) => Object.values(JSON.parse(output)["Peer"]).map((peer) => ({ name: `${peer["DNSName"].split(".")[0]}${append ?? ""}`, diff --git a/src/task.ts b/src/task.ts index a028f24821bc..57aa910fc0c2 100644 --- a/src/task.ts +++ b/src/task.ts @@ -5,8 +5,12 @@ const completionSpec: Fig.Spec = { name: "task", // loadSpec doesn't work for root commands (https://github.com/withfig/autocomplete/issues/223) generateSpec: async (_tokens, executeShellCommand) => { - const out = await executeShellCommand("task --version"); - return out.includes("Task") ? goTask : taskWarrior; + const { stdout } = await executeShellCommand({ + command: "task", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--version"], + }); + return stdout.includes("Task") ? goTask : taskWarrior; }, }; diff --git a/src/task/go-task.ts b/src/task/go-task.ts index d5ae7c75a8d2..8f5477932a72 100644 --- a/src/task/go-task.ts +++ b/src/task/go-task.ts @@ -3,7 +3,7 @@ const TASKFILE_FLAGS = ["-t", "--taskfile"]; const DIRECTORY_FLAGS = ["-d", "--dir"]; const tasksGenerator: Fig.Generator = { - script: "task -a", + script: ["task", "-a"], postProcess: (output) => { if (output.includes("task: No Taskfile found")) { return []; diff --git a/src/task/taskwarrior.ts b/src/task/taskwarrior.ts index 2a59224c56ec..206e5f20e101 100644 --- a/src/task/taskwarrior.ts +++ b/src/task/taskwarrior.ts @@ -234,9 +234,7 @@ const buildPrioritiesSuggestions = () => { // build the filter list with tasks const filtersWithTasks: Fig.Generator = { - script: function () { - return `task export`; - }, + script: ["task", "export"], postProcess: (output) => { const tasks = JSON.parse(output); const filters = [ @@ -253,9 +251,7 @@ const filtersWithTasks: Fig.Generator = { // build tasks list const listTasks: Fig.Generator = { - script: function (context) { - return `task export`; - }, + script: ["task", "export"], postProcess: (output) => { const tasks = JSON.parse(output); return buildTaskSuggestions(tasks); @@ -264,9 +260,7 @@ const listTasks: Fig.Generator = { // build filter suggestions const filters: Fig.Generator = { - script: function (context) { - return `task export`; - }, + script: ["task", "export"], postProcess: (output) => { const tasks = JSON.parse(output); const filters = [ @@ -282,9 +276,7 @@ const filters: Fig.Generator = { // build modifications suggestions const modifications: Fig.Generator = { - script: function (context) { - return `task export`; - }, + script: ["task", "export"], postProcess: (output) => { const tasks = JSON.parse(output); const filters = [ diff --git a/src/terraform.ts b/src/terraform.ts index 40f1b320bb5d..311ead39cc70 100644 --- a/src/terraform.ts +++ b/src/terraform.ts @@ -1,6 +1,6 @@ // If you edit commands or options, please copy our changes on to the terragrunt spec const workspaceList: Fig.Generator = { - script: "terraform workspace list", + script: ["terraform", "workspace", "list"], postProcess: function (out) { return out.split("\n").map((workspace) => { return { @@ -13,7 +13,7 @@ const workspaceList: Fig.Generator = { }; const addressList: Fig.Generator = { - script: "terraform state list", + script: ["terraform", "state", "list"], postProcess: function (out) { if (out.includes("No state file was found!") || out.includes("Error")) { return []; diff --git a/src/terragrunt.ts b/src/terragrunt.ts index c3e810bd0409..070afea7d957 100644 --- a/src/terragrunt.ts +++ b/src/terragrunt.ts @@ -1,7 +1,7 @@ // If you edit terraform commands or options, please copy our changes on to the terraform spec // ARGUMENTS json-out etc const workspaceList: Fig.Generator = { - script: "terragrunt workspace list", + script: ["terragrunt", "workspace", "list"], postProcess: function (out) { return out.split("\n").map((workspace) => { return { @@ -14,7 +14,7 @@ const workspaceList: Fig.Generator = { }; const addressList: Fig.Generator = { - script: "terragrunt state list", + script: ["terragrunt", "state", "list"], postProcess: function (out) { if (out.includes("No state file was found!") || out.includes("Error")) { return []; diff --git a/src/tfenv.ts b/src/tfenv.ts index 3733116da117..2cd1af765fc0 100644 --- a/src/tfenv.ts +++ b/src/tfenv.ts @@ -1,6 +1,6 @@ const generators: Record = { installedVersions: { - script: "tfenv list", + script: ["tfenv", "list"], postProcess: function (out) { return out.split("\n").map((tfversion) => { return { name: tfversion, description: "Version" }; @@ -8,7 +8,7 @@ const generators: Record = { }, }, allVersions: { - script: "tfenv list-remote", + script: ["tfenv", "list-remote"], postProcess: function (out) { return out.split("\n").map(function (line) { return { name: line, type: "option" }; diff --git a/src/tfsec.ts b/src/tfsec.ts index c8811cd1f19d..22e5ab9895b2 100644 --- a/src/tfsec.ts +++ b/src/tfsec.ts @@ -1,5 +1,5 @@ const workspaceGenerator: Fig.Generator = { - script: "terraform workspace list", + script: ["terraform", "workspace", "list"], postProcess: function (out) { return out.split("\n").map((workspace) => ({ name: workspace.replace("*", "").trim(), diff --git a/src/tldr.ts b/src/tldr.ts index e938aee2bcb6..2d960b59e473 100644 --- a/src/tldr.ts +++ b/src/tldr.ts @@ -9,11 +9,19 @@ const windows = `${tldrRc}/pages/windows/`; const isMarkDownRegex = new RegExp(/^.*\.md$/); const wholeTldrPages: Fig.Generator = { - script: () => { - return `command ls -Al ${android} ${common} ${linux} ${osx} ${sunos} ${windows} 2>/dev/null`; - }, - postProcess: (out) => { - return out + custom: async (tokens, executeShellCommand, context) => { + const { stdout } = await executeShellCommand({ + command: "ls", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [ + "-Al", + ...[android, common, linux, osx, sunos, windows].map((path) => + path.replace(/^~/, context.environmentVariables["HOME"]) + ), + ], + }); + + return stdout .split("\n") .filter((line) => isMarkDownRegex.test(line)) .map((line) => { @@ -27,9 +35,7 @@ const wholeTldrPages: Fig.Generator = { }; const linuxTldrPages: Fig.Generator = { - script: () => { - return `command ls -Al ${linux} 2>/dev/null`; - }, + script: ["bash", "-c", `command ls -Al ${linux} 2>/dev/null`], postProcess: (out) => { return out .split("\n") @@ -45,9 +51,7 @@ const linuxTldrPages: Fig.Generator = { }; const osxTldrPages: Fig.Generator = { - script: () => { - return `command ls -l ${osx} 2>/dev/null`; - }, + script: ["bash", "-c", `command ls -l ${osx} 2>/dev/null`], postProcess: (out) => { return out .split("\n") @@ -63,9 +67,7 @@ const osxTldrPages: Fig.Generator = { }; const sunosTldrPages: Fig.Generator = { - script: () => { - return `command ls -l ${sunos} 2>/dev/null`; - }, + script: ["bash", "-c", `command ls -l ${sunos} 2>/dev/null`], postProcess: (out) => { return out .split("\n") diff --git a/src/tmux.ts b/src/tmux.ts index ed3a9f639b5c..6dad63129303 100644 --- a/src/tmux.ts +++ b/src/tmux.ts @@ -1,7 +1,7 @@ const lsArg = (name: string, command: string): Fig.Arg => ({ name, generators: { - script: `tmux ${command}`, + script: ["tmux", command], postProcess: (out) => { return out.split("\n").map((line) => { const content = line.split(":"); diff --git a/src/tmuxinator.ts b/src/tmuxinator.ts index bdd8150d89e1..8ae545984ea8 100644 --- a/src/tmuxinator.ts +++ b/src/tmuxinator.ts @@ -1,5 +1,5 @@ const projects: Fig.Generator = { - script: "tmuxinator list -n", + script: ["tmuxinator", "list", "-n"], postProcess: (output) => { if (output.startsWith("fatal:")) { return []; @@ -17,7 +17,7 @@ const projects: Fig.Generator = { }; const tmuxsessions: Fig.Generator = { - script: "tmux ls", + script: ["tmux", "ls"], postProcess: (output) => { if (output.startsWith("fatal:")) { return []; diff --git a/src/tokei.ts b/src/tokei.ts index 2775cdf8232b..065b0c344c24 100644 --- a/src/tokei.ts +++ b/src/tokei.ts @@ -1,5 +1,5 @@ const languageGenerator: Fig.Generator = { - script: "tokei --languages", + script: ["tokei", "--languages"], splitOn: "\n", }; diff --git a/src/trap.ts b/src/trap.ts index 53a2f4813e74..139132d43209 100644 --- a/src/trap.ts +++ b/src/trap.ts @@ -11,7 +11,7 @@ const re = /(\d+\)\s)?([\w-+]+)/g; const availableSignalsGenerator = ( suggestOptions?: Partial ): Fig.Generator => ({ - script: "command kill -l", + script: ["command", "kill", "-l"], postProcess: (output) => [...output.matchAll(re)].map((signal) => ({ name: signal[2], diff --git a/src/trex.ts b/src/trex.ts index 44bd805926da..af7e6c752a6a 100644 --- a/src/trex.ts +++ b/src/trex.ts @@ -1,5 +1,5 @@ const dependenciesGenerator: Fig.Generator = { - script: "cat import_map.json", + script: ["cat", "import_map.json"], postProcess: function (out) { if (out) { try { @@ -24,7 +24,7 @@ const dependenciesGenerator: Fig.Generator = { }, }; const scriptsGenerator: Fig.Generator = { - script: "cat run.json", + script: ["cat", "run.json"], postProcess: function (out) { if (out) { try { diff --git a/src/tsh.ts b/src/tsh.ts index 42b02b1a5c79..7efc7e047527 100644 --- a/src/tsh.ts +++ b/src/tsh.ts @@ -8,7 +8,7 @@ const globalOptions: Fig.Option[] = [ args: { name: "Teleport proxy address", generators: { - script: "tsh clusters --format=json", + script: ["tsh", "clusters", "--format=json"], postProcess: (out) => JSON.parse(out).map((elm) => elm.cluster_name), }, }, @@ -19,7 +19,7 @@ const globalOptions: Fig.Option[] = [ args: { name: "user", generators: { - script: "tsh status --format json", + script: ["tsh", "status", "--format", "json"], postProcess: (out) => [JSON.parse(out).active.username], }, }, @@ -93,7 +93,7 @@ const completionSpec: Fig.Spec = { name: "user@hostname", description: "Address of remote machine to log into", generators: { - script: "tsh ls --format=json", + script: ["tsh", "ls", "--format=json"], postProcess: (out) => { return JSON.parse(out).map((elm) => { return { diff --git a/src/tsuru.ts b/src/tsuru.ts index a0fb15233c71..8f01c73a8f6c 100644 --- a/src/tsuru.ts +++ b/src/tsuru.ts @@ -8,7 +8,7 @@ const formatTsuruOutput = (output: string) => { const tsuruGenerators: Record = { plans: { - script: "tsuru plan list", + script: ["tsuru", "plan", "list"], postProcess: function (out) { const plans = formatTsuruOutput(out); return plans.map((plan) => { @@ -18,7 +18,7 @@ const tsuruGenerators: Record = { }, teams: { - script: "tsuru team list", + script: ["tsuru", "team", "list"], postProcess: function (out) { const teams = formatTsuruOutput(out); return teams.map((team) => { @@ -28,7 +28,7 @@ const tsuruGenerators: Record = { }, apps: { - script: "tsuru app list", + script: ["tsuru", "app", "list"], postProcess: function (out) { const apps = formatTsuruOutput(out); return apps.map((app) => { @@ -38,7 +38,7 @@ const tsuruGenerators: Record = { }, platforms: { - script: "tsuru platform list", + script: ["tsuru", "platform", "list"], postProcess: function (out) { return out .split("\n") @@ -50,7 +50,7 @@ const tsuruGenerators: Record = { }, pools: { - script: "tsuru pool list", + script: ["tsuru", "pool", "list"], postProcess: function (out) { const pools = formatTsuruOutput(out); return pools.map((pool) => { diff --git a/src/turbo.ts b/src/turbo.ts index 6c9f9e3524bc..9757208a451d 100644 --- a/src/turbo.ts +++ b/src/turbo.ts @@ -98,8 +98,11 @@ const completionSpec: Fig.Spec = { name: "tasks", isVariadic: true, generators: { - script: + script: [ + "bash", + "-c", "until [[ ( -f turbo.json || $PWD = '/' ) ]]; do cd ..; done; cat turbo.json", + ], postProcess: (out) => { let turbo: TurboJSON; try { diff --git a/src/unset.ts b/src/unset.ts index 2f0520f940da..ef53a673a3a7 100644 --- a/src/unset.ts +++ b/src/unset.ts @@ -1,5 +1,5 @@ const environmentVariableGenerator: Fig.Generator = { - script: "env", + script: ["env"], postProcess: (out) => out.length === 0 ? [] diff --git a/src/v.ts b/src/v.ts index 15c2b1d9121c..4fabb6bc5365 100644 --- a/src/v.ts +++ b/src/v.ts @@ -100,7 +100,7 @@ const completionSpec: Fig.Spec = { description: "Display help for V", args: { generators: { - script: "v help topics", + script: ["v", "help", "topics"], postProcess: (out) => { return out .trim() diff --git a/src/valet.ts b/src/valet.ts index 40da10f2bcb1..01c8dd2208c0 100644 --- a/src/valet.ts +++ b/src/valet.ts @@ -161,7 +161,7 @@ const completionSpec: Fig.Spec = { args: { name: "command", generators: { - script: "valet list --raw", + script: ["valet", "list", "--raw"], postProcess: function (out) { return out.split("\n").map((command) => { const name = command.split(" ")[0]; diff --git a/src/vercel.ts b/src/vercel.ts index 8437c6f14e5d..b18a8635b337 100644 --- a/src/vercel.ts +++ b/src/vercel.ts @@ -1,5 +1,5 @@ const envVarList: Fig.Generator = { - script: "vercel env ls", + script: ["vercel", "env", "ls"], postProcess: function (out) { const lines = out.split("\n"); const envList = []; @@ -13,26 +13,8 @@ const envVarList: Fig.Generator = { }, }; -//Unfinished -const deploymentList: Fig.Generator = { - //Grabs all the deployments for - script: "vercel list [project name]", - postProcess: function (out) { - const lines = out.split("\n"); - const deploymentUrlList = []; - for (let i = 4; i < lines.length; i++) { - const deploymentUrl = lines[i].match(/\S+/g)[1]; - deploymentUrlList.push({ - name: deploymentUrl, - icon: "🔗", - }); - } - return deploymentUrlList; - }, -}; - const domainList = { - script: "vercel domains", + script: ["vercel", "domains"], postProcess: function (out) { const lines = out.split("\n"); const domainList = []; @@ -47,7 +29,7 @@ const domainList = { }; const teamList: Fig.Generator = { - script: "vercel teams list", + script: ["vercel", "teams", "list"], postProcess: function (out) { const lines = out.split("\n"); const teamList = []; diff --git a/src/vite.ts b/src/vite.ts index 48b8f1c84c19..6f9950834bf6 100644 --- a/src/vite.ts +++ b/src/vite.ts @@ -109,8 +109,14 @@ const completionSpec: Fig.Spec = { args: { name: "mode", generators: { - script: "\\ls -l1A.env.*", - splitOn: "\n", + script: ["ls", "-l1A"], + postProcess: (out) => + out + .split("\n") + .filter((line) => line.startsWith(".env.")) + .map((name) => ({ + name, + })), }, }, }, diff --git a/src/vr.ts b/src/vr.ts index 7ab1a16de61a..617ce10ab5cc 100644 --- a/src/vr.ts +++ b/src/vr.ts @@ -4,7 +4,14 @@ const scriptGenerator: Fig.Generator = { cache: { strategy: "stale-while-revalidate", }, - script: "NO_COLOR=1 vr", + script: { + command: "vr", + // eslint-disable-next-line @withfig/fig-linter/no-empty-array-values + args: [], + env: { + NO_COLOR: "1", + }, + }, postProcess: (out) => { const suggestions: Fig.Suggestion[] = []; diff --git a/src/vsce.ts b/src/vsce.ts index 5097aff4e68d..3e69a96d0457 100644 --- a/src/vsce.ts +++ b/src/vsce.ts @@ -17,7 +17,7 @@ const targetSuggestions: string[] = [ // NOTE: Running `vsce ls-publishers` requires access to keychain of `vscode-vsce` // which distracts the completion and needs to "Allow always" the access of it to work well. // const publishersGenerator: Fig.Generator = { -// script: "vsce ls-publishers", +// script: ["vsce", "ls-publishers"], // postProcess: (out) => { // if (out.trim() === "") return []; // return out.split("\n").map((publisher) => ({ diff --git a/src/vultr-cli.ts b/src/vultr-cli.ts index 41dd0ce4b4f2..9e69ae2f5871 100644 --- a/src/vultr-cli.ts +++ b/src/vultr-cli.ts @@ -9,7 +9,7 @@ const backupIdArg: Fig.Arg = { const instance: Fig.Arg = { name: "instanceID", generators: { - script: "vultr-cli instance list", + script: ["vultr-cli", "instance", "list"], postProcess: (lines) => lines .split("\n") diff --git a/src/watson.ts b/src/watson.ts index 632c64e0d59b..bb6ff8575de7 100644 --- a/src/watson.ts +++ b/src/watson.ts @@ -1,6 +1,6 @@ // https://tailordev.github.io/Watson/ const listProjects: Fig.Generator = { - script: `watson projects`, + script: ["watson", "projects"], postProcess: (output) => { return output.split("\n").map((project) => ({ name: project, @@ -10,7 +10,7 @@ const listProjects: Fig.Generator = { }; const listTags: Fig.Generator = { - script: `watson tags`, + script: ["watson", "tags"], postProcess: (output) => { return output.split("\n").map((tag) => ({ name: tag, @@ -20,7 +20,7 @@ const listTags: Fig.Generator = { }; const listFrames: Fig.Generator = { - script: `watson log --json --reverse`, + script: ["watson", "log", "--json", "--reverse"], postProcess: (output) => { return JSON.parse(output).map((frame) => ({ name: frame.id.substring(0, 7), diff --git a/src/wd.ts b/src/wd.ts index 377763c23d77..0c1cd379a775 100644 --- a/src/wd.ts +++ b/src/wd.ts @@ -1,8 +1,13 @@ const warpPointsGenerator: Fig.Generator = { - script: "cat ~/.warprc", - postProcess: (out) => { + custom: async (_, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${context.environmentVariables["HOME"]}/.warprc`], + }); + // find all warp points names - const iter = out.matchAll(/^(\w+)/gm); + const iter = stdout.matchAll(/^(\w+)/gm); const suggestions: Fig.Suggestion[] = []; diff --git a/src/which.ts b/src/which.ts index 29b872c0c991..a32154a4f2b7 100644 --- a/src/which.ts +++ b/src/which.ts @@ -1,5 +1,9 @@ const programGenerator: Fig.Generator = { - script: `for i in $(echo $PATH | tr ":" "\n"); do find $i -maxdepth 1 -perm -111 -type f; done`, + script: [ + "bash", + "-c", + `for i in $(echo $PATH | tr ":" "\n"); do find $i -maxdepth 1 -perm -111 -type f; done`, + ], postProcess: (out) => out .split("\n") diff --git a/src/wifi-password.ts b/src/wifi-password.ts index ac1adbd98aaf..d0a27a0981f4 100644 --- a/src/wifi-password.ts +++ b/src/wifi-password.ts @@ -4,8 +4,11 @@ const completionSpec: Fig.Spec = { name: "SSID", description: "The name for a Wi-Fi network", generators: { - script: + script: [ + "bash", + "-c", "networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $2}' | xargs networksetup -listpreferredwirelessnetworks", + ], postProcess: (out) => out .split("\n") diff --git a/src/xc.ts b/src/xc.ts index f1cceb840ffd..4f04ca5186eb 100644 --- a/src/xc.ts +++ b/src/xc.ts @@ -30,8 +30,12 @@ const completionSpec: Fig.Spec = { description: 'Specify the heading for xc tasks (default: "Tasks")', }, ]; - const out = await executeShellCommand("xc"); - const subcommands: Fig.Subcommand[] = out + const { stdout } = await executeShellCommand({ + command: "xc", + // eslint-disable-next-line @withfig/fig-linter/no-empty-array-values + args: [], + }); + const subcommands: Fig.Subcommand[] = stdout .trim() .split("\n") .map((line) => diff --git a/src/xcodes.ts b/src/xcodes.ts index 40e9147b6912..9cade074a320 100644 --- a/src/xcodes.ts +++ b/src/xcodes.ts @@ -15,12 +15,12 @@ const processXcodeList = (out: string, tokens: string[]) => })); const allXcodes: Fig.Generator = { - script: "xcodes list", + script: ["xcodes", "list"], postProcess: processXcodeList, }; const installedXcodes: Fig.Generator = { - script: "xcodes installed", + script: ["xcodes", "installed"], postProcess: processXcodeList, }; diff --git a/src/yalc.ts b/src/yalc.ts index 0bb01c9a1594..0a0430beef7f 100644 --- a/src/yalc.ts +++ b/src/yalc.ts @@ -1,6 +1,10 @@ const generatePackages: Fig.Generator = { // TODO: use the same as for npm and yarn package.json reverse lookup - script: "command find ~/.yalc/packages -maxdepth 4 -iname 'package.json'", + script: [ + "bash", + "-c", + "command find ~/.yalc/packages -maxdepth 4 -iname 'package.json'", + ], postProcess: (out) => out .split("\n") @@ -21,7 +25,7 @@ const generatePackages: Fig.Generator = { }; const getRemovablePackages: Fig.Generator = { - script: "command ls .yalc", + script: ["ls", ".yalc"], postProcess: (out) => out.split("\n").map((path) => ({ name: path, diff --git a/src/yarn.ts b/src/yarn.ts index fba8c9adea83..0d667bfda0a4 100644 --- a/src/yarn.ts +++ b/src/yarn.ts @@ -2,8 +2,20 @@ import { npmScriptsGenerator, npmSearchGenerator } from "./npm"; export const yarnScriptParserDirectives: Fig.Arg["parserDirectives"] = { alias: async (token, executeShellCommand) => { - const out = await executeShellCommand("cat $(npm prefix)/package.json"); - const script: string = JSON.parse(out).scripts?.[token]; + const npmPrefix = await executeShellCommand({ + command: "npm", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["prefix"], + }); + if (npmPrefix.status !== 0) { + throw new Error("npm prefix command failed"); + } + const packageJson = await executeShellCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${npmPrefix.stdout.trim()}/package.json`], + }); + const script: string = JSON.parse(packageJson.stdout).scripts?.[token]; if (!script) { throw new Error(`Script not found: '${token}'`); } @@ -39,12 +51,22 @@ export const nodeClis = new Set([ // generate global package list from global package.json file const getGlobalPackagesGenerator: Fig.Generator = { - script: 'cat "$(yarn global dir)/package.json"', - postProcess: (out, tokens) => { - if (out.trim() == "") return []; + custom: async (tokens, executeCommand, generatorContext) => { + const { stdout: yarnGlobalDir } = await executeCommand({ + command: "yarn", + args: ["global", "dir"], + }); + + const { stdout } = await executeCommand({ + command: "cat", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: [`${yarnGlobalDir.trim()}/package.json`], + }); + + if (stdout.trim() == "") return []; try { - const packageContent = JSON.parse(out); + const packageContent = JSON.parse(stdout); const dependencyScripts = packageContent["dependencies"] || {}; const devDependencyScripts = packageContent["devDependencies"] || {}; const dependencies = [ @@ -68,7 +90,7 @@ const getGlobalPackagesGenerator: Fig.Generator = { // generate package list of direct and indirect dependencies const allDependenciesGenerator: Fig.Generator = { - script: "yarn list --depth=0 --json", + script: ["yarn", "list", "--depth=0", "--json"], postProcess: (out) => { if (out.trim() == "") return []; @@ -85,7 +107,7 @@ const allDependenciesGenerator: Fig.Generator = { }; const configList: Fig.Generator = { - script: "yarn config list", + script: ["yarn", "config", "list"], postProcess: function (out) { if (out.trim() == "") { return []; @@ -112,8 +134,11 @@ const configList: Fig.Generator = { }; export const dependenciesGenerator: Fig.Generator = { - script: + script: [ + "bash", + "-c", "until [[ -f package.json ]] || [[ $PWD = '/' ]]; do cd ..; done; cat package.json", + ], postProcess: function (out, context = []) { if (out.trim() === "") { return []; @@ -326,9 +351,15 @@ const commonOptions: Fig.Option[] = [ export const createCLIsGenerator: Fig.Generator = { script: function (context) { - if (context[context.length - 1] === "") return ""; + if (context[context.length - 1] === "") return undefined; const searchTerm = "create-" + context[context.length - 1]; - return `curl -s -H "Accept: application/json" "https://api.npms.io/v2/search?q=${searchTerm}&size=20"`; + return [ + "curl", + "-s", + "-H", + "Accept: application/json", + `https://api.npms.io/v2/search?q=${searchTerm}&size=20`, + ]; }, cache: { ttl: 100 * 24 * 60 * 60 * 3, // 3 days @@ -353,10 +384,14 @@ const completionSpec: Fig.Spec = { description: "Manage packages and run scripts", generateSpec: async (tokens, executeShellCommand) => { const binaries = ( - await executeShellCommand( - `until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/` - ) - ).split("\n"); + await executeShellCommand({ + command: "bash", + args: [ + "-c", + `until [[ -d node_modules/ ]] || [[ $PWD = '/' ]]; do cd ..; done; ls -1 node_modules/.bin/`, + ], + }) + ).stdout.split("\n"); const subcommands = binaries .filter((name) => nodeClis.has(name)) @@ -1471,17 +1506,26 @@ const completionSpec: Fig.Spec = { description: "Manage workspace", filterStrategy: "fuzzy", generateSpec: async (_tokens, executeShellCommand) => { - const version = await executeShellCommand("yarn --version"); + const version = ( + await executeShellCommand({ + command: "yarn", + // eslint-disable-next-line @withfig/fig-linter/no-useless-arrays + args: ["--version"], + }) + ).stdout; const isYarnV1 = version.startsWith("1."); const getWorkspacesDefinitionsV1 = async () => { - const out = await executeShellCommand(`yarn workspaces info`); + const { stdout } = await executeShellCommand({ + command: "yarn", + args: ["workspaces", "info"], + }); - const startJson = out.indexOf("{"); - const endJson = out.lastIndexOf("}"); + const startJson = stdout.indexOf("{"); + const endJson = stdout.lastIndexOf("}"); return Object.entries( - JSON.parse(out.slice(startJson, endJson + 1)) as Record< + JSON.parse(stdout.slice(startJson, endJson + 1)) as Record< string, { location: string } > @@ -1493,7 +1537,13 @@ const completionSpec: Fig.Spec = { // For yarn >= 2.0.0 const getWorkspacesDefinitionsVOther = async () => { - const out = await executeShellCommand(`yarn workspaces list --json`); + // yarn workspaces list --json + const out = ( + await executeShellCommand({ + command: "yarn", + args: ["workspaces", "list", "--json"], + }) + ).stdout; return out.split("\n").map((line) => JSON.parse(line.trim())); }; @@ -1515,7 +1565,7 @@ const completionSpec: Fig.Spec = { strategy: "stale-while-revalidate", ttl: 60_000, // 60s }, - script: `\\cat ${location}/package.json`, + script: ["cat", `${location}/package.json`], postProcess: function (out: string) { if (out.trim() == "") { return []; diff --git a/src/ykman.ts b/src/ykman.ts index 4bbdb0748f1d..813eedfee972 100644 --- a/src/ykman.ts +++ b/src/ykman.ts @@ -2439,7 +2439,11 @@ const completionSpec: Fig.Spec = { args: { name: "SERIAL", generators: { - script: "ykman list | sed -rn 's/.*Serial: (.*)/\\1/p'", + script: [ + "bash", + "-c", + "ykman list | sed -rn 's/.*Serial: (.*)/\\1/p'", + ], postProcess: function (out) { return out.split("\n").map((serial) => { return { name: serial, description: "Yubikey serial" }; @@ -2456,7 +2460,7 @@ const completionSpec: Fig.Spec = { args: { name: "NAME", generators: { - script: "ykman list --readers", + script: ["ykman", "list", "--readers"], postProcess: function (out) { return out.split("\n").map((readerName) => { return { name: readerName, description: "Yubikey name" }; diff --git a/src/yo.ts b/src/yo.ts index 1ce389ab6b4f..0e905eb40af8 100644 --- a/src/yo.ts +++ b/src/yo.ts @@ -22,7 +22,7 @@ const suggestions: Fig.Suggestion[] = [ // GENERATORS const yeomanGeneratorList: Fig.Generator = { - script: "yo --generators", + script: ["yo", "--generators"], postProcess: function (out) { try { return out diff --git a/src/youtube-dl.ts b/src/youtube-dl.ts index 7518168d91f1..fc574665f4ab 100644 --- a/src/youtube-dl.ts +++ b/src/youtube-dl.ts @@ -1,9 +1,11 @@ const youtubeDlGenerators: Record = { listVideos: { - script: (context) => - `youtube-dl --flat-playlist -J ${context.filter((token) => - token.includes("youtube.") - )}`, + script: (context) => [ + "youtube-dl", + "--flat-playlist", + "-J", + ...context.filter((token) => token.includes("youtube.")), + ], postProcess: function (out) { try { @@ -23,7 +25,7 @@ const youtubeDlGenerators: Record = { }, listClipboard: { - script: "pbpaste", + script: ["pbpaste"], postProcess: function (out) { const regex = new RegExp( "^(https?://)?(www.)?(youtube.com|youtu.?be)/.+$" @@ -941,20 +943,27 @@ const completionSpec: Fig.Spec = { args: { name: "MSO", generators: { - script: (context) => - `youtube-dl ${context.filter((token) => - token.includes("youtube.") - )} --simulate --ap-list-mso | tail -n +3 | tr -s " "`, + custom: async (tokens, executeCommand, context) => { + const { stdout } = await executeCommand({ + command: "youtube-dl", + args: [ + ...tokens.filter((token) => token.includes("youtube.")), + "--simulate", + "--ap-list-mso", + ], + }); - postProcess: (out) => - out.split("\n").map((line) => { - const [name, ...description] = line.split(" "); - - return { - name, - description: description.join(" "), - }; - }), + return stdout + .split("\n") + .slice(3) + .map((line) => { + const [name, ...description] = line.split(" "); + return { + name, + description: description.join(" "), + }; + }); + }, }, }, }, diff --git a/src/z.ts b/src/z.ts index 7115c965768d..e170aaa30d6a 100644 --- a/src/z.ts +++ b/src/z.ts @@ -6,10 +6,13 @@ interface ZSuggestion { } async function getZHistory( - execute: Fig.ExecuteShellCommandFunction + execute: Fig.ExecuteCommandFunction ): Promise { - const out = await execute("cat ${${ZSHZ_DATA:-${_Z_DATA:-${HOME}/.z}}:A}"); - return out.split("\n").map((line) => { + const { stdout } = await execute({ + command: "zsh", + args: ["-c", "cat ${${ZSHZ_DATA:-${_Z_DATA:-${HOME}/.z}}:A}"], + }); + return stdout.split("\n").map((line) => { const [path, weight, time] = line.split("|"); const splitPath = path.split("/"); const name = splitPath[splitPath.length - 1]; @@ -27,10 +30,13 @@ async function getZHistory( async function getCurrentDirectoryFolders( currentWorkingDirectory: string, - execute: Fig.ExecuteShellCommandFunction + execute: Fig.ExecuteCommandFunction ): Promise { - const out = await execute("ls -d */"); - return out.split("\n").map((line) => { + const { stdout } = await execute({ + command: "bash", + args: ["-c", "ls -d */"], + }); + return stdout.split("\n").map((line) => { const name = line.replace("/", ""); return { name, @@ -122,20 +128,25 @@ const zoxideCompletionSpec: Fig.Spec = { isVariadic: true, generators: { custom: async (tokens, executeShellCommand) => { - console.log(tokens); - let command; + let args; if (tokens.length < 2 || tokens[1] === "") { - command = "zoxide query --list --score"; + args = ["query", "--list", "--score"]; } else { - command = `zoxide query --list --score -- ${tokens - .slice(1) - .join(" ")}`; + args = [ + "query", + "--list", + "--score", + "--", + tokens.slice(1).join(" "), + ]; } - console.log(command); - const out = await executeShellCommand(command); + const { stdout } = await executeShellCommand({ + command: "zoxide", + args, + }); - return out.split("\n").map((line) => { + return stdout.split("\n").map((line) => { const trimmedLine = line.trim(); const spaceIndex = trimmedLine.indexOf(" "); const score = Number(trimmedLine.slice(0, spaceIndex)); @@ -158,8 +169,11 @@ const zCompletionSpec: Fig.Spec = { generateSpec: async (_, executeShellCommand) => { // Assume if zoxide is installed, use that completion spec try { - const zoxideInstalled = await executeShellCommand("command -v zoxide"); - if (zoxideInstalled.length > 0) { + const { status } = await executeShellCommand({ + command: "bash", + args: ["-c", "command -v zoxide"], + }); + if (status === 0) { return zoxideCompletionSpec; } } catch (_) {} diff --git a/src/zellij.ts b/src/zellij.ts index 450465cb1fb3..6594774b3115 100644 --- a/src/zellij.ts +++ b/src/zellij.ts @@ -1,5 +1,5 @@ const generateSessions: Fig.Generator = { - script: "zellij list-sessions", + script: ["zellij", "list-sessions"], splitOn: "\n", }; diff --git a/yarn.lock b/yarn.lock index abd9aa0d4692..f8d78b7ede22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -732,10 +732,10 @@ __metadata: languageName: node linkType: hard -"@fig/autocomplete-generators@npm:^2.2.5": - version: 2.2.5 - resolution: "@fig/autocomplete-generators@npm:2.2.5" - checksum: 6744eef510dd4c11ce20fcf8285eb173ae2a5f185c4c04a002e24bb0766e036af30938d07df2f52d3756973e86c5bbc1e363c9a71f91c5b507349f2ed7e3c9a7 +"@fig/autocomplete-generators@npm:^2.3.0": + version: 2.3.0 + resolution: "@fig/autocomplete-generators@npm:2.3.0" + checksum: d2b6be2972c59fc9ea9828c84882650bea4b457dc8abe96b9a127458d923c04411f8a242a8b5e75f53ca2011503610fc8141b1b7ad8bea016f31290aa4685f67 languageName: node linkType: hard @@ -1880,10 +1880,10 @@ __metadata: languageName: node linkType: hard -"@withfig/autocomplete-types@npm:^1.28.0": - version: 1.28.0 - resolution: "@withfig/autocomplete-types@npm:1.28.0" - checksum: ca69f69c4299356b5ef5c1c5c88ac8244773b4a600e616227b7c63c8dc4fe6e5ddb6a6c72d6d70e9296bc870462930b53c28efacb1b6d78e14876a5720527226 +"@withfig/autocomplete-types@npm:^1.29.0": + version: 1.29.0 + resolution: "@withfig/autocomplete-types@npm:1.29.0" + checksum: 714b960c1e4a464e652fa72722d5927cb677f27a0528f5545bb4ebceab885c7035bc89f261450677356708b9455ad802a395d262909475983b64c59229f991e5 languageName: node linkType: hard @@ -1891,7 +1891,7 @@ __metadata: version: 0.0.0-use.local resolution: "@withfig/autocomplete@workspace:." dependencies: - "@fig/autocomplete-generators": ^2.2.5 + "@fig/autocomplete-generators": ^2.3.0 "@fig/autocomplete-helpers": ^1.0.7 "@fig/autocomplete-hooks": ^1.0.2 "@fig/eslint-config-autocomplete": ^1.2.1 @@ -1904,7 +1904,7 @@ __metadata: "@vitejs/plugin-react": ^4.1.0 "@withfig/api-bindings": ^0.30.3 "@withfig/autocomplete-tools": ^2.7.10 - "@withfig/autocomplete-types": ^1.28.0 + "@withfig/autocomplete-types": ^1.29.0 autoprefixer: ^10.4.16 chalk: ^5.3.0 chokidar: ^3.5.3 From 8256af79a4811d84632dcc3c980bb814c26fa871 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Mon, 6 Nov 2023 23:40:14 +0000 Subject: [PATCH 50/81] ci: version bump to 2.640.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1b8041c0fee2..aa8ba77c7be1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.640.2", + "version": "2.640.3", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 73ba7a64794aecd02ad8dfec113a03f713b98dec Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Thu, 9 Nov 2023 08:22:28 -0800 Subject: [PATCH 51/81] @eltociear has signed the CLA in withfig/autocomplete#2166 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index d74f90e13a72..02b5d78df05a 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1031,6 +1031,14 @@ "created_at": "2023-11-05T12:48:53Z", "repoId": 299482335, "pullRequestNo": 1666 + }, + { + "name": "eltociear", + "id": 22633385, + "comment_id": 1804145442, + "created_at": "2023-11-09T16:22:10Z", + "repoId": 299482335, + "pullRequestNo": 2166 } ] } \ No newline at end of file From 26243c9f1213f07478cfd3a66ca5e2d39748df02 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 10 Nov 2023 03:52:29 +0900 Subject: [PATCH 52/81] docs: Update README.md (#2166) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfe75271a4d9..db3fc12b74e8 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Use the steps below or follow our getting started guide: [fig.io/docs](https://f 3. Clone your forked repo and create an example spec ```bash - # Replace `YOUR_GITHUB_USERNAME` with your own github username + # Replace `YOUR_GITHUB_USERNAME` with your own GitHub username git clone https://github.com/YOUR_GITHUB_USERNAME/autocomplete.git fig-autocomplete cd fig-autocomplete From 30756c06f4402bb4eb66f8ecaf45127a21a34cd0 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Thu, 9 Nov 2023 17:04:58 -0800 Subject: [PATCH 53/81] @casseyshao has signed the CLA in withfig/autocomplete#2167 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 02b5d78df05a..38d3ad262d79 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1039,6 +1039,14 @@ "created_at": "2023-11-09T16:22:10Z", "repoId": 299482335, "pullRequestNo": 2166 + }, + { + "name": "casseyshao", + "id": 60023562, + "comment_id": 1804915049, + "created_at": "2023-11-10T01:04:43Z", + "repoId": 299482335, + "pullRequestNo": 2167 } ] } \ No newline at end of file From b0145e5703533287a139103ff7493a44f26e3c7a Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:11:23 -0800 Subject: [PATCH 54/81] @rajyraman has signed the CLA in withfig/autocomplete#2168 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 38d3ad262d79..c2494fa3566c 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1047,6 +1047,14 @@ "created_at": "2023-11-10T01:04:43Z", "repoId": 299482335, "pullRequestNo": 2167 + }, + { + "name": "rajyraman", + "id": 5035266, + "comment_id": 1806583874, + "created_at": "2023-11-11T00:11:08Z", + "repoId": 299482335, + "pullRequestNo": 2168 } ] } \ No newline at end of file From f7de672e104c291ae12afa5aa68ce73e5e7e59bc Mon Sep 17 00:00:00 2001 From: Grant G Date: Mon, 13 Nov 2023 10:04:26 -0800 Subject: [PATCH 55/81] Update @fig/autocomplete-generators to 2.4.0 (#2169) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index aa8ba77c7be1..77d2e71889f3 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "vite-plugin-externals": "^0.6.2" }, "dependencies": { - "@fig/autocomplete-generators": "^2.3.0", + "@fig/autocomplete-generators": "^2.4.0", "@fig/autocomplete-helpers": "^1.0.7", "@fig/autocomplete-hooks": "^1.0.2", "@withfig/api-bindings": "^0.30.3", diff --git a/yarn.lock b/yarn.lock index f8d78b7ede22..964e095f9f3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -732,10 +732,10 @@ __metadata: languageName: node linkType: hard -"@fig/autocomplete-generators@npm:^2.3.0": - version: 2.3.0 - resolution: "@fig/autocomplete-generators@npm:2.3.0" - checksum: d2b6be2972c59fc9ea9828c84882650bea4b457dc8abe96b9a127458d923c04411f8a242a8b5e75f53ca2011503610fc8141b1b7ad8bea016f31290aa4685f67 +"@fig/autocomplete-generators@npm:^2.4.0": + version: 2.4.0 + resolution: "@fig/autocomplete-generators@npm:2.4.0" + checksum: 336ed2aaa537e2f6aca15cb0c1d412c2b919b5f0f15ccddcf849206ec82358013f02873dec72770f86b246410a9baa70994e71f6b132f30a6df9a2d186defd9f languageName: node linkType: hard @@ -1891,7 +1891,7 @@ __metadata: version: 0.0.0-use.local resolution: "@withfig/autocomplete@workspace:." dependencies: - "@fig/autocomplete-generators": ^2.3.0 + "@fig/autocomplete-generators": ^2.4.0 "@fig/autocomplete-helpers": ^1.0.7 "@fig/autocomplete-hooks": ^1.0.2 "@fig/eslint-config-autocomplete": ^1.2.1 From 310e4b86f7a61472d4c29765e73846034bcfefc5 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Sat, 18 Nov 2023 07:27:50 -0800 Subject: [PATCH 56/81] @Yashwin-Sudarshan has signed the CLA in withfig/autocomplete#2175 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index c2494fa3566c..018c3eb21d0e 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1055,6 +1055,14 @@ "created_at": "2023-11-11T00:11:08Z", "repoId": 299482335, "pullRequestNo": 2168 + }, + { + "name": "Yashwin-Sudarshan", + "id": 49670540, + "comment_id": 1817537761, + "created_at": "2023-11-18T15:27:37Z", + "repoId": 299482335, + "pullRequestNo": 2175 } ] } \ No newline at end of file From dac20b4cb7e57594296c5e6203770d9677ff334b Mon Sep 17 00:00:00 2001 From: Grant G Date: Mon, 20 Nov 2023 05:40:15 -0800 Subject: [PATCH 57/81] Add CW spec (#2179) --- src/cw.ts | 3549 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3549 insertions(+) create mode 100644 src/cw.ts diff --git a/src/cw.ts b/src/cw.ts new file mode 100644 index 000000000000..e6cb2ee77765 --- /dev/null +++ b/src/cw.ts @@ -0,0 +1,3549 @@ +export const themesGenerator: Fig.Generator = { + script: ["fig", "theme", "--list"], + postProcess: (output) => { + const builtinThemes: Fig.Suggestion[] = [ + { + name: "system", + icon: "💻", + priority: 51, + }, + { + name: "light", + icon: "fig://template?color=ffffff&badge=☀️", + priority: 51, + }, + { + name: "dark", + icon: "fig://template?color=000000&badge=🌙", + priority: 51, + }, + ]; + return output + .split("\n") + .map( + (theme) => + ({ + name: theme.replace(".json", ""), + icon: "🎨", + }) as Fig.Suggestion + ) + .concat(builtinThemes); + }, +}; + +const completion: Fig.Spec = { + name: "cw", + description: "Top level cli commands", + subcommands: [ + { + name: "app", + description: "Interact with the desktop app", + subcommands: [ + { + name: "install", + description: "Install the CodeWhisperer app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "onboarding", + description: "Run the CodeWhisperer tutorial again", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "running", + description: "Check if CodeWhisperer is running", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "launch", + description: "Launch the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "restart", + description: "Restart the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "quit", + description: "Quit the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "set-path", + description: "Set the internal pseudo-terminal path", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uninstall", + description: "Uninstall the CodeWhisperer app", + options: [ + { + name: "--app-bundle", + description: "Remove executable and user data", + }, + { + name: "--input-method", + description: "Remove input method", + }, + { + name: "--daemon", + description: "Remove CodeWhisperer daemon", + }, + { + name: "--dotfiles", + description: "Remove dotfile shell integration", + }, + { + name: "--ssh", + description: "Remove SSH integration", + }, + { + name: "--no-open", + description: "Do not open the uninstallation page", + }, + { + name: "--only-open", + description: "Only open the uninstallation page", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "prompts", + description: "Prompts shown on terminal startup", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "install", + description: "Install the CodeWhisperer app", + }, + { + name: "onboarding", + description: "Run the CodeWhisperer tutorial again", + }, + { + name: "running", + description: "Check if CodeWhisperer is running", + }, + { + name: "launch", + description: "Launch the CodeWhisperer desktop app", + }, + { + name: "restart", + description: "Restart the CodeWhisperer desktop app", + }, + { + name: "quit", + description: "Quit the CodeWhisperer desktop app", + }, + { + name: "set-path", + description: "Set the internal pseudo-terminal path", + }, + { + name: "uninstall", + description: "Uninstall the CodeWhisperer app", + }, + { + name: "prompts", + description: "Prompts shown on terminal startup", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "hook", + description: "Hook commands", + hidden: true, + subcommands: [ + { + name: "editbuffer", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "session_id", + }, + { + name: "integration", + }, + { + name: "tty", + }, + { + name: "pid", + }, + { + name: "histno", + }, + { + name: "cursor", + }, + { + name: "text", + }, + ], + }, + { + name: "hide", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "init", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "pid", + }, + { + name: "tty", + }, + ], + }, + { + name: "integration-ready", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "integration", + }, + }, + { + name: "keyboard-focus-changed", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "app_identifier", + }, + { + name: "focused_session_id", + }, + ], + }, + { + name: "pre-exec", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "pid", + }, + { + name: "tty", + }, + ], + }, + { + name: "prompt", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "pid", + }, + { + name: "tty", + }, + ], + }, + { + name: "ssh", + options: [ + { + name: "--prompt", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "pid", + }, + { + name: "tty", + }, + { + name: "control_path", + }, + { + name: "remote_dest", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "editbuffer", + }, + { + name: "hide", + }, + { + name: "init", + }, + { + name: "integration-ready", + }, + { + name: "keyboard-focus-changed", + }, + { + name: "pre-exec", + }, + { + name: "prompt", + }, + { + name: "ssh", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "debug", + description: "Debug CodeWhisperer", + subcommands: [ + { + name: "app", + description: "Debug CodeWhisperer app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "build", + description: "Switch to another branch of a Fig.js app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "app", + suggestions: ["dashboard", "autocomplete"], + }, + { + name: "build", + isOptional: true, + suggestions: ["production", "beta", "develop"], + }, + ], + }, + { + name: "autocomplete-window", + description: "Toggle/set autocomplete window debug mode", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "mode", + isOptional: true, + suggestions: ["on", "off"], + }, + }, + { + name: "logs", + description: "Show CodeWhisperer debug logs", + options: [ + { + name: "--level", + isRepeatable: true, + args: { + name: "level", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "files", + isVariadic: true, + isOptional: true, + }, + }, + { + name: "input-method", + description: "CodeWhisperer input method editor", + subcommands: [ + { + name: "install", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "bundle_path", + isOptional: true, + template: "filepaths", + }, + }, + { + name: "uninstall", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "bundle_path", + isOptional: true, + template: "filepaths", + }, + }, + { + name: "list", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "status", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "bundle_path", + isOptional: true, + template: "filepaths", + }, + }, + { + name: "source", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "bundle_identifier", + }, + { + name: "action", + suggestions: ["enable", "disable", "select", "deselect"], + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "install", + }, + { + name: "uninstall", + }, + { + name: "list", + }, + { + name: "status", + }, + { + name: "source", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "prompt-accessibility", + description: "Prompt accessibility", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "sample", + description: "Sample CodeWhisperer process", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "verify-codesign", + description: "Debug CodeWhisperer codesign verification", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "accessibility", + description: "Accessibility", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "action", + isOptional: true, + suggestions: ["refresh", "reset", "prompt", "open", "status"], + }, + }, + { + name: "key-tester", + description: "Key Tester", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "diagnostics", + description: "Watches diagnostics", + options: [ + { + name: "--rate", + isRepeatable: true, + args: { + name: "rate", + isOptional: true, + }, + }, + { + name: "--watch", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "query-index", + description: + "Queries remote repository for updates given the specified metadata", + options: [ + { + name: ["-c", "--channel"], + isRepeatable: true, + args: { + name: "channel", + }, + }, + { + name: ["-k", "--kind"], + isRepeatable: true, + args: { + name: "kind", + }, + }, + { + name: ["-v", "--variant"], + isRepeatable: true, + args: { + name: "variant", + }, + }, + { + name: ["-e", "--version"], + isRepeatable: true, + args: { + name: "version", + }, + }, + { + name: ["-a", "--architecture"], + isRepeatable: true, + args: { + name: "architecture", + }, + }, + { + name: ["-t", "--override-threshold"], + isRepeatable: true, + args: { + name: "override_threshold", + isOptional: true, + }, + }, + { + name: ["-r", "--enable-rollout"], + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "devtools", + description: "Open up the devtools of a specific webview", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "app", + suggestions: ["dashboard", "autocomplete"], + }, + }, + { + name: "get-index", + description: "Displays remote index", + options: [ + { + name: ["-d", "--debug"], + description: "Display using debug formatting", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "channel", + }, + }, + { + name: "list-intellij-variants", + description: "Lists installed IntelliJ variants", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "shell", + description: + "Disables sourcing of user shell config and instead uses a minimal CodeWhisperer default", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "app", + description: "Debug CodeWhisperer app", + }, + { + name: "build", + description: "Switch to another branch of a Fig.js app", + }, + { + name: "autocomplete-window", + description: "Toggle/set autocomplete window debug mode", + }, + { + name: "logs", + description: "Show CodeWhisperer debug logs", + }, + { + name: "input-method", + description: "CodeWhisperer input method editor", + subcommands: [ + { + name: "install", + }, + { + name: "uninstall", + }, + { + name: "list", + }, + { + name: "status", + }, + { + name: "source", + }, + ], + }, + { + name: "prompt-accessibility", + description: "Prompt accessibility", + }, + { + name: "sample", + description: "Sample CodeWhisperer process", + }, + { + name: "verify-codesign", + description: "Debug CodeWhisperer codesign verification", + }, + { + name: "accessibility", + description: "Accessibility", + }, + { + name: "key-tester", + description: "Key Tester", + }, + { + name: "diagnostics", + description: "Watches diagnostics", + }, + { + name: "query-index", + description: + "Queries remote repository for updates given the specified metadata", + }, + { + name: "devtools", + description: "Open up the devtools of a specific webview", + }, + { + name: "get-index", + description: "Displays remote index", + }, + { + name: "list-intellij-variants", + description: "Lists installed IntelliJ variants", + }, + { + name: "shell", + description: + "Disables sourcing of user shell config and instead uses a minimal CodeWhisperer default", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["settings", "setting"], + description: "Customize appearance & behavior", + subcommands: [ + { + name: "open", + description: "Open the settings file", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + description: "List all the settings", + options: [ + { + name: ["-f", "--format"], + description: "Format of the output", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "open", + description: "Open the settings file", + }, + { + name: "all", + description: "List all the settings", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-f", "--format"], + description: "Format of the output", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-d", "--delete"], + description: "Delete a value", + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: [ + { + name: "key", + isOptional: true, + }, + { + name: "value", + isOptional: true, + }, + ], + }, + { + name: "tips", + description: "Enable/disable fig tips", + subcommands: [ + { + name: "enable", + description: "Enable fig tips", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "disable", + description: "Disable fig tips", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "reset", + description: "Reset the tips to the default", + hidden: true, + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "prompt", + description: "Show the tips", + hidden: true, + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "enable", + description: "Enable fig tips", + }, + { + name: "disable", + description: "Disable fig tips", + }, + { + name: "reset", + description: "Reset the tips to the default", + hidden: true, + }, + { + name: "prompt", + description: "Show the tips", + hidden: true, + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "install", + description: "Install fig cli components", + options: [ + { + name: "--daemon", + description: "Install only the daemon", + }, + { + name: "--dotfiles", + description: "Install only the shell integrations", + }, + { + name: "--input-method", + description: "Prompt input method installation", + }, + { + name: "--no-confirm", + description: "Don't confirm automatic installation", + }, + { + name: "--force", + description: "Force installation of fig", + }, + { + name: "--ssh", + description: "Install only the ssh integration", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uninstall", + description: "Uninstall fig", + hidden: true, + options: [ + { + name: ["-y", "--no-confirm"], + description: "Force uninstall", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "update", + description: "Update dotfiles", + options: [ + { + name: "--no-confirm", + description: "(deprecated) Use --non-interactive instead", + }, + { + name: ["-y", "--non-interactive"], + description: "Don't prompt for confirmation", + }, + { + name: "--relaunch-dashboard", + description: + "Relaunch into dashboard after update (false will launch in background)", + }, + { + name: "--rollout", + description: "Uses rollout", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["diagnostic", "diagnostics"], + description: "Run diagnostic tests", + options: [ + { + name: ["-f", "--format"], + description: "The format of the output", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: "--force", + description: "Force limited diagnostic output", + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "init", + description: "Generate the dotfiles for the given shell", + options: [ + { + name: "--rcfile", + isRepeatable: true, + args: { + name: "rcfile", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: [ + { + name: "shell", + suggestions: [ + { + name: "bash", + description: "Bash shell", + }, + { + name: "zsh", + description: "Zsh shell", + }, + { + name: "fish", + description: "Fish shell", + }, + { + name: "nu", + description: "Nu shell", + }, + ], + }, + { + name: "when", + suggestions: ["pre", "post"], + }, + ], + }, + { + name: "theme", + description: "Get or set theme", + options: [ + { + name: "--list", + exclusiveOn: ["--folder"], + }, + { + name: "--folder", + exclusiveOn: ["--list"], + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "theme", + isOptional: true, + }, + }, + { + name: "issue", + description: "Create a new Github issue", + options: [ + { + name: ["-f", "--force"], + description: "Force issue creation", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "description", + isVariadic: true, + isOptional: true, + }, + }, + { + name: "login", + description: "Login to CodeWhisperer", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "logout", + description: "Logout of CodeWhisperer", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "whoami", + description: "Prints details about the current user", + options: [ + { + name: ["-f", "--format"], + description: "Output format to use", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "user", + description: "Manage your fig user", + subcommands: [ + { + name: "login", + description: "Login to CodeWhisperer", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "logout", + description: "Logout of CodeWhisperer", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "whoami", + description: "Prints details about the current user", + options: [ + { + name: ["-f", "--format"], + description: "Output format to use", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "login", + description: "Login to CodeWhisperer", + }, + { + name: "logout", + description: "Logout of CodeWhisperer", + }, + { + name: "whoami", + description: "Prints details about the current user", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "doctor", + description: "Check CodeWhisperer is properly configured", + options: [ + { + name: "--verbose", + description: "Run all doctor tests, with no fixes", + }, + { + name: "--strict", + description: "Error on warnings", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "completion", + description: "Generate the completion spec for CodeWhisperer", + hidden: true, + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "shell", + isOptional: true, + suggestions: [ + { + name: "bash", + description: "Bash shell completions", + }, + { + name: "fish", + description: "Fish shell completions", + }, + { + name: "zsh", + description: "Zsh shell completions", + }, + { + name: "fig", + description: "Fig completion spec", + }, + ], + }, + }, + { + name: ["internal", "_"], + description: "Internal subcommands used for CodeWhisperer", + hidden: true, + subcommands: [ + { + name: "pre-cmd", + description: + "Command that is run during the PreCmd section of the fig integrations", + options: [ + { + name: "--alias", + isRepeatable: true, + args: { + name: "alias", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "local-state", + description: "Change the local-state file", + subcommands: [ + { + name: "init", + description: "Reload the state listener", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "open", + description: "Open the state file", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + description: "List all the settings", + options: [ + { + name: ["-f", "--format"], + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "init", + description: "Reload the state listener", + }, + { + name: "open", + description: "Open the state file", + }, + { + name: "all", + description: "List all the settings", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-f", "--format"], + description: "Format of the output", + isRepeatable: true, + args: { + name: "format", + isOptional: true, + suggestions: [ + { + name: "plain", + description: "Outputs the results as markdown", + }, + { + name: "json", + description: "Outputs the results as JSON", + }, + { + name: "json-pretty", + description: "Outputs the results as pretty print JSON", + }, + ], + }, + }, + { + name: ["-d", "--delete"], + description: "Delete the state", + }, + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: [ + { + name: "key", + isOptional: true, + }, + { + name: "value", + isOptional: true, + }, + ], + }, + { + name: "callback", + description: "Callback used for the internal pseudoterminal", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "handler_id", + }, + { + name: "filename", + isOptional: true, + }, + { + name: "exit_code", + isOptional: true, + }, + ], + }, + { + name: "install", + description: "Install fig cli", + options: [ + { + name: "--daemon", + description: "Install only the daemon", + }, + { + name: "--dotfiles", + description: "Install only the shell integrations", + }, + { + name: "--input-method", + description: "Prompt input method installation", + }, + { + name: "--no-confirm", + description: "Don't confirm automatic installation", + }, + { + name: "--force", + description: "Force installation of fig", + }, + { + name: "--ssh", + description: "Install only the ssh integration", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uninstall", + description: "Uninstall fig cli", + options: [ + { + name: "--daemon", + description: "Uninstall only the daemon", + }, + { + name: "--dotfiles", + description: "Uninstall only the shell integrations", + }, + { + name: "--input-method", + description: "Uninstall only the input method", + }, + { + name: "--binary", + description: "Uninstall only the binary", + }, + { + name: "--ssh", + description: "Uninstall only the ssh integration", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "get-shell", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "hostname", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "should-figterm-launch", + description: "Detects if Figterm should be launched", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + }, + { + name: "event", + options: [ + { + name: "--name", + description: "Name of the event", + isRepeatable: true, + args: { + name: "name", + }, + }, + { + name: "--payload", + description: "Payload of the event as a JSON string", + isRepeatable: true, + args: { + name: "payload", + isOptional: true, + }, + }, + { + name: "--apps", + description: "Apps to send the event to", + isRepeatable: true, + args: { + name: "apps", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "sockets-dir", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "stream-from-socket", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "figterm-socket-path", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "session_id", + }, + }, + { + name: "ipc", + options: [ + { + name: "--figterm", + isRepeatable: true, + args: { + name: "figterm", + isOptional: true, + }, + }, + { + name: "--json", + isRepeatable: true, + args: { + name: "json", + }, + }, + { + name: "--app", + }, + { + name: "--recv", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uninstall-for-all-users", + description: "Linux only", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uuidgen", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "open-uninstall-page", + options: [ + { + name: "--verbose", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ssh-local-command", + description: "Displays prompt to install remote shell integrations", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "remote_dest", + }, + { + name: "uuid", + }, + ], + }, + { + name: "prompt-ssh", + description: + "\\[Deprecated\\] Displays prompt to install remote shell integrations", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "remote_dest", + }, + }, + { + name: "attempt-to-finish-input-method-installation", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "bundle_path", + isOptional: true, + template: "filepaths", + }, + }, + { + name: "dump-state", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "component", + suggestions: ["figterm", "web-notifications"], + }, + }, + { + name: "finish-update", + options: [ + { + name: "--relaunch-dashboard", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "swap-files", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: [ + { + name: "from", + template: "filepaths", + }, + { + name: "to", + template: "filepaths", + }, + ], + }, + { + name: "check-ssh", + hidden: true, + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "remote_username", + }, + }, + { + name: "brew-uninstall", + options: [ + { + name: "--zap", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "generate-ssh", + description: "Generates an SSH configuration file", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "remote_username", + }, + }, + { + name: "ghost-text", + options: [ + { + name: "--buffer", + isRepeatable: true, + args: { + name: "buffer", + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ghost-text-accept", + options: [ + { + name: "--buffer", + isRepeatable: true, + args: { + name: "buffer", + }, + }, + { + name: "--suggestion", + isRepeatable: true, + args: { + name: "suggestion", + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "pre-cmd", + description: + "Command that is run during the PreCmd section of the fig integrations", + }, + { + name: "local-state", + description: "Change the local-state file", + subcommands: [ + { + name: "init", + description: "Reload the state listener", + }, + { + name: "open", + description: "Open the state file", + }, + { + name: "all", + description: "List all the settings", + }, + ], + }, + { + name: "callback", + description: "Callback used for the internal pseudoterminal", + }, + { + name: "install", + description: "Install fig cli", + }, + { + name: "uninstall", + description: "Uninstall fig cli", + }, + { + name: "get-shell", + }, + { + name: "hostname", + }, + { + name: "should-figterm-launch", + description: "Detects if Figterm should be launched", + }, + { + name: "event", + }, + { + name: "sockets-dir", + }, + { + name: "stream-from-socket", + }, + { + name: "figterm-socket-path", + }, + { + name: "ipc", + }, + { + name: "uninstall-for-all-users", + description: "Linux only", + }, + { + name: "uuidgen", + }, + { + name: "open-uninstall-page", + }, + { + name: "ssh-local-command", + description: + "Displays prompt to install remote shell integrations", + }, + { + name: "prompt-ssh", + description: + "\\[Deprecated\\] Displays prompt to install remote shell integrations", + }, + { + name: "attempt-to-finish-input-method-installation", + }, + { + name: "dump-state", + }, + { + name: "finish-update", + }, + { + name: "swap-files", + }, + { + name: "check-ssh", + hidden: true, + }, + { + name: "brew-uninstall", + }, + { + name: "generate-ssh", + description: "Generates an SSH configuration file", + }, + { + name: "ghost-text", + }, + { + name: "ghost-text-accept", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "launch", + description: "Launch the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "quit", + description: "Quit the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "restart", + description: "Restart the CodeWhisperer desktop app", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "process", + isOptional: true, + suggestions: [ + { + name: "daemon", + description: "Daemon process", + }, + { + name: "app", + description: "CodeWhisperer process", + }, + ], + }, + }, + { + name: "onboarding", + description: "Run the CodeWhisperer tutorial", + hidden: true, + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["integrations", "integration"], + description: "Manage system integrations", + subcommands: [ + { + name: "install", + subcommands: [ + { + name: "dotfiles", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "shell", + isOptional: true, + suggestions: [ + { + name: "bash", + description: "Bash shell", + }, + { + name: "zsh", + description: "Zsh shell", + }, + { + name: "fish", + description: "Fish shell", + }, + { + name: "nu", + description: "Nu shell", + }, + ], + }, + }, + { + name: "daemon", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ssh", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "input-method", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "vscode", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["intellij", "jetbrains"], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-s", "--silent"], + description: "Suppress status messages", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "uninstall", + subcommands: [ + { + name: "dotfiles", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "shell", + isOptional: true, + suggestions: [ + { + name: "bash", + description: "Bash shell", + }, + { + name: "zsh", + description: "Zsh shell", + }, + { + name: "fish", + description: "Fish shell", + }, + { + name: "nu", + description: "Nu shell", + }, + ], + }, + }, + { + name: "daemon", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ssh", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "input-method", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "vscode", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["intellij", "jetbrains"], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-s", "--silent"], + description: "Suppress status messages", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "reinstall", + subcommands: [ + { + name: "dotfiles", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "shell", + isOptional: true, + suggestions: [ + { + name: "bash", + description: "Bash shell", + }, + { + name: "zsh", + description: "Zsh shell", + }, + { + name: "fish", + description: "Fish shell", + }, + { + name: "nu", + description: "Nu shell", + }, + ], + }, + }, + { + name: "daemon", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ssh", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "input-method", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "vscode", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["intellij", "jetbrains"], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-s", "--silent"], + description: "Suppress status messages", + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "status", + subcommands: [ + { + name: "dotfiles", + options: [ + { + name: ["-h", "--help"], + description: "Print help (see more with '--help')", + }, + ], + args: { + name: "shell", + isOptional: true, + suggestions: [ + { + name: "bash", + description: "Bash shell", + }, + { + name: "zsh", + description: "Zsh shell", + }, + { + name: "fish", + description: "Fish shell", + }, + { + name: "nu", + description: "Nu shell", + }, + ], + }, + }, + { + name: "daemon", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "ssh", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "input-method", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "vscode", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["intellij", "jetbrains"], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "all", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "install", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "uninstall", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "reinstall", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "status", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: ["ai", "q"], + description: "English -> Bash translation", + options: [ + { + name: ["-n", "--n"], + description: "Number of completions to generate (must be <=5)", + hidden: true, + isRepeatable: true, + args: { + name: "n", + isOptional: true, + }, + }, + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + args: { + name: "input", + isVariadic: true, + isOptional: true, + }, + }, + { + name: "telemetry", + description: "Enable/disable telemetry", + hidden: true, + subcommands: [ + { + name: "enable", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "disable", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "status", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "enable", + }, + { + name: "disable", + }, + { + name: "status", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "version", + description: "Version", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help-all", + description: "Print help for all subcommands", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "dashboard", + description: "Open the fig dashboard", + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + ], + }, + { + name: "help", + description: "Print this message or the help of the given subcommand(s)", + subcommands: [ + { + name: "app", + description: "Interact with the desktop app", + subcommands: [ + { + name: "install", + description: "Install the Fig app", + }, + { + name: "onboarding", + description: "Run the CodeWhisperer tutorial again", + }, + { + name: "running", + description: "Check if CodeWhisperer is running", + }, + { + name: "launch", + description: "Launch the CodeWhisperer desktop app", + }, + { + name: "restart", + description: "Restart the CodeWhisperer desktop app", + }, + { + name: "quit", + description: "Quit the CodeWhisperer desktop app", + }, + { + name: "set-path", + description: "Set the internal pseudo-terminal path", + }, + { + name: "uninstall", + description: "Uninstall the CodeWhisperer app", + }, + { + name: "prompts", + description: "Prompts shown on terminal startup", + }, + ], + }, + { + name: "hook", + description: "Hook commands", + hidden: true, + subcommands: [ + { + name: "editbuffer", + }, + { + name: "hide", + }, + { + name: "init", + }, + { + name: "integration-ready", + }, + { + name: "keyboard-focus-changed", + }, + { + name: "pre-exec", + }, + { + name: "prompt", + }, + { + name: "ssh", + }, + ], + }, + { + name: "debug", + description: "Debug CodeWhisperer", + subcommands: [ + { + name: "app", + description: "Debug CodeWhisperer app", + }, + { + name: "build", + description: "Switch to another branch of a Fig.js app", + }, + { + name: "autocomplete-window", + description: "Toggle/set autocomplete window debug mode", + }, + { + name: "logs", + description: "Show CodeWhisperer debug logs", + }, + { + name: "input-method", + description: "CodeWhisperer input method editor", + subcommands: [ + { + name: "install", + }, + { + name: "uninstall", + }, + { + name: "list", + }, + { + name: "status", + }, + { + name: "source", + }, + ], + }, + { + name: "prompt-accessibility", + description: "Prompt accessibility", + }, + { + name: "sample", + description: "Sample CodeWhisperer process", + }, + { + name: "verify-codesign", + description: "Debug CodeWhisperer codesign verification", + }, + { + name: "accessibility", + description: "Accessibility", + }, + { + name: "key-tester", + description: "Key Tester", + }, + { + name: "diagnostics", + description: "Watches diagnostics", + }, + { + name: "query-index", + description: + "Queries remote repository for updates given the specified metadata", + }, + { + name: "devtools", + description: "Open up the devtools of a specific webview", + }, + { + name: "get-index", + description: "Displays remote index", + }, + { + name: "list-intellij-variants", + description: "Lists installed IntelliJ variants", + }, + { + name: "shell", + description: + "Disables sourcing of user shell config and instead uses a minimal CodeWhisperer default", + }, + ], + }, + { + name: "settings", + description: "Customize appearance & behavior", + subcommands: [ + { + name: "open", + description: "Open the settings file", + }, + { + name: "all", + description: "List all the settings", + }, + ], + }, + { + name: "tips", + description: "Enable/disable fig tips", + subcommands: [ + { + name: "enable", + description: "Enable fig tips", + }, + { + name: "disable", + description: "Disable fig tips", + }, + { + name: "reset", + description: "Reset the tips to the default", + hidden: true, + }, + { + name: "prompt", + description: "Show the tips", + hidden: true, + }, + ], + }, + { + name: "install", + description: "Install fig cli components", + }, + { + name: "uninstall", + description: "Uninstall fig", + hidden: true, + }, + { + name: "update", + description: "Update dotfiles", + }, + { + name: "diagnostic", + description: "Run diagnostic tests", + }, + { + name: "init", + description: "Generate the dotfiles for the given shell", + }, + { + name: "theme", + description: "Get or set theme", + }, + { + name: "issue", + description: "Create a new Github issue", + }, + { + name: "login", + description: "Login to CodeWhisperer", + }, + { + name: "logout", + description: "Logout of CodeWhisperer", + }, + { + name: "whoami", + description: "Prints details about the current user", + }, + { + name: "user", + description: "Manage your fig user", + subcommands: [ + { + name: "login", + description: "Login to CodeWhisperer", + }, + { + name: "logout", + description: "Logout of CodeWhisperer", + }, + { + name: "whoami", + description: "Prints details about the current user", + }, + ], + }, + { + name: "doctor", + description: "Check CodeWhisperer is properly configured", + }, + { + name: "completion", + description: "Generate the completion spec for CodeWhisperer", + hidden: true, + }, + { + name: "internal", + description: "Internal subcommands used for CodeWhisperer", + hidden: true, + subcommands: [ + { + name: "pre-cmd", + description: + "Command that is run during the PreCmd section of the fig integrations", + }, + { + name: "local-state", + description: "Change the local-state file", + subcommands: [ + { + name: "init", + description: "Reload the state listener", + }, + { + name: "open", + description: "Open the state file", + }, + { + name: "all", + description: "List all the settings", + }, + ], + }, + { + name: "callback", + description: "Callback used for the internal pseudoterminal", + }, + { + name: "install", + description: "Install fig cli", + }, + { + name: "uninstall", + description: "Uninstall fig cli", + }, + { + name: "get-shell", + }, + { + name: "hostname", + }, + { + name: "should-figterm-launch", + description: "Detects if Figterm should be launched", + }, + { + name: "event", + }, + { + name: "sockets-dir", + }, + { + name: "stream-from-socket", + }, + { + name: "figterm-socket-path", + }, + { + name: "ipc", + }, + { + name: "uninstall-for-all-users", + description: "Linux only", + }, + { + name: "uuidgen", + }, + { + name: "open-uninstall-page", + }, + { + name: "ssh-local-command", + description: + "Displays prompt to install remote shell integrations", + }, + { + name: "prompt-ssh", + description: + "\\[Deprecated\\] Displays prompt to install remote shell integrations", + }, + { + name: "attempt-to-finish-input-method-installation", + }, + { + name: "dump-state", + }, + { + name: "finish-update", + }, + { + name: "swap-files", + }, + { + name: "check-ssh", + hidden: true, + }, + { + name: "brew-uninstall", + }, + { + name: "generate-ssh", + description: "Generates an SSH configuration file", + }, + { + name: "ghost-text", + }, + { + name: "ghost-text-accept", + }, + ], + }, + { + name: "launch", + description: "Launch the CodeWhisperer desktop app", + }, + { + name: "quit", + description: "Quit the CodeWhisperer desktop app", + }, + { + name: "restart", + description: "Restart the CodeWhisperer desktop app", + }, + { + name: "onboarding", + description: "Run the CodeWhisperer tutorial", + hidden: true, + }, + { + name: "integrations", + description: "Manage system integrations", + subcommands: [ + { + name: "install", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "uninstall", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "reinstall", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + { + name: "status", + subcommands: [ + { + name: "dotfiles", + }, + { + name: "daemon", + }, + { + name: "ssh", + }, + { + name: "input-method", + }, + { + name: "vscode", + }, + { + name: "intellij", + }, + { + name: "all", + }, + ], + }, + ], + }, + { + name: "ai", + description: "English -> Bash translation", + }, + { + name: "telemetry", + description: "Enable/disable telemetry", + hidden: true, + subcommands: [ + { + name: "enable", + }, + { + name: "disable", + }, + { + name: "status", + }, + ], + }, + { + name: "version", + description: "Version", + }, + { + name: "help-all", + description: "Print help for all subcommands", + }, + { + name: "dashboard", + description: "Open the fig dashboard", + }, + { + name: "help", + description: + "Print this message or the help of the given subcommand(s)", + }, + ], + }, + ], + options: [ + { + name: ["-h", "--help"], + description: "Print help", + }, + { + name: ["-V", "--version"], + description: "Print version", + }, + ], +}; + +export default completion; From b60f723488df26bc145d2c9b613e6cc4fc81e073 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Mon, 20 Nov 2023 13:41:35 +0000 Subject: [PATCH 58/81] ci: version bump to 2.640.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77d2e71889f3..f88ea553a8e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.640.3", + "version": "2.640.4", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 71d04735bce2b59e4162d466649668a20db9857d Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Mon, 20 Nov 2023 06:38:29 -0800 Subject: [PATCH 59/81] @beeinger has signed the CLA in withfig/autocomplete#2180 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 018c3eb21d0e..202849df47a0 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1063,6 +1063,14 @@ "created_at": "2023-11-18T15:27:37Z", "repoId": 299482335, "pullRequestNo": 2175 + }, + { + "name": "beeinger", + "id": 40423831, + "comment_id": 1819188302, + "created_at": "2023-11-20T14:38:12Z", + "repoId": 299482335, + "pullRequestNo": 2180 } ] } \ No newline at end of file From 4a3e513739eee3a731132dac05a4faf2a5d2a6b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:19:34 -0800 Subject: [PATCH 60/81] build(deps-dev): bump eslint from 8.52.0 to 8.54.0 (#2177) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 964e095f9f3c..7caacf975721 100644 --- a/yarn.lock +++ b/yarn.lock @@ -708,9 +708,9 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.2": - version: 2.1.2 - resolution: "@eslint/eslintrc@npm:2.1.2" +"@eslint/eslintrc@npm:^2.1.3": + version: 2.1.3 + resolution: "@eslint/eslintrc@npm:2.1.3" dependencies: ajv: ^6.12.4 debug: ^4.3.2 @@ -721,14 +721,14 @@ __metadata: js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: bc742a1e3b361f06fedb4afb6bf32cbd27171292ef7924f61c62f2aed73048367bcc7ac68f98c06d4245cd3fabc43270f844e3c1699936d4734b3ac5398814a7 + checksum: 5c6c3878192fe0ddffa9aff08b4e2f3bcc8f1c10d6449b7295a5f58b662019896deabfc19890455ffd7e60a5bd28d25d0eaefb2f78b2d230aae3879af92b89e5 languageName: node linkType: hard -"@eslint/js@npm:8.52.0": - version: 8.52.0 - resolution: "@eslint/js@npm:8.52.0" - checksum: 490893b8091a66415f4ac98b963d23eb287264ea3bd6af7ec788f0570705cf64fd6ab84b717785980f55e39d08ff5c7fde6d8e4391ccb507169370ce3a6d091a +"@eslint/js@npm:8.54.0": + version: 8.54.0 + resolution: "@eslint/js@npm:8.54.0" + checksum: 6d88a6f711ef0133566b5340e3178a178fbb297585766460f195d0a9db85688f1e5cf8559fd5748aeb3131e2096c66595b323d8edab22df015acda68f1ebde92 languageName: node linkType: hard @@ -3729,13 +3729,13 @@ __metadata: linkType: hard "eslint@npm:^8.50.0": - version: 8.52.0 - resolution: "eslint@npm:8.52.0" + version: 8.54.0 + resolution: "eslint@npm:8.54.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 - "@eslint/eslintrc": ^2.1.2 - "@eslint/js": 8.52.0 + "@eslint/eslintrc": ^2.1.3 + "@eslint/js": 8.54.0 "@humanwhocodes/config-array": ^0.11.13 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -3772,7 +3772,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: fd22d1e9bd7090e31b00cbc7a3b98f3b76020a4c4641f987ae7d0c8f52e1b88c3b268bdfdabac2e1a93513e5d11339b718ff45cbff48a44c35d7e52feba510ed + checksum: 7e876e9da2a18a017271cf3733d05a3dfbbe469272d75753408c6ea5b1646c71c6bb18cb91e10ca930144c32c1ce3701e222f1ae6784a3975a69f8f8aa68e49f languageName: node linkType: hard From e95256ca00a769d662bab789109a7df1d9839201 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:19:44 -0800 Subject: [PATCH 61/81] build(deps-dev): bump esbuild from 0.19.4 to 0.19.6 (#2176) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 368 +++++++++++++++++++++++++++--------------------------- 1 file changed, 184 insertions(+), 184 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7caacf975721..9c3d918e136b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -347,16 +347,16 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-arm64@npm:0.18.13" +"@esbuild/android-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-arm64@npm:0.18.20" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/android-arm64@npm:0.19.4" +"@esbuild/android-arm64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/android-arm64@npm:0.19.6" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -368,128 +368,128 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-arm@npm:0.18.13" +"@esbuild/android-arm@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-arm@npm:0.18.20" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-arm@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/android-arm@npm:0.19.4" +"@esbuild/android-arm@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/android-arm@npm:0.19.6" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/android-x64@npm:0.18.13" +"@esbuild/android-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/android-x64@npm:0.18.20" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/android-x64@npm:0.19.4" +"@esbuild/android-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/android-x64@npm:0.19.6" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/darwin-arm64@npm:0.18.13" +"@esbuild/darwin-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/darwin-arm64@npm:0.18.20" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/darwin-arm64@npm:0.19.4" +"@esbuild/darwin-arm64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/darwin-arm64@npm:0.19.6" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/darwin-x64@npm:0.18.13" +"@esbuild/darwin-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/darwin-x64@npm:0.18.20" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/darwin-x64@npm:0.19.4" +"@esbuild/darwin-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/darwin-x64@npm:0.19.6" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/freebsd-arm64@npm:0.18.13" +"@esbuild/freebsd-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/freebsd-arm64@npm:0.18.20" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/freebsd-arm64@npm:0.19.4" +"@esbuild/freebsd-arm64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/freebsd-arm64@npm:0.19.6" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/freebsd-x64@npm:0.18.13" +"@esbuild/freebsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/freebsd-x64@npm:0.18.20" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/freebsd-x64@npm:0.19.4" +"@esbuild/freebsd-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/freebsd-x64@npm:0.19.6" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-arm64@npm:0.18.13" +"@esbuild/linux-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-arm64@npm:0.18.20" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-arm64@npm:0.19.4" +"@esbuild/linux-arm64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-arm64@npm:0.19.6" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-arm@npm:0.18.13" +"@esbuild/linux-arm@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-arm@npm:0.18.20" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-arm@npm:0.19.4" +"@esbuild/linux-arm@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-arm@npm:0.19.6" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-ia32@npm:0.18.13" +"@esbuild/linux-ia32@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-ia32@npm:0.18.20" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-ia32@npm:0.19.4" +"@esbuild/linux-ia32@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-ia32@npm:0.19.6" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -508,170 +508,170 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-loong64@npm:0.18.13" +"@esbuild/linux-loong64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-loong64@npm:0.18.20" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-loong64@npm:0.19.4" +"@esbuild/linux-loong64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-loong64@npm:0.19.6" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-mips64el@npm:0.18.13" +"@esbuild/linux-mips64el@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-mips64el@npm:0.18.20" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-mips64el@npm:0.19.4" +"@esbuild/linux-mips64el@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-mips64el@npm:0.19.6" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-ppc64@npm:0.18.13" +"@esbuild/linux-ppc64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-ppc64@npm:0.18.20" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-ppc64@npm:0.19.4" +"@esbuild/linux-ppc64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-ppc64@npm:0.19.6" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-riscv64@npm:0.18.13" +"@esbuild/linux-riscv64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-riscv64@npm:0.18.20" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-riscv64@npm:0.19.4" +"@esbuild/linux-riscv64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-riscv64@npm:0.19.6" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-s390x@npm:0.18.13" +"@esbuild/linux-s390x@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-s390x@npm:0.18.20" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-s390x@npm:0.19.4" +"@esbuild/linux-s390x@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-s390x@npm:0.19.6" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/linux-x64@npm:0.18.13" +"@esbuild/linux-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/linux-x64@npm:0.18.20" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/linux-x64@npm:0.19.4" +"@esbuild/linux-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/linux-x64@npm:0.19.6" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/netbsd-x64@npm:0.18.13" +"@esbuild/netbsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/netbsd-x64@npm:0.18.20" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/netbsd-x64@npm:0.19.4" +"@esbuild/netbsd-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/netbsd-x64@npm:0.19.6" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/openbsd-x64@npm:0.18.13" +"@esbuild/openbsd-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/openbsd-x64@npm:0.18.20" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/openbsd-x64@npm:0.19.4" +"@esbuild/openbsd-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/openbsd-x64@npm:0.19.6" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/sunos-x64@npm:0.18.13" +"@esbuild/sunos-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/sunos-x64@npm:0.18.20" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/sunos-x64@npm:0.19.4" +"@esbuild/sunos-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/sunos-x64@npm:0.19.6" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-arm64@npm:0.18.13" +"@esbuild/win32-arm64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-arm64@npm:0.18.20" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/win32-arm64@npm:0.19.4" +"@esbuild/win32-arm64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/win32-arm64@npm:0.19.6" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-ia32@npm:0.18.13" +"@esbuild/win32-ia32@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-ia32@npm:0.18.20" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/win32-ia32@npm:0.19.4" +"@esbuild/win32-ia32@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/win32-ia32@npm:0.19.6" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.13": - version: 0.18.13 - resolution: "@esbuild/win32-x64@npm:0.18.13" +"@esbuild/win32-x64@npm:0.18.20": + version: 0.18.20 + resolution: "@esbuild/win32-x64@npm:0.18.20" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.19.4": - version: 0.19.4 - resolution: "@esbuild/win32-x64@npm:0.19.4" +"@esbuild/win32-x64@npm:0.19.6": + version: 0.19.6 + resolution: "@esbuild/win32-x64@npm:0.19.6" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3495,31 +3495,31 @@ __metadata: linkType: hard "esbuild@npm:^0.18.10": - version: 0.18.13 - resolution: "esbuild@npm:0.18.13" - dependencies: - "@esbuild/android-arm": 0.18.13 - "@esbuild/android-arm64": 0.18.13 - "@esbuild/android-x64": 0.18.13 - "@esbuild/darwin-arm64": 0.18.13 - "@esbuild/darwin-x64": 0.18.13 - "@esbuild/freebsd-arm64": 0.18.13 - "@esbuild/freebsd-x64": 0.18.13 - "@esbuild/linux-arm": 0.18.13 - "@esbuild/linux-arm64": 0.18.13 - "@esbuild/linux-ia32": 0.18.13 - "@esbuild/linux-loong64": 0.18.13 - "@esbuild/linux-mips64el": 0.18.13 - "@esbuild/linux-ppc64": 0.18.13 - "@esbuild/linux-riscv64": 0.18.13 - "@esbuild/linux-s390x": 0.18.13 - "@esbuild/linux-x64": 0.18.13 - "@esbuild/netbsd-x64": 0.18.13 - "@esbuild/openbsd-x64": 0.18.13 - "@esbuild/sunos-x64": 0.18.13 - "@esbuild/win32-arm64": 0.18.13 - "@esbuild/win32-ia32": 0.18.13 - "@esbuild/win32-x64": 0.18.13 + version: 0.18.20 + resolution: "esbuild@npm:0.18.20" + dependencies: + "@esbuild/android-arm": 0.18.20 + "@esbuild/android-arm64": 0.18.20 + "@esbuild/android-x64": 0.18.20 + "@esbuild/darwin-arm64": 0.18.20 + "@esbuild/darwin-x64": 0.18.20 + "@esbuild/freebsd-arm64": 0.18.20 + "@esbuild/freebsd-x64": 0.18.20 + "@esbuild/linux-arm": 0.18.20 + "@esbuild/linux-arm64": 0.18.20 + "@esbuild/linux-ia32": 0.18.20 + "@esbuild/linux-loong64": 0.18.20 + "@esbuild/linux-mips64el": 0.18.20 + "@esbuild/linux-ppc64": 0.18.20 + "@esbuild/linux-riscv64": 0.18.20 + "@esbuild/linux-s390x": 0.18.20 + "@esbuild/linux-x64": 0.18.20 + "@esbuild/netbsd-x64": 0.18.20 + "@esbuild/openbsd-x64": 0.18.20 + "@esbuild/sunos-x64": 0.18.20 + "@esbuild/win32-arm64": 0.18.20 + "@esbuild/win32-ia32": 0.18.20 + "@esbuild/win32-x64": 0.18.20 dependenciesMeta: "@esbuild/android-arm": optional: true @@ -3567,36 +3567,36 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 6512b7e186cffb4546f3508f1e2d1dd27eb43a8a8a79d4ea7eb34ae3dbdc647679ae96b29c54a4951c355ee3168e8ad9c128cbfc033154b0849e269276d5bc9c + checksum: 5d253614e50cdb6ec22095afd0c414f15688e7278a7eb4f3720a6dd1306b0909cf431e7b9437a90d065a31b1c57be60130f63fe3e8d0083b588571f31ee6ec7b languageName: node linkType: hard "esbuild@npm:^0.19.4": - version: 0.19.4 - resolution: "esbuild@npm:0.19.4" - dependencies: - "@esbuild/android-arm": 0.19.4 - "@esbuild/android-arm64": 0.19.4 - "@esbuild/android-x64": 0.19.4 - "@esbuild/darwin-arm64": 0.19.4 - "@esbuild/darwin-x64": 0.19.4 - "@esbuild/freebsd-arm64": 0.19.4 - "@esbuild/freebsd-x64": 0.19.4 - "@esbuild/linux-arm": 0.19.4 - "@esbuild/linux-arm64": 0.19.4 - "@esbuild/linux-ia32": 0.19.4 - "@esbuild/linux-loong64": 0.19.4 - "@esbuild/linux-mips64el": 0.19.4 - "@esbuild/linux-ppc64": 0.19.4 - "@esbuild/linux-riscv64": 0.19.4 - "@esbuild/linux-s390x": 0.19.4 - "@esbuild/linux-x64": 0.19.4 - "@esbuild/netbsd-x64": 0.19.4 - "@esbuild/openbsd-x64": 0.19.4 - "@esbuild/sunos-x64": 0.19.4 - "@esbuild/win32-arm64": 0.19.4 - "@esbuild/win32-ia32": 0.19.4 - "@esbuild/win32-x64": 0.19.4 + version: 0.19.6 + resolution: "esbuild@npm:0.19.6" + dependencies: + "@esbuild/android-arm": 0.19.6 + "@esbuild/android-arm64": 0.19.6 + "@esbuild/android-x64": 0.19.6 + "@esbuild/darwin-arm64": 0.19.6 + "@esbuild/darwin-x64": 0.19.6 + "@esbuild/freebsd-arm64": 0.19.6 + "@esbuild/freebsd-x64": 0.19.6 + "@esbuild/linux-arm": 0.19.6 + "@esbuild/linux-arm64": 0.19.6 + "@esbuild/linux-ia32": 0.19.6 + "@esbuild/linux-loong64": 0.19.6 + "@esbuild/linux-mips64el": 0.19.6 + "@esbuild/linux-ppc64": 0.19.6 + "@esbuild/linux-riscv64": 0.19.6 + "@esbuild/linux-s390x": 0.19.6 + "@esbuild/linux-x64": 0.19.6 + "@esbuild/netbsd-x64": 0.19.6 + "@esbuild/openbsd-x64": 0.19.6 + "@esbuild/sunos-x64": 0.19.6 + "@esbuild/win32-arm64": 0.19.6 + "@esbuild/win32-ia32": 0.19.6 + "@esbuild/win32-x64": 0.19.6 dependenciesMeta: "@esbuild/android-arm": optional: true @@ -3644,7 +3644,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 024309a16365b020815a30e9a3a9354894a391cf1adbfad7f44a975cf161ab5e961619b30e1ec8ea02994631d71e6b38831119be69f8ccb610c32bbe21addc79 + checksum: b5f6e19c9f3e5302ffea4ad0ba39e17f7eed09f342f04d5561cfa491a69334095655ac2a9166c29a80da14af35cfcaaaf7751f8b2bad870d49ccdb8817921f37 languageName: node linkType: hard From 76391b5f799572e1cd84adf29442da64a7a98a36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:19:57 -0800 Subject: [PATCH 62/81] build(deps-dev): bump @types/progress from 2.0.5 to 2.0.7 (#2172) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9c3d918e136b..f43fc978bfd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1416,11 +1416,11 @@ __metadata: linkType: hard "@types/progress@npm:^2.0.5": - version: 2.0.5 - resolution: "@types/progress@npm:2.0.5" + version: 2.0.7 + resolution: "@types/progress@npm:2.0.7" dependencies: "@types/node": "*" - checksum: 633427b875f782176456ceaf78bcdf47abf27bcf52385fa1acb545d0e6450f5638aa313ca600f25fb12bf094a003257b19b000d1072981d7be8a375c87e37a92 + checksum: 50904eabb81ea98f5c3762a56e6f289a8501da8dc328f3c626efc17c6ab431288881d15f98e74e09a56e376d4dc9e91ad942937d7e2c7b67c3a19c7494978a0d languageName: node linkType: hard From 126ae0d037fe91c0aaaed1984d757ad793c74d3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:20:16 -0800 Subject: [PATCH 63/81] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.8.0 to 6.11.0 (#2178) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 118 +++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/yarn.lock b/yarn.lock index f43fc978bfd3..e792b8bf5779 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1506,14 +1506,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^6.7.3": - version: 6.8.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.8.0" + version: 6.11.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.11.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.8.0 - "@typescript-eslint/type-utils": 6.8.0 - "@typescript-eslint/utils": 6.8.0 - "@typescript-eslint/visitor-keys": 6.8.0 + "@typescript-eslint/scope-manager": 6.11.0 + "@typescript-eslint/type-utils": 6.11.0 + "@typescript-eslint/utils": 6.11.0 + "@typescript-eslint/visitor-keys": 6.11.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -1526,7 +1526,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: c36ccf606ebcaff8263c4ffa3b4cda58c6f93474b9eea9906e51be2fef8596977a245cc13770b21c6bfd38ccf45a3cf3613d5f4499429f62ec80afe15ae345bd + checksum: 8ba9ce7ce8609a044e405baf57cc84d6973d7676950c870288d7eae2dba44b36664e3f4d90b94a4de08e17259fe8baa7790750cd4e5391dbe2a2743497d7fae2 languageName: node linkType: hard @@ -1585,6 +1585,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/scope-manager@npm:6.11.0" + dependencies: + "@typescript-eslint/types": 6.11.0 + "@typescript-eslint/visitor-keys": 6.11.0 + checksum: d219a96fd80fb14176cdcc47b070e870c73ccc0dfb32a8657f6ceaefb613dc0ea240a77250dcfc437d9c9360ca165c2765d4cf8fe689dae7e9eee2c0d6a98a50 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/scope-manager@npm:6.7.3" @@ -1595,16 +1605,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/scope-manager@npm:6.8.0" - dependencies: - "@typescript-eslint/types": 6.8.0 - "@typescript-eslint/visitor-keys": 6.8.0 - checksum: b6cf2803531d1c14b56c30fd3cd807b80e17fe48d0da8e5aa9ae50915407ed732c7e2a7ac8030b7cf8ed07b8e481a1138d76bf05b727837a0e016280c2f6873b - languageName: node - linkType: hard - "@typescript-eslint/type-utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/type-utils@npm:5.62.0" @@ -1622,12 +1622,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/type-utils@npm:6.8.0" +"@typescript-eslint/type-utils@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/type-utils@npm:6.11.0" dependencies: - "@typescript-eslint/typescript-estree": 6.8.0 - "@typescript-eslint/utils": 6.8.0 + "@typescript-eslint/typescript-estree": 6.11.0 + "@typescript-eslint/utils": 6.11.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -1635,7 +1635,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9b7d56904dc1a5719ef79eb1b7989d6fad10c71fb07ec3e66cf69b8c8dc5383d644ab122d4701bc4960fb7c99cc08aee4e645db3e4675d488d5779197e15dfda + checksum: 2effbe62ae3b12f8a88663072f68a5dcb1135d9ee3c09a0d9fcf49b943837c0a5966e907d4a1a15c27ddf82af2fcf7f6e004655d3e1f7a17c21596469771ff7d languageName: node linkType: hard @@ -1653,6 +1653,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/types@npm:6.11.0" + checksum: ca8a11320286c9b0759a70ec83b9fd99937c9686fafdd41d8ea09ed7b2fa12e6b342bf65547efe5495926cd04cfc6488315920e3caffd27f12d42cb9a8cf88c8 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:6.7.3": version: 6.7.3 resolution: "@typescript-eslint/types@npm:6.7.3" @@ -1660,13 +1667,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/types@npm:6.8.0" - checksum: 1fcd85f6d575116d51c6ee757ed37610ae5e7e4296a29f93c9c6949f6cd16d24550eb7fc5bae7a43119cc08e13836f69a7ae7c54ebba6c95aef96b34d3bfb7f7 - languageName: node - linkType: hard - "@typescript-eslint/typescript-estree@npm:5.59.7": version: 5.59.7 resolution: "@typescript-eslint/typescript-estree@npm:5.59.7" @@ -1703,12 +1703,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.7.3": - version: 6.7.3 - resolution: "@typescript-eslint/typescript-estree@npm:6.7.3" +"@typescript-eslint/typescript-estree@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.11.0" dependencies: - "@typescript-eslint/types": 6.7.3 - "@typescript-eslint/visitor-keys": 6.7.3 + "@typescript-eslint/types": 6.11.0 + "@typescript-eslint/visitor-keys": 6.11.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1717,16 +1717,16 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: eaba1feb0e6882b0bad292172c118aac43ba683d1f04b940b542a20035468d030b062b036ea49eca36aa21782e9b1019e87717003b3c3db7d12dc707466b7eb7 + checksum: e137ba7c4cad08853a44d9c40072496ca5f2d440828be9fd2d207a59db56b05a6dcb4756f3ba341ee2ae714de45df80114477946d30801c5a46eed67314fd9c6 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.8.0" +"@typescript-eslint/typescript-estree@npm:6.7.3": + version: 6.7.3 + resolution: "@typescript-eslint/typescript-estree@npm:6.7.3" dependencies: - "@typescript-eslint/types": 6.8.0 - "@typescript-eslint/visitor-keys": 6.8.0 + "@typescript-eslint/types": 6.7.3 + "@typescript-eslint/visitor-keys": 6.7.3 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1735,7 +1735,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 388db7f33ef1bc0e7b960c0bce9c744c2e32c66c7ab8dfae73d8533958202ad6f31663b0010f79c45b5ff93159c67f45b00693d73b9da2472b17156dfd26b4a8 + checksum: eaba1feb0e6882b0bad292172c118aac43ba683d1f04b940b542a20035468d030b062b036ea49eca36aa21782e9b1019e87717003b3c3db7d12dc707466b7eb7 languageName: node linkType: hard @@ -1757,20 +1757,20 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/utils@npm:6.8.0" +"@typescript-eslint/utils@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/utils@npm:6.11.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.8.0 - "@typescript-eslint/types": 6.8.0 - "@typescript-eslint/typescript-estree": 6.8.0 + "@typescript-eslint/scope-manager": 6.11.0 + "@typescript-eslint/types": 6.11.0 + "@typescript-eslint/typescript-estree": 6.11.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 6d9f90db504502a9aa10e834830c3ffa25483757414670acc6141a3ebef9171a57688a3a179febf35a0e1e0b322f37228d9537bf1b279f1af7fc97888b873bc3 + checksum: e90aa2c8c56038a48de65a5303f9e4a4a70bb0d4d0a05cfcd28157fc0f06b2fc186c2e76a495f4540a903ea37577daa1403bab923d940114ec27a6326153d60f languageName: node linkType: hard @@ -1794,23 +1794,23 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.7.3": - version: 6.7.3 - resolution: "@typescript-eslint/visitor-keys@npm:6.7.3" +"@typescript-eslint/visitor-keys@npm:6.11.0": + version: 6.11.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.11.0" dependencies: - "@typescript-eslint/types": 6.7.3 + "@typescript-eslint/types": 6.11.0 eslint-visitor-keys: ^3.4.1 - checksum: cef64173a919107f420703e204d97d0afef0d9bd7a67570df5bdb39ac9464211c5a7b3af735d8f41e8004b443ab83e88b1d6fb951886aed4d3fe9d4778667199 + checksum: 6aae9dd79963bbefbf2e310015b909627da541a13ab4d8359eea3c86c34fdbb91e583f65b5a99dee1959f7c5d67b21b45e5a05c63ddb4b82dacd60c890ce8b25 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.8.0" +"@typescript-eslint/visitor-keys@npm:6.7.3": + version: 6.7.3 + resolution: "@typescript-eslint/visitor-keys@npm:6.7.3" dependencies: - "@typescript-eslint/types": 6.8.0 + "@typescript-eslint/types": 6.7.3 eslint-visitor-keys: ^3.4.1 - checksum: 710d9067b85d7715a400ae625c083c41733abb891d7b35108de083913980f9642e79d27689599fa39915f0fecae16dbfc30367007fccc838ccd917943660de22 + checksum: cef64173a919107f420703e204d97d0afef0d9bd7a67570df5bdb39ac9464211c5a7b3af735d8f41e8004b443ab83e88b1d6fb951886aed4d3fe9d4778667199 languageName: node linkType: hard From 65a073cdeaa0d34254a59ea22320652421ed3c77 Mon Sep 17 00:00:00 2001 From: Maciej Sulecki Date: Mon, 20 Nov 2023 21:55:11 +0000 Subject: [PATCH 64/81] feat(cargo-make): add cargo-make autocompletion and Makefile.toml support (#2180) --- src/cargo.ts | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/src/cargo.ts b/src/cargo.ts index 6bcbb51c5476..78bdb73b32e5 100644 --- a/src/cargo.ts +++ b/src/cargo.ts @@ -208,6 +208,34 @@ const featuresGenerator: Fig.Generator = { }, }; +const makeTasksGenerator: Fig.Generator = { + custom: async function (tokens, executeCommand) { + let makefileLocation = "Makefile.toml"; + + const makefileFlagIdx = tokens.findIndex((param) => param === "--makefile"); + if (makefileFlagIdx !== -1 && tokens.length > makefileFlagIdx + 1) + makefileLocation = tokens[makefileFlagIdx + 1]; + + const args = [makefileLocation]; + const { stdout } = await executeCommand({ + command: "cat", + args, + }); + + const taskRegex = /\[tasks\.([^\]]+)\]/g; + let match; + const tasks = []; + + while ((match = taskRegex.exec(stdout)) !== null) { + tasks.push({ + name: match[1], + }); + } + + return tasks; + }, +}; + type CrateSearchResults = { crates: Crate[]; }; @@ -7357,6 +7385,171 @@ const completionSpec: (toolchain?: boolean) => Fig.Spec = ( subcommands.push(insta); } + if (commands.includes("make")) { + const make: Fig.Subcommand = { + name: "make", + icon: "🛠", + description: "Rust cargo-make task runner and build tool", + args: { + name: "TASK", + filterStrategy: "fuzzy", + isVariadic: true, + isOptional: true, + generators: makeTasksGenerator, + }, + options: [ + { + name: ["--help", "-h"], + description: "Print help information", + }, + { + name: ["--version", "-V"], + description: "Print version information", + }, + { + name: "--makefile", + description: + "The optional toml file containing the tasks definitions", + args: { name: "FILE", template: "filepaths" }, + }, + { + name: ["--task", "-t"], + description: "The task name to execute", + args: { + name: "TASK", + filterStrategy: "fuzzy", + isVariadic: true, + isOptional: true, + generators: makeTasksGenerator, + }, + }, + { + name: ["--profile", "-p"], + description: "The profile name", + args: { name: "PROFILE", default: "development" }, + }, + { + name: "--cwd", + description: "Set the current working directory", + args: { name: "DIRECTORY", template: "folders" }, + }, + { + name: "--no-workspace", + description: "Disable workspace support", + }, + { + name: "--no-on-error", + description: + "Disable on error flow even if defined in config sections", + }, + { + name: "--allow-private", + description: "Allow invocation of private tasks", + }, + { + name: "--skip-init-end-tasks", + description: "If set, init and end tasks are skipped", + }, + { + name: "--skip-tasks", + description: "Skip all tasks that match the provided regex", + args: { name: "SKIP_TASK_PATTERNS" }, + }, + { + name: "--env-file", + description: "Set environment variables from provided file", + args: { name: "FILE", template: "filepaths" }, + }, + { + name: ["--env", "-e"], + description: "Set environment variables", + args: { name: "ENV" }, + }, + { + name: ["--loglevel", "-l"], + description: "The log level", + args: { + name: "LOG LEVEL", + suggestions: ["verbose", "info", "error", "off"], + }, + }, + { + name: ["--verbose", "-v"], + description: "Sets the log level to verbose", + }, + { + name: "--quiet", + description: "Sets the log level to error", + }, + { + name: "--silent", + description: "Sets the log level to off", + }, + { + name: "--no-color", + description: "Disables colorful output", + }, + { + name: "--time-summary", + description: "Print task level time summary at end of flow", + }, + { + name: "--experimental", + description: + "Allows access to unsupported experimental predefined tasks", + }, + { + name: "--disable-check-for-updates", + description: "Disables the update check during startup", + }, + { + name: "--output-format", + description: "The print/list steps format", + args: { + name: "OUTPUT FORMAT", + suggestions: [ + "default", + "short-description", + "markdown", + "markdown-single-page", + "markdown-sub-section", + "autocomplete", + ], + }, + }, + { + name: "--output-file", + description: "The list steps output file name", + args: { name: "OUTPUT_FILE", template: "filepaths" }, + }, + { + name: "--hide-uninteresting", + description: "Hide any minor tasks such as pre/post hooks", + }, + { + name: "--print-steps", + description: + "Only prints the steps of the build in the order they will be invoked but without invoking them", + }, + { + name: "--list-all-steps", + description: "Lists all known steps", + }, + { + name: "--list-category-steps", + description: "List steps for a given category", + args: { name: "CATEGORY" }, + }, + { + name: "--diff-steps", + description: + "Runs diff between custom flow and prebuilt flow (requires git)", + }, + ], + }; + subcommands.push(make); + } + return { name: "cargo", subcommands, From 80d2d3ff9f43a45aaab057c6cd2a9393a9f73919 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Mon, 20 Nov 2023 21:56:26 +0000 Subject: [PATCH 65/81] ci: version bump to 2.641.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f88ea553a8e3..68bb96f96c1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.640.4", + "version": "2.641.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 5a33b786e4343a27fb0475cbba061b1b68f46f96 Mon Sep 17 00:00:00 2001 From: Grant G Date: Mon, 20 Nov 2023 14:11:35 -0800 Subject: [PATCH 66/81] fix(cw): Typos and generator issue (#2181) --- src/cw.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cw.ts b/src/cw.ts index e6cb2ee77765..84286360f85a 100644 --- a/src/cw.ts +++ b/src/cw.ts @@ -1,5 +1,5 @@ export const themesGenerator: Fig.Generator = { - script: ["fig", "theme", "--list"], + script: ["cw", "theme", "--list"], postProcess: (output) => { const builtinThemes: Fig.Suggestion[] = [ { @@ -21,9 +21,9 @@ export const themesGenerator: Fig.Generator = { return output .split("\n") .map( - (theme) => + (name) => ({ - name: theme.replace(".json", ""), + name, icon: "🎨", }) as Fig.Suggestion ) @@ -992,11 +992,11 @@ const completion: Fig.Spec = { }, { name: "tips", - description: "Enable/disable fig tips", + description: "Enable/disable CodeWhisperer tips", subcommands: [ { name: "enable", - description: "Enable fig tips", + description: "Enable CodeWhisperer tips", options: [ { name: ["-h", "--help"], @@ -1006,7 +1006,7 @@ const completion: Fig.Spec = { }, { name: "disable", - description: "Disable fig tips", + description: "Disable CodeWhisperer tips", options: [ { name: ["-h", "--help"], @@ -1043,11 +1043,11 @@ const completion: Fig.Spec = { subcommands: [ { name: "enable", - description: "Enable fig tips", + description: "Enable CodeWhisperer tips", }, { name: "disable", - description: "Disable fig tips", + description: "Disable CodeWhisperer tips", }, { name: "reset", @@ -1076,7 +1076,7 @@ const completion: Fig.Spec = { }, { name: "install", - description: "Install fig cli components", + description: "Install CodeWhisperer cli components", options: [ { name: "--daemon", @@ -1096,7 +1096,7 @@ const completion: Fig.Spec = { }, { name: "--force", - description: "Force installation of fig", + description: "Force installation of CodeWhisperer", }, { name: "--ssh", @@ -1110,7 +1110,7 @@ const completion: Fig.Spec = { }, { name: "uninstall", - description: "Uninstall fig", + description: "Uninstall CodeWhisperer", hidden: true, options: [ { @@ -1328,7 +1328,7 @@ const completion: Fig.Spec = { }, { name: "user", - description: "Manage your fig user", + description: "Manage your CodeWhisperer user", subcommands: [ { name: "login", @@ -1474,7 +1474,7 @@ const completion: Fig.Spec = { { name: "pre-cmd", description: - "Command that is run during the PreCmd section of the fig integrations", + "Command that is run during the PreCmd section of the CodeWhisperer integrations", options: [ { name: "--alias", From a6f5441b5d5cc9c4474b55150dbd83bf0112ad9a Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Mon, 20 Nov 2023 22:12:57 +0000 Subject: [PATCH 67/81] ci: version bump to 2.641.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 68bb96f96c1e..a5603edec85d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.641.0", + "version": "2.641.1", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From ef61687bd557023b7b1b68a452bb7d58c9458afb Mon Sep 17 00:00:00 2001 From: Yashwin <49670540+Yashwin-Sudarshan@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:40:34 +1100 Subject: [PATCH 68/81] feat(cut): add -w flag (#2175) --- src/cut.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cut.ts b/src/cut.ts index 81a37f1cb8e2..decdb7a37181 100644 --- a/src/cut.ts +++ b/src/cut.ts @@ -50,6 +50,11 @@ const completionSpec: Fig.Spec = { description: "Suppress lines with no field delimiter characters. unless specified, lines with no delimiters are passed through unmodified", }, + { + name: "-w", + description: + "Use whitespace (spaces and tabs) as the delimiter. Consecutive spaces and tabs count as one single field separator", + }, ], }; From 9bd370c2aa8aae482680664a3a32c47888a7462f Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Tue, 21 Nov 2023 01:41:53 +0000 Subject: [PATCH 69/81] ci: version bump to 2.642.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a5603edec85d..0fcf2f92c1cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.641.1", + "version": "2.642.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From 2a22062da5e8a513357355261b53e8dc3c2627a6 Mon Sep 17 00:00:00 2001 From: figbot <82115609+withfig-bot@users.noreply.github.com> Date: Wed, 22 Nov 2023 04:08:50 -0800 Subject: [PATCH 70/81] @overbit has signed the CLA in withfig/autocomplete#2182 --- cla/signatures.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cla/signatures.json b/cla/signatures.json index 202849df47a0..8dfba1311f80 100644 --- a/cla/signatures.json +++ b/cla/signatures.json @@ -1071,6 +1071,14 @@ "created_at": "2023-11-20T14:38:12Z", "repoId": 299482335, "pullRequestNo": 2180 + }, + { + "name": "overbit", + "id": 2861984, + "comment_id": 1822651876, + "created_at": "2023-11-22T12:08:24Z", + "repoId": 299482335, + "pullRequestNo": 2182 } ] } \ No newline at end of file From af0cdaec4898583957541a7dd964924fa0bb357a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:32:04 -0800 Subject: [PATCH 71/81] build(deps-dev): bump typescript from 5.0.4 to 5.3.2 (#2187) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 0fcf2f92c1cb..6faf3f51953e 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "progress": "^2.0.3", "tailwindcss": "^3.3.3", "ts-node": "^10.9.1", - "typescript": "~5.0.0", + "typescript": "~5.3.2", "vite": "^4.4.9", "vite-plugin-externals": "^0.6.2" }, diff --git a/yarn.lock b/yarn.lock index e792b8bf5779..993da5310c46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1926,7 +1926,7 @@ __metadata: strip-json-comments: ^5.0.1 tailwindcss: ^3.3.3 ts-node: ^10.9.1 - typescript: ~5.0.0 + typescript: ~5.3.2 vite: ^4.4.9 vite-plugin-externals: ^0.6.2 yaml: ^2.3.2 @@ -7111,13 +7111,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.0.0": - version: 5.0.4 - resolution: "typescript@npm:5.0.4" +"typescript@npm:~5.3.2": + version: 5.3.2 + resolution: "typescript@npm:5.3.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 + checksum: d92534dda639eb825db013203404c1fabca8ac630564283c9e7dc9e64fd9c9346c2de95ecebdf3e6e8c1c32941bca1cfe0da37877611feb9daf8feeaea58d230 languageName: node linkType: hard @@ -7131,13 +7131,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@~5.0.0#~builtin": - version: 5.0.4 - resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" +"typescript@patch:typescript@~5.3.2#~builtin": + version: 5.3.2 + resolution: "typescript@patch:typescript@npm%3A5.3.2#~builtin::version=5.3.2&hash=77c9e2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac + checksum: c034461079fbfde3cb584ddee52afccb15b6e32a0ce186d0b2719968786f7ca73e1b07f71fac4163088790b16811c6ccf79680de190664ef66ff0ba9c1fe4a23 languageName: node linkType: hard From 0f35a7d03430ab87e6a4802557ab42e6425965e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:32:24 -0800 Subject: [PATCH 72/81] build(deps-dev): bump tailwindcss from 3.3.3 to 3.3.5 (#2186) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/yarn.lock b/yarn.lock index 993da5310c46..4839597b1317 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3960,7 +3960,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9": +"fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9": version: 3.2.12 resolution: "fast-glob@npm:3.2.12" dependencies: @@ -3973,6 +3973,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.3.0": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.4 + checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 + languageName: node + linkType: hard + "fast-json-patch@npm:^3.0.0-1": version: 3.1.1 resolution: "fast-json-patch@npm:3.1.1" @@ -4765,12 +4778,12 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.18.2": - version: 1.18.2 - resolution: "jiti@npm:1.18.2" +"jiti@npm:^1.19.1": + version: 1.21.0 + resolution: "jiti@npm:1.21.0" bin: jiti: bin/jiti.js - checksum: 46c41cd82d01c6efdee3fc0ae9b3e86ed37457192d6366f19157d863d64961b07982ab04e9d5879576a1af99cc4d132b0b73b336094f86a5ce9fb1029ec2d29f + checksum: a7bd5d63921c170eaec91eecd686388181c7828e1fa0657ab374b9372bfc1f383cf4b039e6b272383d5cb25607509880af814a39abdff967322459cca41f2961 languageName: node linkType: hard @@ -6885,18 +6898,18 @@ __metadata: linkType: hard "tailwindcss@npm:^3.3.3": - version: 3.3.3 - resolution: "tailwindcss@npm:3.3.3" + version: 3.3.5 + resolution: "tailwindcss@npm:3.3.5" dependencies: "@alloc/quick-lru": ^5.2.0 arg: ^5.0.2 chokidar: ^3.5.3 didyoumean: ^1.2.2 dlv: ^1.1.3 - fast-glob: ^3.2.12 + fast-glob: ^3.3.0 glob-parent: ^6.0.2 is-glob: ^4.0.3 - jiti: ^1.18.2 + jiti: ^1.19.1 lilconfig: ^2.1.0 micromatch: ^4.0.5 normalize-path: ^3.0.0 @@ -6913,7 +6926,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: 0195c7a3ebb0de5e391d2a883d777c78a4749f0c532d204ee8aea9129f2ed8e701d8c0c276aa5f7338d07176a3c2a7682c1d0ab9c8a6c2abe6d9325c2954eb50 + checksum: e04bb3bb7f9f17e9b6db0c7ace755ef0d6d05bff36ebeb9e5006e13c018ed5566f09db30a1a34380e38fa93ebbb4ae0e28fe726879d5e9ddd8c5b52bffd26f14 languageName: node linkType: hard From fc4d2043fb23c25469c792d970f9c7ed0e1cd01d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:32:34 -0800 Subject: [PATCH 73/81] build(deps-dev): bump @types/react from 18.2.28 to 18.2.38 (#2184) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4839597b1317..a0ff14f3a5a6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1441,13 +1441,13 @@ __metadata: linkType: hard "@types/react@npm:*, @types/react@npm:^18.2.23": - version: 18.2.28 - resolution: "@types/react@npm:18.2.28" + version: 18.2.38 + resolution: "@types/react@npm:18.2.38" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: 81381bedeba83278f4c9febb0b83e0bd3f42a25897a50b9cb36ef53651d34b3d50f87ebf11211ea57ea575131f85d31e93e496ce46478a00b0f9bf7b26b5917a + checksum: 71f8c167173d32252be8b2d3c1c76b3570b94d2fbbd139da86d146be453626f5777e12c2781559119637520dbef9f91cffe968f67b5901618f29226d49fad326 languageName: node linkType: hard From 443fd92f153549466b46c2a54d83b2bd4a8eec49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:32:49 -0800 Subject: [PATCH 74/81] build(deps-dev): bump @typescript-eslint/eslint-plugin from 6.11.0 to 6.12.0 (#2183) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 82 +++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/yarn.lock b/yarn.lock index a0ff14f3a5a6..f07c8e9d81b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1506,14 +1506,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^6.7.3": - version: 6.11.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.11.0" + version: 6.12.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.12.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.11.0 - "@typescript-eslint/type-utils": 6.11.0 - "@typescript-eslint/utils": 6.11.0 - "@typescript-eslint/visitor-keys": 6.11.0 + "@typescript-eslint/scope-manager": 6.12.0 + "@typescript-eslint/type-utils": 6.12.0 + "@typescript-eslint/utils": 6.12.0 + "@typescript-eslint/visitor-keys": 6.12.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -1526,7 +1526,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 8ba9ce7ce8609a044e405baf57cc84d6973d7676950c870288d7eae2dba44b36664e3f4d90b94a4de08e17259fe8baa7790750cd4e5391dbe2a2743497d7fae2 + checksum: a791ebe432a6cac50a15c9e98502b62e874de0c7e35fd320b9bdca21afd4ae88c88cff45ee50a95362da14e98965d946e57b15965f5522f1153568a3fe45db8a languageName: node linkType: hard @@ -1585,13 +1585,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/scope-manager@npm:6.11.0" +"@typescript-eslint/scope-manager@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/scope-manager@npm:6.12.0" dependencies: - "@typescript-eslint/types": 6.11.0 - "@typescript-eslint/visitor-keys": 6.11.0 - checksum: d219a96fd80fb14176cdcc47b070e870c73ccc0dfb32a8657f6ceaefb613dc0ea240a77250dcfc437d9c9360ca165c2765d4cf8fe689dae7e9eee2c0d6a98a50 + "@typescript-eslint/types": 6.12.0 + "@typescript-eslint/visitor-keys": 6.12.0 + checksum: 4cc4eb1bcd04ba7b0a1de4284521cde5f3f25f2530f78dfcb3f098396b142fd30a45f615a87dc7a3adddbd131a6255cb12b1df19aacff71a3f766992ddef183f languageName: node linkType: hard @@ -1622,12 +1622,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/type-utils@npm:6.11.0" +"@typescript-eslint/type-utils@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/type-utils@npm:6.12.0" dependencies: - "@typescript-eslint/typescript-estree": 6.11.0 - "@typescript-eslint/utils": 6.11.0 + "@typescript-eslint/typescript-estree": 6.12.0 + "@typescript-eslint/utils": 6.12.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -1635,7 +1635,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 2effbe62ae3b12f8a88663072f68a5dcb1135d9ee3c09a0d9fcf49b943837c0a5966e907d4a1a15c27ddf82af2fcf7f6e004655d3e1f7a17c21596469771ff7d + checksum: c345c45f1262eee4b9f6960a59b3aba960643d0004094a3d8fb9682ab79af2fae864695029246dc9e0d4fdb2f3d017a56b7dc034e551d263deba75c2ef048d39 languageName: node linkType: hard @@ -1653,10 +1653,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/types@npm:6.11.0" - checksum: ca8a11320286c9b0759a70ec83b9fd99937c9686fafdd41d8ea09ed7b2fa12e6b342bf65547efe5495926cd04cfc6488315920e3caffd27f12d42cb9a8cf88c8 +"@typescript-eslint/types@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/types@npm:6.12.0" + checksum: d3b40f9d400f6455ce5ae610651597c9e9ec85d46ca6d3c1025597a76305c557ebc5b88340ec6db0e694c9c79f1299d375b87a1a5b9314b22231dbbb5ce54695 languageName: node linkType: hard @@ -1703,12 +1703,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.11.0" +"@typescript-eslint/typescript-estree@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.12.0" dependencies: - "@typescript-eslint/types": 6.11.0 - "@typescript-eslint/visitor-keys": 6.11.0 + "@typescript-eslint/types": 6.12.0 + "@typescript-eslint/visitor-keys": 6.12.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -1717,7 +1717,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: e137ba7c4cad08853a44d9c40072496ca5f2d440828be9fd2d207a59db56b05a6dcb4756f3ba341ee2ae714de45df80114477946d30801c5a46eed67314fd9c6 + checksum: 943f7ff2e164d812f6ae0a2d5096836aff00b1fda39937b03f126f266f03f3655794f5fc4643b49b71c312126d9422dfd764744bd1ba41ee6821a5bac1511aa2 languageName: node linkType: hard @@ -1757,20 +1757,20 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/utils@npm:6.11.0" +"@typescript-eslint/utils@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/utils@npm:6.12.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.11.0 - "@typescript-eslint/types": 6.11.0 - "@typescript-eslint/typescript-estree": 6.11.0 + "@typescript-eslint/scope-manager": 6.12.0 + "@typescript-eslint/types": 6.12.0 + "@typescript-eslint/typescript-estree": 6.12.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: e90aa2c8c56038a48de65a5303f9e4a4a70bb0d4d0a05cfcd28157fc0f06b2fc186c2e76a495f4540a903ea37577daa1403bab923d940114ec27a6326153d60f + checksum: dad05bd0e4db7a88c2716f9ee83c7c28c30d71e57392e58dc0db66b5f5c4c86b9db14142c6a1a82cf1650da294d31980c56a118015d3a2a645acb8b8a5ebc315 languageName: node linkType: hard @@ -1794,13 +1794,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.11.0" +"@typescript-eslint/visitor-keys@npm:6.12.0": + version: 6.12.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.12.0" dependencies: - "@typescript-eslint/types": 6.11.0 + "@typescript-eslint/types": 6.12.0 eslint-visitor-keys: ^3.4.1 - checksum: 6aae9dd79963bbefbf2e310015b909627da541a13ab4d8359eea3c86c34fdbb91e583f65b5a99dee1959f7c5d67b21b45e5a05c63ddb4b82dacd60c890ce8b25 + checksum: 3d8dc74ae748a95fe60b48dbaecca8d9c0c8df344d8034e3843057251fba24f06a3d29dbb9f525c9540b538d8c24221d3cf119ac483e9de38149a978051c72f3 languageName: node linkType: hard From 0fdb30371b40e0a8b35d27096f24c1f9553a539f Mon Sep 17 00:00:00 2001 From: Daniele Iasella <2861984+overbit@users.noreply.github.com> Date: Thu, 30 Nov 2023 21:33:48 +0000 Subject: [PATCH 75/81] fix(nx): cache generation issue due to wrong shell command (#2182) --- src/nx.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nx.ts b/src/nx.ts index 81c56966577b..502e0949ca3e 100644 --- a/src/nx.ts +++ b/src/nx.ts @@ -140,11 +140,12 @@ const preProcessProjects = async ( ).workspaceLayout, }; const searchFolders = - appsDir === libsDir ? appsDir : `${appsDir} ${libsDir}`; + appsDir === libsDir ? [appsDir] : [appsDir, libsDir]; + nxProjectPathCache = ( await executeShellCommand({ command: "find", - args: [searchFolders, "-name", "project.json"], + args: [...searchFolders, "-name", "project.json"], }) ).stdout .split("\n") From 542e839168fa50d721f874a5aa85f90099bc6fa4 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Thu, 30 Nov 2023 21:35:01 +0000 Subject: [PATCH 76/81] ci: version bump to 2.642.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6faf3f51953e..9b80c7beafa3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.642.0", + "version": "2.642.1", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From f2ba814ef18f8c29416671a6dd9fdf128695bc01 Mon Sep 17 00:00:00 2001 From: Cassey Shao <60023562+casseyshao@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:40:52 -0500 Subject: [PATCH 77/81] Add help option description to vi (#2167) --- src/vi.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vi.ts b/src/vi.ts index 2b08f272a225..5f9b40b78e86 100644 --- a/src/vi.ts +++ b/src/vi.ts @@ -5,6 +5,12 @@ const completionSpec: Fig.Spec = { args: { template: "filepaths", }, + options: [ + { + name: ["-h", "--help"], + description: "Print help message for vi and exit", + }, + ], }; export default completionSpec; From 3d34126184d17ce1f28217e852f8ff0d9e50045a Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 30 Nov 2023 18:41:46 -0300 Subject: [PATCH 78/81] feat(goreleaser): update spec (#2165) --- src/goreleaser.ts | 62 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/src/goreleaser.ts b/src/goreleaser.ts index 67cd4b9c58f7..4f3f5244ab7f 100644 --- a/src/goreleaser.ts +++ b/src/goreleaser.ts @@ -48,12 +48,28 @@ const completionSpec: Fig.Spec = { description: "Builds only for current GOOS and GOARCH, regardless of what's set in the configuration file", }, - { name: "--skip-before", description: "Skips global before hooks" }, + { + name: "--skip", + description: + "Skip the given options (valid options are before, post-hooks, pre-hooks, validate)", + isRepeatable: true, + args: { name: "skip" }, + }, + { + name: "--skip-before", + description: "Skips global before hooks", + hidden: true, + }, { name: "--skip-post-hooks", description: "Skips all post-build hooks", + hidden: true, + }, + { + name: "--skip-validate", + description: "Skips several sanity checks", + hidden: true, }, - { name: "--skip-validate", description: "Skips several sanity checks" }, { name: "--snapshot", description: @@ -238,27 +254,53 @@ const completionSpec: Fig.Spec = { description: "Removes the dist folder", hidden: true, }, + { + name: "--skip", + description: + "Skip the given options (valid options are announce, aur, before, docker, homebrew, ko, nix, publish, sbom, scoop, sign, snapcraft, validate, winget)", + isRepeatable: true, + args: { name: "skip" }, + }, { name: "--skip-announce", - description: "Skips announcing releases (implies --skip-validate)", + description: "Skips announcing releases (implies --skip=validate)", + hidden: true, + }, + { + name: "--skip-before", + description: "Skips global before hooks", + hidden: true, }, - { name: "--skip-before", description: "Skips global before hooks" }, { name: "--skip-docker", description: "Skips Docker Images/Manifests builds", + hidden: true, }, - { name: "--skip-ko", description: "Skips Ko builds" }, + { name: "--skip-ko", description: "Skips Ko builds", hidden: true }, { name: "--skip-publish", - description: "Skips publishing artifacts (implies --skip-announce)", + description: "Skips publishing artifacts (implies --skip=announce)", + hidden: true, + }, + { + name: "--skip-sbom", + description: "Skips cataloging artifacts", + hidden: true, + }, + { + name: "--skip-sign", + description: "Skips signing artifacts", + hidden: true, + }, + { + name: "--skip-validate", + description: "Skips git checks", + hidden: true, }, - { name: "--skip-sbom", description: "Skips cataloging artifacts" }, - { name: "--skip-sign", description: "Skips signing artifacts" }, - { name: "--skip-validate", description: "Skips git checks" }, { name: "--snapshot", description: - "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts (implies --skip-publish, --skip-announce and --skip-validate)", + "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts (implies --skip=announce,publish,validate)", }, { name: "--timeout", From 71aea171c78a3164eb43742ff7158747daf7c8e8 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Thu, 30 Nov 2023 21:42:55 +0000 Subject: [PATCH 79/81] ci: version bump to 2.643.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9b80c7beafa3..e12828e11a84 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.642.1", + "version": "2.643.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index", From c49d2bcc89b484df15ad567010537d9c5680ecfd Mon Sep 17 00:00:00 2001 From: Jesse Greer <64601257+gnosticdev@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:44:21 -0500 Subject: [PATCH 80/81] feat(bun): add subcommands, options, logo (#2132) Co-authored-by: gnostic <64601257+nynxa@users.noreply.github.com> --- src/bun.ts | 868 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 682 insertions(+), 186 deletions(-) diff --git a/src/bun.ts b/src/bun.ts index 0069180a1d62..dfbe1cba77ae 100644 --- a/src/bun.ts +++ b/src/bun.ts @@ -1,4 +1,8 @@ -import { keyValueList, filepaths } from "@fig/autocomplete-generators"; +import { + keyValueList, + filepaths, + valueList, +} from "@fig/autocomplete-generators"; import { npmScriptsGenerator, npmSearchGenerator, @@ -7,6 +11,453 @@ import { import { npxSuggestions } from "./npx"; import { createCLIsGenerator } from "./yarn"; +const icon = + "data:image/svg+xml;base64,PHN2ZyBpZD0iQnVuIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MCA3MCI+PHRpdGxlPkJ1biBMb2dvPC90aXRsZT48cGF0aCBpZD0iU2hhZG93IiBkPSJNNzEuMDksMjAuNzRjLS4xNi0uMTctLjMzLS4zNC0uNS0uNXMtLjMzLS4zNC0uNS0uNS0uMzMtLjM0LS41LS41LS4zMy0uMzQtLjUtLjUtLjMzLS4zNC0uNS0uNS0uMzMtLjM0LS41LS41LS4zMy0uMzQtLjUtLjVBMjYuNDYsMjYuNDYsMCwwLDEsNzUuNSwzNS43YzAsMTYuNTctMTYuODIsMzAuMDUtMzcuNSwzMC4wNS0xMS41OCwwLTIxLjk0LTQuMjMtMjguODMtMTAuODZsLjUuNS41LjUuNS41LjUuNS41LjUuNS41LjUuNUMxOS41NSw2NS4zLDMwLjE0LDY5Ljc1LDQyLDY5Ljc1YzIwLjY4LDAsMzcuNS0xMy40OCwzNy41LTMwQzc5LjUsMzIuNjksNzYuNDYsMjYsNzEuMDksMjAuNzRaIi8+PGcgaWQ9IkJvZHkiPjxwYXRoIGlkPSJCYWNrZ3JvdW5kIiBkPSJNNzMsMzUuN2MwLDE1LjIxLTE1LjY3LDI3LjU0LTM1LDI3LjU0UzMsNTAuOTEsMywzNS43QzMsMjYuMjcsOSwxNy45NCwxOC4yMiwxM1MzMy4xOCwzLDM4LDNzOC45NCw0LjEzLDE5Ljc4LDEwQzY3LDE3Ljk0LDczLDI2LjI3LDczLDM1LjdaIiBzdHlsZT0iZmlsbDojZmJmMGRmIi8+PHBhdGggaWQ9IkJvdHRvbV9TaGFkb3ciIGRhdGEtbmFtZT0iQm90dG9tIFNoYWRvdyIgZD0iTTczLDM1LjdhMjEuNjcsMjEuNjcsMCwwLDAtLjgtNS43OGMtMi43MywzMy4zLTQzLjM1LDM0LjktNTkuMzIsMjQuOTRBNDAsNDAsMCwwLDAsMzgsNjMuMjRDNTcuMyw2My4yNCw3Myw1MC44OSw3MywzNS43WiIgc3R5bGU9ImZpbGw6I2Y2ZGVjZSIvPjxwYXRoIGlkPSJMaWdodF9TaGluZSIgZGF0YS1uYW1lPSJMaWdodCBTaGluZSIgZD0iTTI0LjUzLDExLjE3QzI5LDguNDksMzQuOTQsMy40Niw0MC43OCwzLjQ1QTkuMjksOS4yOSwwLDAsMCwzOCwzYy0yLjQyLDAtNSwxLjI1LTguMjUsMy4xMy0xLjEzLjY2LTIuMywxLjM5LTMuNTQsMi4xNS0yLjMzLDEuNDQtNSwzLjA3LTgsNC43QzguNjksMTguMTMsMywyNi42MiwzLDM1LjdjMCwuNCwwLC44LDAsMS4xOUM5LjA2LDE1LjQ4LDIwLjA3LDEzLjg1LDI0LjUzLDExLjE3WiIgc3R5bGU9ImZpbGw6I2ZmZmVmYyIvPjxwYXRoIGlkPSJUb3AiIGQ9Ik0zNS4xMiw1LjUzQTE2LjQxLDE2LjQxLDAsMCwxLDI5LjQ5LDE4Yy0uMjguMjUtLjA2LjczLjMuNTksMy4zNy0xLjMxLDcuOTItNS4yMyw2LTEzLjE0QzM1LjcxLDUsMzUuMTIsNS4xMiwzNS4xMiw1LjUzWm0yLjI3LDBBMTYuMjQsMTYuMjQsMCwwLDEsMzksMTljLS4xMi4zNS4zMS42NS41NS4zNkM0MS43NCwxNi41Niw0My42NSwxMSwzNy45Myw1LDM3LjY0LDQuNzQsMzcuMTksNS4xNCwzNy4zOSw1LjQ5Wm0yLjc2LS4xN0ExNi40MiwxNi40MiwwLDAsMSw0NywxNy4xMmEuMzMuMzMsMCwwLDAsLjY1LjExYy45Mi0zLjQ5LjQtOS40NC03LjE3LTEyLjUzQzQwLjA4LDQuNTQsMzkuODIsNS4wOCw0MC4xNSw1LjMyWk0yMS42OSwxNS43NmExNi45NCwxNi45NCwwLDAsMCwxMC40Ny05Yy4xOC0uMzYuNzUtLjIyLjY2LjE4LTEuNzMsOC03LjUyLDkuNjctMTEuMTIsOS40NUMyMS4zMiwxNi40LDIxLjMzLDE1Ljg3LDIxLjY5LDE1Ljc2WiIgc3R5bGU9ImZpbGw6I2NjYmVhNztmaWxsLXJ1bGU6ZXZlbm9kZCIvPjxwYXRoIGlkPSJPdXRsaW5lIiBkPSJNMzgsNjUuNzVDMTcuMzIsNjUuNzUuNSw1Mi4yNy41LDM1LjdjMC0xMCw2LjE4LTE5LjMzLDE2LjUzLTI0LjkyLDMtMS42LDUuNTctMy4yMSw3Ljg2LTQuNjIsMS4yNi0uNzgsMi40NS0xLjUxLDMuNi0yLjE5QzMyLDEuODksMzUsLjUsMzgsLjVzNS42MiwxLjIsOC45LDMuMTRjMSwuNTcsMiwxLjE5LDMuMDcsMS44NywyLjQ5LDEuNTQsNS4zLDMuMjgsOSw1LjI3QzY5LjMyLDE2LjM3LDc1LjUsMjUuNjksNzUuNSwzNS43LDc1LjUsNTIuMjcsNTguNjgsNjUuNzUsMzgsNjUuNzVaTTM4LDNjLTIuNDIsMC01LDEuMjUtOC4yNSwzLjEzLTEuMTMuNjYtMi4zLDEuMzktMy41NCwyLjE1LTIuMzMsMS40NC01LDMuMDctOCw0LjdDOC42OSwxOC4xMywzLDI2LjYyLDMsMzUuNywzLDUwLjg5LDE4LjcsNjMuMjUsMzgsNjMuMjVTNzMsNTAuODksNzMsMzUuN0M3MywyNi42Miw2Ny4zMSwxOC4xMyw1Ny43OCwxMyw1NCwxMSw1MS4wNSw5LjEyLDQ4LjY2LDcuNjRjLTEuMDktLjY3LTIuMDktMS4yOS0zLTEuODRDNDIuNjMsNCw0MC40MiwzLDM4LDNaIi8+PC9nPjxnIGlkPSJNb3V0aCI+PGcgaWQ9IkJhY2tncm91bmQtMiIgZGF0YS1uYW1lPSJCYWNrZ3JvdW5kIj48cGF0aCBkPSJNNDUuMDUsNDNhOC45Myw4LjkzLDAsMCwxLTIuOTIsNC43MSw2LjgxLDYuODEsMCwwLDEtNCwxLjg4QTYuODQsNi44NCwwLDAsMSwzNCw0Ny43MSw4LjkzLDguOTMsMCwwLDEsMzEuMTIsNDNhLjcyLjcyLDAsMCwxLC44LS44MUg0NC4yNkEuNzIuNzIsMCwwLDEsNDUuMDUsNDNaIiBzdHlsZT0iZmlsbDojYjcxNDIyIi8+PC9nPjxnIGlkPSJUb25ndWUiPjxwYXRoIGlkPSJCYWNrZ3JvdW5kLTMiIGRhdGEtbmFtZT0iQmFja2dyb3VuZCIgZD0iTTM0LDQ3Ljc5YTYuOTEsNi45MSwwLDAsMCw0LjEyLDEuOSw2LjkxLDYuOTEsMCwwLDAsNC4xMS0xLjksMTAuNjMsMTAuNjMsMCwwLDAsMS0xLjA3LDYuODMsNi44MywwLDAsMC00LjktMi4zMSw2LjE1LDYuMTUsMCwwLDAtNSwyLjc4QzMzLjU2LDQ3LjQsMzMuNzYsNDcuNiwzNCw0Ny43OVoiIHN0eWxlPSJmaWxsOiNmZjYxNjQiLz48cGF0aCBpZD0iT3V0bGluZS0yIiBkYXRhLW5hbWU9Ik91dGxpbmUiIGQ9Ik0zNC4xNiw0N2E1LjM2LDUuMzYsMCwwLDEsNC4xOS0yLjA4LDYsNiwwLDAsMSw0LDEuNjljLjIzLS4yNS40NS0uNTEuNjYtLjc3YTcsNywwLDAsMC00LjcxLTEuOTMsNi4zNiw2LjM2LDAsMCwwLTQuODksMi4zNkE5LjUzLDkuNTMsMCwwLDAsMzQuMTYsNDdaIi8+PC9nPjxwYXRoIGlkPSJPdXRsaW5lLTMiIGRhdGEtbmFtZT0iT3V0bGluZSIgZD0iTTM4LjA5LDUwLjE5YTcuNDIsNy40MiwwLDAsMS00LjQ1LTIsOS41Miw5LjUyLDAsMCwxLTMuMTEtNS4wNSwxLjIsMS4yLDAsMCwxLC4yNi0xLDEuNDEsMS40MSwwLDAsMSwxLjEzLS41MUg0NC4yNmExLjQ0LDEuNDQsMCwwLDEsMS4xMy41MSwxLjE5LDEuMTksMCwwLDEsLjI1LDFoMGE5LjUyLDkuNTIsMCwwLDEtMy4xMSw1LjA1QTcuNDIsNy40MiwwLDAsMSwzOC4wOSw1MC4xOVptLTYuMTctNy40Yy0uMTYsMC0uMi4wNy0uMjEuMDlhOC4yOSw4LjI5LDAsMCwwLDIuNzMsNC4zN0E2LjIzLDYuMjMsMCwwLDAsMzguMDksNDlhNi4yOCw2LjI4LDAsMCwwLDMuNjUtMS43Myw4LjMsOC4zLDAsMCwwLDIuNzItNC4zNy4yMS4yMSwwLDAsMC0uMi0uMDlaIi8+PC9nPjxnIGlkPSJGYWNlIj48ZWxsaXBzZSBpZD0iUmlnaHRfQmx1c2giIGRhdGEtbmFtZT0iUmlnaHQgQmx1c2giIGN4PSI1My4yMiIgY3k9IjQwLjE4IiByeD0iNS44NSIgcnk9IjMuNDQiIHN0eWxlPSJmaWxsOiNmZWJiZDAiLz48ZWxsaXBzZSBpZD0iTGVmdF9CbHVjaCIgZGF0YS1uYW1lPSJMZWZ0IEJsdWNoIiBjeD0iMjIuOTUiIGN5PSI0MC4xOCIgcng9IjUuODUiIHJ5PSIzLjQ0IiBzdHlsZT0iZmlsbDojZmViYmQwIi8+PHBhdGggaWQ9IkV5ZXMiIGQ9Ik0yNS43LDM4LjhhNS41MSw1LjUxLDAsMSwwLTUuNS01LjUxQTUuNTEsNS41MSwwLDAsMCwyNS43LDM4LjhabTI0Ljc3LDBBNS41MSw1LjUxLDAsMSwwLDQ1LDMzLjI5LDUuNSw1LjUsMCwwLDAsNTAuNDcsMzguOFoiIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZCIvPjxwYXRoIGlkPSJJcmlzIiBkPSJNMjQsMzMuNjRhMi4wNywyLjA3LDAsMSwwLTIuMDYtMi4wN0EyLjA3LDIuMDcsMCwwLDAsMjQsMzMuNjRabTI0Ljc3LDBhMi4wNywyLjA3LDAsMSwwLTIuMDYtMi4wN0EyLjA3LDIuMDcsMCwwLDAsNDguNzUsMzMuNjRaIiBzdHlsZT0iZmlsbDojZmZmO2ZpbGwtcnVsZTpldmVub2RkIi8+PC9nPjwvc3ZnPg=="; + +/** Suggest common ports for the various --inspect options */ +const inspectArgs: Fig.SingleOrArray = { + name: "[host:]port", + isOptional: true, + suggestions: [ + { + name: "3000", + icon: "fig://icon?type=box", + description: "Serve on port 3000", + }, + { + name: "8080", + icon: "fig://icon?type=box", + description: "Serve on port 8080", + }, + ], + description: "Activate inspector on particular port and/or hostname", +}; + +const loaders = [ + "js", + "jsx", + "ts", + "tsx", + "json", + "toml", + "text", + "file", + "wasm", + "napi", +]; +/** Format from https://github.com/oven-sh/bun/blob/dcbcf9803a19be989c0f48d22a50a43731fcfacd/src/cli.zig */ +const sharedPublicParams: Fig.Option[] = [ + { + name: ["-h", "--help"], + description: "Display this help and exit", + }, + { + name: ["-b", "--bun"], + description: + "Force a script or package to use Bun's runtime instead of Node.js (via symlinking node)", + }, + { + name: "--cwd", + args: { + name: "path", + description: + "Absolute path to resolve files & entry points from. This just changes the process' cwd", + }, + }, + { + name: ["-c", "--config"], + args: { + name: "path", + template: "filepaths", + description: "Config file to load Bun from (e.g. -c bunfig.toml)", + isOptional: true, + }, + description: "Load config (bunfig.toml)", + }, + { + name: "--extension-order", + args: { + name: "order", + isVariadic: true, + description: "Defaults to: .tsx,.ts,.jsx,.js,.json", + }, + }, + { + name: "--jsx-factory", + args: { + name: "name", + suggestions: ["React.createElement", "h", "preact.h"], + }, + description: `Changes the function called when compiling JSX elements using the classic JSX runtime`, + }, + { + name: "--jsx-fragment", + priority: 49, + args: { name: "string", isOptional: true }, + insertValue: "--jsx-fragment='{cursor}'", + description: "Changes the function called when compiling JSX fragments", + }, + { + name: "--jsx-import-source", + args: { name: "module", suggestions: ["react"] }, + description: `Declares the module specifier to be used for importing the jsx and jsxs factory functions. Default: "react"`, + }, + { + name: "--jsx-runtime", + args: { name: "name", suggestions: ["automatic", "classic"] }, + description: `"automatic" (default) or "classic"`, + }, + { + name: ["-r", "--preload"], + args: { + name: "args", + isVariadic: true, + description: "Import a module before other modules are loaded", + }, + }, + { + name: "--main-fields", + args: { + name: "args", + isVariadic: true, + description: + "Main fields to lookup in package.json. Defaults to --target dependent", + }, + }, + { + name: "--no-summary", + description: "Don't print a summary (when generating .bun)", + }, + { + name: ["-v", "--version"], + description: "Print version and exit", + }, + { + name: "--revision", + description: "Print version with revision and exit", + }, + { + name: "--tsconfig-override", + args: { + name: "overrides", + description: "Load tsconfig from path instead of cwd/tsconfig.json", + }, + }, + { + name: ["-d", "--define"], + args: { + name: "k=v", + isVariadic: true, + description: + "Substitute key=value while parsing, e.g. --define process.env.NODE_ENV=development", + }, + }, + { + name: ["-e", "--external"], + args: { + name: "args", + isVariadic: true, + description: + "Exclude module from transpilation (can use * wildcards). ex: -e react", + }, + }, + { + name: ["-l", "--loader"], + args: { + name: "args", + isVariadic: true, + description: + "Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: js, jsx, ts, tsx, json, toml, text, file, wasm, napi", + generators: keyValueList({ + keys: loaders.map((loader) => "." + loader), + values: loaders, + }), + }, + }, + { + name: ["-u", "--origin"], + args: { + name: "args", + description: 'Rewrite import URLs to start with --origin. Default: ""', + }, + }, + { + name: ["-p", "--port"], + args: { + name: "args", + description: 'Port to serve Bun\'s dev server on. Default: "3000"', + }, + }, + { + name: "--smol", + description: "Use less memory, but run garbage collection more often", + }, + { + name: "--minify", + description: "Minify (experimental)", + priority: 50, + }, + { + name: "--minify-syntax", + description: "Minify syntax and inline data (experimental)", + }, + { + name: "--minify-whitespace", + description: "Minify whitespace (experimental)", + }, + { + name: "--minify-identifiers", + description: "Minify identifiers", + }, + { + name: "--no-macros", + description: + "Disable macros from being executed in the bundler, transpiler and runtime", + }, + { + name: "--target", + description: "Target environment", + priority: 50, + args: { + generators: valueList({ + values: ["node", "browser", "bun"], + }), + }, + }, + { + name: "--inspect", + description: "Activate Bun's debugger for a file", + requiresSeparator: true, + args: inspectArgs, + }, + { + name: "--inspect-wait", + description: + "Activate Bun's Debugger, wait for a connection before executing", + requiresSeparator: true, + args: inspectArgs, + }, + { + name: "--inspect-brk", + description: + "Activate Bun's Debugger, set breakpoint on first line of code and wait", + requiresSeparator: true, + args: inspectArgs, + }, + { + name: "--if-present", + description: "Exit if the entrypoint does not exist", + }, +]; + +// note: we are keeping --port and --origin as it can be reused for bun build and elsewhere +const notBunDevFlags: Fig.Option[] = [ + { + name: "--hot", + description: + "Enable auto reload in the Bun runtime, test runner, or bundler", + priority: 50, + }, + { + name: "--watch", + description: "Automatically restart the process on file change", + priority: 50, + }, + { + name: "--no-install", + description: "Disable auto install in the Bun runtime", + }, + { + name: "-i", + description: + "Automatically install dependencies and use global cache in Bun's runtime, equivalent to --install=fallback", + }, + { + name: "--install", + args: { + name: "arg", + description: `Install dependencies automatically when no node_modules are present, default: "auto". "force" to ignore node_modules, fallback to install any missing`, + suggestions: ["auto", "force", "fallback", "disable"], + }, + }, + { + name: "--prefer-offline", + description: + "Skip staleness checks for packages in the Bun runtime and resolve from disk", + }, + { + name: "--prefer-latest", + description: + "Use the latest matching versions of packages in the Bun runtime, always checking npm", + }, + { + name: "--silent", + description: "Don't repeat the command for bun run", + }, +]; + +const buildOnlyParams: Fig.Option[] = [ + { + name: "compile", + description: + "Generate a standalone Bun executable containing your bundled code", + priority: 50, + }, + { + name: "--format", + description: + "Specifies the module format to build to. Only esm is supported currently", + args: { + name: "args", + suggestions: ["esm"], + }, + }, + { + name: "--outdir", + description: 'Default to "dist" if multiple files', + priority: 50, + args: { + name: "path", + }, + }, + { + name: "--outfile", + description: "Write to a file", + priority: 50, + args: { + name: "path", + }, + }, + { + name: "--root", + description: "Root directory used for multiple entry points", + args: { + name: "path", + }, + }, + { + name: "--splitting", + description: "Enable code splitting", + priority: 50, + }, + { + name: "--public-path", + description: "A prefix to be appended to any import paths in bundled code", + args: { + name: "args", + }, + }, + { + name: "--sourcemap", + description: "Build with sourcemaps - 'inline', 'external', or 'none'", + requiresSeparator: "-", + priority: 50, + args: { + name: "args", + isOptional: true, + suggestions: ["inline", "external", "none"], + }, + }, + { + name: "--entry-naming", + description: + 'Customize entry point filenames. Defaults to "[dir]/[name].[ext]"', + args: { + name: "args", + }, + }, + { + name: "--chunk-naming", + description: 'Customize chunk filenames. Defaults to "[name]-[hash].[ext]"', + args: { + name: "args", + }, + }, + { + name: "--asset-naming", + description: 'Customize asset filenames. Defaults to "[name]-[hash].[ext]"', + args: { + name: "args", + }, + }, + { + name: "--server-components", + description: "Enable React Server Components (experimental)", + }, + { + name: "--no-bundle", + description: "Transpile file only, do not bundle", + }, +]; + +const testOnlyParams: Fig.Option[] = [ + { + name: "--timeout", + description: "Set the per-test timeout in milliseconds, default is 5000", + args: { + name: "number", + }, + }, + { + name: "--update-snapshots", + description: "Update snapshot files", + }, + { + name: "--rerun-each", + description: + "Re-run each test file times, helps catch certain bugs", + args: { + name: "number", + }, + }, + { + name: "--only", + description: 'Only run tests that are marked with "test.only()"', + }, + { + name: "--todo", + description: 'Include tests that are marked with "test.todo()"', + }, + { + name: "--coverage", + description: "Generate a coverage profile", + }, + { + name: "--bail", + description: + "Exit the test suite after failures. If you do not specify a number, it defaults to 1", + args: { + name: "number", + isOptional: true, + }, + }, + { + name: ["-t", "--test-name-pattern"], + description: "Run only tests with a name that matches the given regex", + args: { + name: "pattern", + }, + }, +]; + +const debugParams: Fig.Option[] = [ + { + name: "--dump-environment-variables", + description: + "Dump environment variables from .env and process as JSON and quit. Useful for debugging", + priority: 49, + }, + { + name: "--dump-limits", + description: "Dump system limits. Useful for debugging", + priority: 49, + }, +]; + +const publicParams = [...sharedPublicParams, ...notBunDevFlags]; +const buildParams = [...publicParams, ...buildOnlyParams, ...debugParams]; +const testParams = [...publicParams, ...testOnlyParams, ...debugParams]; + const dependencyOptions: Fig.Option[] = [ { name: ["-c", "--config"], @@ -29,19 +480,22 @@ const dependencyOptions: Fig.Option[] = [ name: "--no-save", description: "Don't save a lockfile", }, + { + name: "--save", + description: "Save to package.json", + }, { name: "--dry-run", description: "Don't install anything", }, { - name: "--lockfile", - args: { name: "path", template: "filepaths" }, - description: "Store & load a lockfile at a specific filepath", + name: "--frozen-lockfile", + description: "Disallow changes to lockfile", }, { name: ["-f", "--force"], description: - "Always request the latest versions from the registry & reinstall all dependenices", + "Always request the latest versions from the registry & reinstall all dependencies", }, { name: "--cache-dir", @@ -88,12 +542,67 @@ const dependencyOptions: Fig.Option[] = [ name: "--help", description: "Print the help menu", }, + { + name: "--no-progress", + description: "Disable the progress bar", + }, + { + name: "--no-summary", + description: "Don't print a summary", + }, + { + name: "--no-verify", + description: "Skip verifying integrity of newly downloaded packages", + }, + { + name: "--ignore-scripts", + description: + "Skip lifecycle scripts in the project's package.json (dependency scripts are never run)", + }, + { + name: ["-d", "--dev", "-D", "--development"], + description: "Install as devDependency", + priority: 75, + isRepeatable: false, + }, + { + name: "--exact", + description: "Install exact version", + }, + { + name: "--optional", + description: "Install as optionalDependency", + }, ]; +/** Generate the globally linked packages stored in $BUN_INSTALL directory */ +const bunLinksGenerator: Fig.Generator = { + script: [ + "command", + "sh", + "-c", + "find $BUN_INSTALL/install/global/node_modules -type l -o -type d -maxdepth 2 | awk -F 'node_modules/' '{print $2}'", + ], + postProcess(out) { + return out.split("\n").map((dep) => { + return { + name: dep, + description: "Link to this package", + icon: "📦", + }; + }); + }, + cache: { + strategy: "stale-while-revalidate", + ttl: 60 * 60 * 24, // 24 hours + }, +}; + const spec: Fig.Spec = { name: "bun", description: "A fast bundler, transpiler, JavaScript Runtime and package manager for web software", + icon, args: [ { name: "file", @@ -107,174 +616,17 @@ const spec: Fig.Spec = { name: "args", }, ], - options: [ - { - name: "--use", - args: { name: "framework", suggestions: ["next"], template: "folders" }, - description: `Choose a framework, e.g. "--use next". It checks first for a package named "bun-framework-packagename" and then "packagename"`, - }, - { - name: "--bunfile", - args: { name: "path", template: "filepaths" }, - description: `Use a .bun file (default: node_modules.bun)`, - }, - { - name: "--inspect", - description: "Activate Bun's Debugger", - }, - { - name: "--inspect-wait", - description: - "Activate Bun's Debugger, wait for a connection before executing", - }, - { - name: "--inspect-brk", - description: - "Activate Bun's Debugger, set breakpoint on first line of code and wait", - }, - { - name: "--server-bunfile", - args: { name: "path", template: "filepaths" }, - description: `Use a .server.bun file (default: node_modules.server.bun)`, - }, - { - name: "--cwd", - args: { name: "path", template: "folders" }, - description: `Absolute path to resolve files & entry points from. This just changes the process' cwd`, - }, - { - name: ["-c", "--config"], - args: { name: "path", isOptional: true, template: "filepaths" }, - description: `Config file to load bun from (e.g. -c bunfig.toml`, - }, - { - name: "--disable-react-fast-refresh", - description: `Disable React Fast Refresh`, - }, - { - name: "--disable-hmr", - description: `Disable Hot Module Reloading (disables fast refresh too)`, - }, - { - name: "--extension-order", - args: { - name: "order", - isVariadic: true, - generators: keyValueList({ - keys: [".tsx", ".ts", ".jsx", ".js", ".json"], - }), - }, - description: `Defaults to: .tsx,.ts,.jsx,.js,.json`, - }, - { - name: "--jsx-factory", - args: { - name: "name", - suggestions: ["React.createElement", "h", "preact.h"], - }, - description: `Changes the function called when compiling JSX elements using the classic JSX runtime`, - }, - { - name: "--jsx-fragment", - args: { name: "name", suggestions: ["React.Fragment", "Fragment"] }, - description: `Changes the function called when compiling JSX fragments`, - }, - { - name: "--jsx-import-source", - args: { name: "module", suggestions: ["react"] }, - description: `Declares the module specifier to be used for importing the jsx and jsxs factory functions. Default: "react"`, - }, - { - name: "--jsx-production", - description: `Use jsx instead of jsxDEV (default) for the automatic runtime`, - }, - { - name: "--jsx-runtime", - args: { name: "name", suggestions: ["automatic", "classic"] }, - description: `"automatic" (default) or "classic"`, - }, - { - name: "--main-fields", - args: { name: "fields", isVariadic: true }, - description: `Main fields to lookup in package.json. Defaults to --platform dependent`, - }, - { - name: "--no-summary", - description: `Don't print a summary (when generating .bun)`, - }, - { name: ["-v", "--version"], description: `Print version and exit` }, - { - name: "--platform", - args: { name: "name", suggestions: ["browser", "node"] }, - description: `"browser" or "node". Defaults to "browser"`, - }, - { - name: "--public-dir", - args: { name: "path", template: "folders" }, - description: `Top-level directory for .html files, fonts or anything external. Defaults to "/public", to match create-react-app and Next.js`, - }, - { - name: "--tsconfig-override", - args: { name: "path", template: "filepaths" }, - description: `Load tsconfig from path instead of cwd/tsconfig.json`, - }, - { - name: ["-d", "--define"], - args: { name: "k:v", isVariadic: true }, - description: `Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:"development". Values are parsed as JSON`, - }, - { - name: ["-e", "--external"], - args: { name: "module", isVariadic: true }, - description: `Exclude module from transpilation (can use * wildcards). ex: -e react`, - }, - { name: ["-h", "--help"], description: `Display this help and exit` }, - { - name: ["-i", "--inject"], - args: { name: "module", isVariadic: true }, - description: `Inject module at the top of every file`, - }, - { - name: ["-l", "--loader"], - args: { name: "loader", isVariadic: true }, - description: `Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: jsx, js, json, tsx, ts, css`, - }, - { - name: ["-u", "--origin"], - args: { name: "url" }, - description: `Rewrite import URLs to start with --origin. Default: ""`, - }, - { - name: ["-p", "--port"], - args: { name: "port" }, - description: `Port to serve bun's dev server on. Default: "3000"`, - }, - { name: "--silent", description: `Don't repeat the command for bun run` }, - ], + // These flags are used before the subcommand or file + options: publicParams.filter( + (param) => + param.name.includes("--inspect") || + param.name.includes("--hot") || + param.name.includes("--watch") + ), subcommands: [ - { - name: "dev", - icon: "🛠️", - description: "Start a bun Dev server", - args: { - name: "files", - template: "filepaths", - isVariadic: true, - }, - }, - { - name: "bun", - icon: "📦", - description: "Bundle dependencies of input files into a '.bun' file", - args: { - name: "files", - template: "filepaths", - isVariadic: true, - }, - }, { name: ["c", "create"], - icon: "🛠️", + icon, description: "Start a new project from a template", args: [ { @@ -349,20 +701,18 @@ const spec: Fig.Spec = { }, { name: "run", - icon: "🛠️", + icon, description: "Run a package.json script or executable", - args: [ - { - name: "script", - filterStrategy: "fuzzy", - generators: npmScriptsGenerator, - }, - { - name: "args", - isVariadic: true, - isOptional: true, - }, - ], + args: { + name: "script", + filterStrategy: "fuzzy", + generators: [ + filepaths({ + extensions: ["ts", "tsx", "js", "jsx", "mjs", "cjs"], + }), + npmScriptsGenerator, + ], + }, }, { name: ["i", "install"], @@ -395,14 +745,142 @@ const spec: Fig.Spec = { isVariadic: true, }, }, + { + name: ["build", "bun"], + icon, + description: "Bundle files using Bun's native bundler", + args: { + name: "entrypoints", + isVariadic: true, + generators: filepaths({ + extensions: ["ts", "tsx", "js", "jsx", "mjs", "cjs"], + }), + description: + "Entrypoint to bundle. If multiple entrypoints provided, must specify --outdir", + }, + options: buildParams, + }, + { + name: "update", + icon, + description: "Update outdated dependencies", + options: dependencyOptions, + args: { + name: "package", + filterStrategy: "fuzzy", + isOptional: true, + generators: dependenciesGenerator, + isVariadic: true, + }, + }, + { + name: "link", + icon: "📦", + description: + "Run without an argument to register this package to the global package registry. Uses the name field from package.json", + args: { + name: "package", + filterStrategy: "fuzzy", + isOptional: true, + generators: bunLinksGenerator, + description: "Install a package from the global package registry", + }, + options: [ + { + name: "--save", + description: "Save to package.json", + dependsOn: ["package"], + }, + ], + }, + { + name: "unlink", + icon: "📦", + description: "Unlink this package from the global package registry", + // Unliking a package by name is not yet implemented. Use bunLinksGenerator once it is implemented. + }, { name: "upgrade", - icon: "🛠️", + icon, description: "Get the latest version of bun", + options: [ + { + name: "--canary", + description: "Install the latest canary release", + }, + ], + }, + { + name: "test", + icon, + description: "Run unit tests with Bun", + args: { + name: "files", + generators: { + // Suggest test files -> https://bun.sh/docs/cli/test. (not in node_modules or .git) + script: [ + "command", + "sh", + "-c", + 'find $(npm prefix) | grep -E ".*.(test|_test|spec|_spec).(ts|tsx|js|jsx)$" | grep -vE ".*/node_modules/.*" | sed "s|$(npm prefix)/||"', + ], + postProcess(out) { + return out.split("\n").map((file) => { + return { + name: file.split("/").pop(), + priority: 76, + description: `run ${file}`, + insertValue: file, + }; + }); + }, + cache: { + strategy: "stale-while-revalidate", + ttl: 60 * 60 * 24, // 24 hours + }, + }, + isVariadic: true, + filterStrategy: "fuzzy", + isOptional: true, + description: "Test files to run", + }, + options: testParams, + }, + { + name: "pm", + icon, + description: "Set of utilities for working with Bun's package manager", + options: [ + { + name: "bin", + description: "Print the path to bin folder", + }, + { + name: "cache", + description: "Print the path to the cache folder", + }, + { + name: "hash", + description: "Generate & print the hash of the current lockfile", + }, + { + name: "hash-print", + description: "Print the hash stored in the current lockfile", + }, + { + name: "hash-string", + description: "Print the string used to hash the lockfile", + }, + { + name: "ls", + description: + "List the dependency tree according to the current lockfile", + }, + ], }, { name: "completions", - icon: "🛠️", + icon, description: "Install shell completions", }, { @@ -413,13 +891,31 @@ const spec: Fig.Spec = { { name: "help", description: "Print the help menu", + icon, }, { name: "x", - icon: "🛠️", + icon, description: "Run an npx command", loadSpec: "bunx", }, + { + name: "repl", + icon, + description: + "Run a REPL (read eval print loop) with the Bun runtime.(experimental)", + }, + { + name: "init", + icon, + description: "Initialize a new bun project", + options: [ + { + name: ["-y", "--yes"], + description: "Answer yes to all prompts", + }, + ], + }, ], }; From 2507982fabfa4260f808b65af7b28f0f40b9f442 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Thu, 30 Nov 2023 21:45:35 +0000 Subject: [PATCH 81/81] ci: version bump to 2.644.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e12828e11a84..6c79c698e19d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@withfig/autocomplete", - "version": "2.643.0", + "version": "2.644.0", "description": "Fig Autocomplete Specs", "schemaVersion": "v7", "main": "./build/index",