mirror of
https://github.com/di-sukharev/opencommit.git
synced 2026-01-13 07:38:01 -05:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed66e403e7 | ||
|
|
b89e50ebbf | ||
|
|
38ebe49daa | ||
|
|
6ccded1f23 | ||
|
|
31357132e4 | ||
|
|
b35a393152 | ||
|
|
8fe382a072 | ||
|
|
4b703c634a | ||
|
|
6821e937cf | ||
|
|
69f3c48b2c | ||
|
|
f49f1a86df | ||
|
|
98945df561 | ||
|
|
e8e190ff3d | ||
|
|
9c3f28b7c6 | ||
|
|
e146d4d60d | ||
|
|
2ae35749a5 | ||
|
|
8836c57fa4 | ||
|
|
4b523e5782 | ||
|
|
33491486bb | ||
|
|
e76db8276b | ||
|
|
c2ae98170c | ||
|
|
91987030f0 | ||
|
|
2a55b08b51 | ||
|
|
ed4d6e0109 | ||
|
|
6712e798c5 | ||
|
|
1347962a93 | ||
|
|
3ca9b9752f | ||
|
|
50e2f67a9b | ||
|
|
c1a4c3daf2 | ||
|
|
e4de6d8186 | ||
|
|
5abe5d715d | ||
|
|
32c34abd22 | ||
|
|
1050cad95d | ||
|
|
7bbc97980e | ||
|
|
2a9a3d5818 | ||
|
|
22935f38ba | ||
|
|
4ae6361ad8 | ||
|
|
5a0a384cbe | ||
|
|
a8839353f7 | ||
|
|
88006b8693 | ||
|
|
5d9d1c972a | ||
|
|
3892bd0e69 | ||
|
|
2b6cc5c360 | ||
|
|
c4c2600cf6 | ||
|
|
c361aaa914 | ||
|
|
f3d673185e | ||
|
|
5615bdce86 | ||
|
|
68b327bee7 | ||
|
|
b747d70e69 | ||
|
|
caa64fbcf9 | ||
|
|
1a49c08409 | ||
|
|
3399d65a0c | ||
|
|
d561170519 | ||
|
|
bf29c260ca | ||
|
|
9e2a3d8988 | ||
|
|
1ea5fbc430 | ||
|
|
55e9adf73d | ||
|
|
60325f53b9 | ||
|
|
3966c4c53a | ||
|
|
2527c80f2f | ||
|
|
e89fc96732 | ||
|
|
b5d1057fd6 | ||
|
|
5f310970cc | ||
|
|
7d483f0d7b | ||
|
|
d1ed0a9fea |
5
TODO.md → .github/TODO.md
vendored
5
TODO.md → .github/TODO.md
vendored
@@ -1,8 +1,9 @@
|
||||
# TODOs
|
||||
|
||||
- [] [build for both mjs and cjs](https://snyk.io/blog/best-practices-create-modern-npm-package/)
|
||||
- [x] set prepare-commit-msg hook
|
||||
- [] show "new version available" message, look into this commit e146d4d cli.ts file
|
||||
- [] make bundle smaller by properly configuring esbuild
|
||||
- [] [build for both mjs and cjs](https://snyk.io/blog/best-practices-create-modern-npm-package/)
|
||||
- [] do // TODOs in the code
|
||||
- [] batch small files in one request
|
||||
- [] add tests
|
||||
- [] make hook work
|
||||
BIN
.github/opencommit-example.png
vendored
Normal file
BIN
.github/opencommit-example.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 318 KiB |
33
README.md
33
README.md
@@ -5,15 +5,18 @@
|
||||
<h4 align="center">Author <a href="https://github.com/di-sukharev">@di-sukharev</a> <a href="https://twitter.com/io_Y_oi"><img src="https://img.shields.io/twitter/follow/io_Y_oi?style=flat&label=io_Y_oi&logo=twitter&color=0bf&logoColor=fff" align="center"></a>
|
||||
</h4>
|
||||
</div>
|
||||
<p>AI generates conventional commits with mind-blowing accuracy</p>
|
||||
<h2>GPT CLI to auto-generate impressive commits in 1 second</h2>
|
||||
<p>Killing lame commits with AI 🤯🔫</p>
|
||||
<a href="https://www.npmjs.com/package/opencommit"><img src="https://img.shields.io/npm/v/opencommit" alt="Current version"></a>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
<div align="center">
|
||||
<img src=".github/opencommit-example.png" alt="OpenCommit example"/>
|
||||
</div>
|
||||
|
||||
Look into [the commits](https://github.com/di-sukharev/opencommit/commit) to see how OpenCommit works. Emoji and long commit description text is configurable.
|
||||
All the commits in this repo are done with OpenCommit — look into [the commits](https://github.com/di-sukharev/opencommit/commit/eae7618d575ee8d2e9fff5de56da79d40c4bc5fc) to see how OpenCommit works. Emoji and long commit description text is configurable.
|
||||
|
||||
## Setup
|
||||
|
||||
@@ -25,15 +28,15 @@ Look into [the commits](https://github.com/di-sukharev/opencommit/commit) to see
|
||||
npm install -g opencommit
|
||||
```
|
||||
|
||||
2. Get your API key from [OpenAI](https://platform.openai.com/account/api-keys)
|
||||
2. Get your API key from [OpenAI](https://platform.openai.com/account/api-keys). Make sure you add payment details, so API works.
|
||||
|
||||
3. Set the key to opencommit config:
|
||||
|
||||
```sh
|
||||
opencommit config set OPENAI_API_KEY=<your token>
|
||||
opencommit config set OPENAI_API_KEY=<your_api_key>
|
||||
```
|
||||
|
||||
Your token isn't sent to anyone, it's saved in `~/.opencommit` config file.
|
||||
Your api key is stored locally in `~/.opencommit` config file.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -60,27 +63,27 @@ oc
|
||||
To add emoji:
|
||||
|
||||
```sh
|
||||
opencommit config set emoji=true
|
||||
oc config set emoji=true
|
||||
```
|
||||
|
||||
To remove emoji:
|
||||
|
||||
```sh
|
||||
opencommit config set emoji=false
|
||||
oc config set emoji=false
|
||||
```
|
||||
|
||||
### Postface commits with descriptions of changes 🤠
|
||||
### Postface commits with descriptions of changes
|
||||
|
||||
To add descriptions:
|
||||
|
||||
```sh
|
||||
opencommit config set description=true
|
||||
oc config set description=true
|
||||
```
|
||||
|
||||
To remove description:
|
||||
|
||||
```sh
|
||||
opencommit config set description=false
|
||||
oc config set description=false
|
||||
```
|
||||
|
||||
## Git hook
|
||||
@@ -90,20 +93,20 @@ You can set opencommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/gi
|
||||
To set the hook:
|
||||
|
||||
```sh
|
||||
opencommit hook set
|
||||
oc hook set
|
||||
```
|
||||
|
||||
To unset the hook:
|
||||
|
||||
```sh
|
||||
opencommit hook unset
|
||||
oc hook unset
|
||||
```
|
||||
|
||||
To use the hook:
|
||||
|
||||
```sh
|
||||
git add <files...>
|
||||
git commit
|
||||
git add <files...>
|
||||
git commit
|
||||
```
|
||||
|
||||
Or follow the process of your IDE Source Control feature, when it calls `git commit` command — OpenCommit will integrate into the flow.
|
||||
|
||||
578
package-lock.json
generated
578
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "open-commit",
|
||||
"version": "0.0.1",
|
||||
"name": "opencommit",
|
||||
"version": "1.1.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "open-commit",
|
||||
"version": "0.0.1",
|
||||
"name": "opencommit",
|
||||
"version": "1.1.6",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.6.1",
|
||||
@@ -19,8 +19,8 @@
|
||||
"openai": "^3.2.1"
|
||||
},
|
||||
"bin": {
|
||||
"oc": "out/cli.mjs",
|
||||
"opencommit": "out/cli.mjs"
|
||||
"oc": "out/cli.cjs",
|
||||
"opencommit": "out/cli.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ini": "^1.3.31",
|
||||
@@ -36,23 +36,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@clack/core": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.0.tgz",
|
||||
"integrity": "sha512-ujw1888RciTArxUvwLOf24XSygRX7F4qiCPI7WLH3zCTZJuqKPMcTS7Wqjz0x/AuMpwGPlzhKln4+sCuQqYxzA==",
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.2.tgz",
|
||||
"integrity": "sha512-FZnsNynwGDIDktx6PEZK1EuCkFpY4ldEX6VYvfl0dqeoLPb9Jpw1xoUXaVcGR8ExmYNm1w2vdGdJkEUYD/2pqg==",
|
||||
"dependencies": {
|
||||
"picocolors": "^1.0.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@clack/prompts": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.6.1.tgz",
|
||||
"integrity": "sha512-7KuMST/5zB7KpvfR00kcnbOaXmfN6tkJmkLpAyV2Iv2SJ7oxFbhNFvR5OQJynSKDhU8oOp/eFMK6Q0k/DXsq8A==",
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.6.3.tgz",
|
||||
"integrity": "sha512-AM+kFmAHawpUQv2q9+mcB6jLKxXGjgu/r2EQjEwujgpCdzrST6BJqYw00GRn56/L/Izw5U7ImoLmy00X/r80Pw==",
|
||||
"bundleDependencies": [
|
||||
"is-unicode-supported"
|
||||
],
|
||||
"dependencies": {
|
||||
"@clack/core": "^0.3.0",
|
||||
"@clack/core": "^0.3.2",
|
||||
"is-unicode-supported": "*",
|
||||
"picocolors": "^1.0.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
@@ -81,6 +81,38 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
|
||||
"integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
|
||||
"integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz",
|
||||
@@ -274,14 +306,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz",
|
||||
"integrity": "sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz",
|
||||
"integrity": "sha512-a2RQAkosH3d3ZIV08s3DcL/mcGc2M/UC528VkPULFxR9VnVPT8pBu0IyBAJJmVsCmhVfwQX1v6q+QGnmSe1bew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.54.0",
|
||||
"@typescript-eslint/type-utils": "5.54.0",
|
||||
"@typescript-eslint/utils": "5.54.0",
|
||||
"@typescript-eslint/scope-manager": "5.54.1",
|
||||
"@typescript-eslint/type-utils": "5.54.1",
|
||||
"@typescript-eslint/utils": "5.54.1",
|
||||
"debug": "^4.3.4",
|
||||
"grapheme-splitter": "^1.0.4",
|
||||
"ignore": "^5.2.0",
|
||||
@@ -308,14 +340,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz",
|
||||
"integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.1.tgz",
|
||||
"integrity": "sha512-8zaIXJp/nG9Ff9vQNh7TI+C3nA6q6iIsGJ4B4L6MhZ7mHnTMR4YP5vp2xydmFXIy8rpyIVbNAG44871LMt6ujg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.54.0",
|
||||
"@typescript-eslint/types": "5.54.0",
|
||||
"@typescript-eslint/typescript-estree": "5.54.0",
|
||||
"@typescript-eslint/scope-manager": "5.54.1",
|
||||
"@typescript-eslint/types": "5.54.1",
|
||||
"@typescript-eslint/typescript-estree": "5.54.1",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -335,13 +367,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz",
|
||||
"integrity": "sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.1.tgz",
|
||||
"integrity": "sha512-zWKuGliXxvuxyM71UA/EcPxaviw39dB2504LqAmFDjmkpO8qNLHcmzlh6pbHs1h/7YQ9bnsO8CCcYCSA8sykUg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.54.0",
|
||||
"@typescript-eslint/visitor-keys": "5.54.0"
|
||||
"@typescript-eslint/types": "5.54.1",
|
||||
"@typescript-eslint/visitor-keys": "5.54.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -352,13 +384,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz",
|
||||
"integrity": "sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.1.tgz",
|
||||
"integrity": "sha512-WREHsTz0GqVYLIbzIZYbmUUr95DKEKIXZNH57W3s+4bVnuF1TKe2jH8ZNH8rO1CeMY3U4j4UQeqPNkHMiGem3g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "5.54.0",
|
||||
"@typescript-eslint/utils": "5.54.0",
|
||||
"@typescript-eslint/typescript-estree": "5.54.1",
|
||||
"@typescript-eslint/utils": "5.54.1",
|
||||
"debug": "^4.3.4",
|
||||
"tsutils": "^3.21.0"
|
||||
},
|
||||
@@ -379,9 +411,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz",
|
||||
"integrity": "sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.1.tgz",
|
||||
"integrity": "sha512-G9+1vVazrfAfbtmCapJX8jRo2E4MDXxgm/IMOF4oGh3kq7XuK3JRkOg6y2Qu1VsTRmWETyTkWt1wxy7X7/yLkw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -392,13 +424,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz",
|
||||
"integrity": "sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.1.tgz",
|
||||
"integrity": "sha512-bjK5t+S6ffHnVwA0qRPTZrxKSaFYocwFIkZx5k7pvWfsB1I57pO/0M0Skatzzw1sCkjJ83AfGTL0oFIFiDX3bg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.54.0",
|
||||
"@typescript-eslint/visitor-keys": "5.54.0",
|
||||
"@typescript-eslint/types": "5.54.1",
|
||||
"@typescript-eslint/visitor-keys": "5.54.1",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
@@ -419,16 +451,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz",
|
||||
"integrity": "sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.1.tgz",
|
||||
"integrity": "sha512-IY5dyQM8XD1zfDe5X8jegX6r2EVU5o/WJnLu/znLPWCBF7KNGC+adacXnt5jEYS9JixDcoccI6CvE4RCjHMzCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@types/semver": "^7.3.12",
|
||||
"@typescript-eslint/scope-manager": "5.54.0",
|
||||
"@typescript-eslint/types": "5.54.0",
|
||||
"@typescript-eslint/typescript-estree": "5.54.0",
|
||||
"@typescript-eslint/scope-manager": "5.54.1",
|
||||
"@typescript-eslint/types": "5.54.1",
|
||||
"@typescript-eslint/typescript-estree": "5.54.1",
|
||||
"eslint-scope": "^5.1.1",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"semver": "^7.3.7"
|
||||
@@ -445,12 +477,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz",
|
||||
"integrity": "sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==",
|
||||
"version": "5.54.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.1.tgz",
|
||||
"integrity": "sha512-q8iSoHTgwCfgcRJ2l2x+xCbu8nBlRAlsQ33k24Adj8eoVBE0f8dUeI+bAa8F84Mv05UGbAx57g2zrRsYIooqQg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.54.0",
|
||||
"@typescript-eslint/types": "5.54.1",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -542,15 +574,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
@@ -935,6 +963,54 @@
|
||||
"esbuild-windows-arm64": "0.15.18"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
|
||||
"integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
|
||||
"integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
|
||||
@@ -951,6 +1027,262 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-32": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
|
||||
"integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
|
||||
"integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
|
||||
"integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-mips64le": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
|
||||
"integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-ppc64le": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
|
||||
"integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-riscv64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
|
||||
"integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-s390x": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
|
||||
"integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-netbsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-openbsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-sunos-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
|
||||
"integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-32": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
|
||||
"integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
|
||||
"integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
@@ -1069,6 +1401,21 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
@@ -1125,9 +1472,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esquery": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz",
|
||||
"integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
|
||||
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"estraverse": "^5.1.0"
|
||||
@@ -1206,31 +1553,6 @@
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dependencies": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/external-editor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||
@@ -1890,11 +2212,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
@@ -1967,14 +2292,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
@@ -2207,9 +2532,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
|
||||
"integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
@@ -2255,6 +2580,28 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -2319,11 +2666,6 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs/node_modules/tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
@@ -2583,10 +2925,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
},
|
||||
"node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
@@ -2603,6 +2944,12 @@
|
||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||
}
|
||||
},
|
||||
"node_modules/tsutils/node_modules/tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@@ -2726,17 +3073,6 @@
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/strip-ansi": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
|
||||
|
||||
10
package.json
10
package.json
@@ -1,13 +1,17 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "0.0.1",
|
||||
"description": "AI generates conventional commits with mind-blowing accuracy.",
|
||||
"version": "1.1.6",
|
||||
"description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
||||
"keywords": [
|
||||
"git",
|
||||
"chatgpt",
|
||||
"gpt",
|
||||
"ai",
|
||||
"openai",
|
||||
"opencommit",
|
||||
"aicommit",
|
||||
"aicommits",
|
||||
"gptcommit",
|
||||
"commit"
|
||||
],
|
||||
"main": "cli.js",
|
||||
@@ -37,7 +41,7 @@
|
||||
"start": "node ./out/cli.cjs",
|
||||
"dev": "ts-node ./src/cli.ts",
|
||||
"build": "rimraf out && esbuild ./src/cli.ts --bundle --outfile=out/cli.cjs --format=cjs --platform=node",
|
||||
"deploy": "npm run build && npm version patch && npm publish",
|
||||
"deploy": "npm run build && npm version patch && npm publish --tag latest",
|
||||
"lint": "eslint src --ext ts && tsc --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
4
src/CommandsEnum.ts
Normal file
4
src/CommandsEnum.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum COMMANDS {
|
||||
config = 'config',
|
||||
hook = 'hook'
|
||||
}
|
||||
50
src/api.ts
50
src/api.ts
@@ -1,39 +1,33 @@
|
||||
import { intro, outro } from '@clack/prompts';
|
||||
import { AxiosError } from 'axios';
|
||||
import chalk from 'chalk';
|
||||
import {
|
||||
ChatCompletionRequestMessage,
|
||||
ChatCompletionResponseMessage,
|
||||
Configuration as OpenAiApiConfiguration,
|
||||
OpenAIApi
|
||||
} from 'openai';
|
||||
|
||||
import { getConfig } from './commands/config';
|
||||
import { CONFIG_MODES, getConfig } from './commands/config';
|
||||
|
||||
const config = getConfig();
|
||||
|
||||
let apiKey = config?.OPENAI_API_KEY;
|
||||
|
||||
if (!apiKey) {
|
||||
const [command, mode] = process.argv.slice(2);
|
||||
|
||||
if (!apiKey && command !== 'config' && mode !== CONFIG_MODES.set) {
|
||||
intro('opencommit');
|
||||
|
||||
outro(
|
||||
'OPENAI_API_KEY is not set, please run `oc config set OPENAI_API_KEY=<your token>`'
|
||||
'OPENAI_API_KEY is not set, please run `oc config set OPENAI_API_KEY=<your token>. Make sure you add payment details, so API works.`'
|
||||
);
|
||||
outro(
|
||||
'For help Look into README https://github.com/di-sukharev/opencommit#setup'
|
||||
'For help look into README https://github.com/di-sukharev/opencommit#setup'
|
||||
);
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// if (!apiKey) {
|
||||
// intro('opencommit');
|
||||
// const apiKey = await text({
|
||||
// message: 'input your OPENAI_API_KEY'
|
||||
// });
|
||||
|
||||
// setConfig([[CONFIG_KEYS.OPENAI_API_KEY as string, apiKey as any]]);
|
||||
|
||||
// outro('OPENAI_API_KEY is set');
|
||||
// }
|
||||
|
||||
class OpenAi {
|
||||
private openAiApiConfiguration = new OpenAiApiConfiguration({
|
||||
apiKey: apiKey
|
||||
@@ -43,7 +37,7 @@ class OpenAi {
|
||||
|
||||
public generateCommitMessage = async (
|
||||
messages: Array<ChatCompletionRequestMessage>
|
||||
): Promise<ChatCompletionResponseMessage | undefined> => {
|
||||
): Promise<string | undefined> => {
|
||||
try {
|
||||
const { data } = await this.openAI.createChatCompletion({
|
||||
model: 'gpt-3.5-turbo',
|
||||
@@ -55,10 +49,24 @@ class OpenAi {
|
||||
|
||||
const message = data.choices[0].message;
|
||||
|
||||
return message;
|
||||
} catch (error) {
|
||||
console.error('openAI api error', { error });
|
||||
throw error;
|
||||
return message?.content;
|
||||
} catch (error: any) {
|
||||
outro(`${chalk.red('✖')} ${error}`);
|
||||
|
||||
if (error.isAxiosError && error.response?.status === 401) {
|
||||
const err = error as AxiosError;
|
||||
|
||||
const openAiError = (
|
||||
err.response?.data as { error?: { message: string } }
|
||||
).error;
|
||||
|
||||
if (openAiError?.message) outro(openAiError.message);
|
||||
outro(
|
||||
'For help look into README https://github.com/di-sukharev/opencommit#setup'
|
||||
);
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { cli } from 'cleye';
|
||||
import packageJSON from '../package.json';
|
||||
import packageJSON from '../package.json' assert { type: 'json' };
|
||||
|
||||
import { configCommand } from './commands/config';
|
||||
import { hookCommand, isHookCalled } from './commands/githook.js';
|
||||
|
||||
@@ -16,6 +16,7 @@ const generateCommitMessageFromGitDiff = async (
|
||||
commitSpinner.start('Generating the commit message');
|
||||
const commitMessage = await generateCommitMessageWithChatCompletion(diff);
|
||||
|
||||
// TODO: show proper error messages
|
||||
if (typeof commitMessage !== 'string') {
|
||||
const errorMessages = {
|
||||
[GenerateCommitMessageErrorEnum.emptyMessage]:
|
||||
@@ -44,8 +45,22 @@ ${chalk.grey('——————————————————')}`
|
||||
});
|
||||
|
||||
if (isCommitConfirmedByUser && !isCancel(isCommitConfirmedByUser)) {
|
||||
await execa('git', ['commit', '-m', commitMessage]);
|
||||
const { stdout } = await execa('git', ['commit', '-m', commitMessage]);
|
||||
outro(`${chalk.green('✔')} successfully committed`);
|
||||
outro(stdout);
|
||||
const isPushConfirmedByUser = await confirm({
|
||||
message: 'Do you want to run `git push`?'
|
||||
});
|
||||
|
||||
if (isPushConfirmedByUser && !isCancel(isPushConfirmedByUser)) {
|
||||
const pushSpinner = spinner();
|
||||
|
||||
pushSpinner.start('Running `git push`');
|
||||
const { stdout } = await execa('git', ['push']);
|
||||
pushSpinner.stop(`${chalk.green('✔')} successfully pushed all commits`);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
}
|
||||
} else outro(`${chalk.gray('✖')} process cancelled`);
|
||||
};
|
||||
|
||||
@@ -79,7 +94,7 @@ export async function commit(isStageAllFlag = false) {
|
||||
.bold('`oc`')} command.`
|
||||
);
|
||||
|
||||
stagedFilesSpinner.stop('Counting staged files');
|
||||
stagedFilesSpinner.stop('No files are staged');
|
||||
const isStageAllAndCommitConfirmedByUser = await confirm({
|
||||
message: 'Do you want to stage all files and generate commit message?'
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import { existsSync, writeFileSync, readFileSync } from 'fs';
|
||||
import { homedir } from 'os';
|
||||
import { intro, outro } from '@clack/prompts';
|
||||
import chalk from 'chalk';
|
||||
import { COMMANDS } from '../CommandsEnum';
|
||||
|
||||
export enum CONFIG_KEYS {
|
||||
OPENAI_API_KEY = 'OPENAI_API_KEY',
|
||||
@@ -12,13 +13,21 @@ export enum CONFIG_KEYS {
|
||||
emoji = 'emoji'
|
||||
}
|
||||
|
||||
export enum CONFIG_MODES {
|
||||
get = 'get',
|
||||
set = 'set'
|
||||
}
|
||||
|
||||
const validateConfig = (
|
||||
key: string,
|
||||
condition: any,
|
||||
validationMessage: string
|
||||
) => {
|
||||
if (!condition) {
|
||||
throw new Error(`Unsupported config key ${key}: ${validationMessage}`);
|
||||
outro(
|
||||
`${chalk.red('✖')} Unsupported config key ${key}: ${validationMessage}`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -110,7 +119,7 @@ export const setConfig = (keyValues: [key: string, value: string][]) => {
|
||||
|
||||
export const configCommand = command(
|
||||
{
|
||||
name: 'config',
|
||||
name: COMMANDS.config,
|
||||
parameters: ['<mode>', '<key=values...>']
|
||||
},
|
||||
async (argv) => {
|
||||
@@ -118,12 +127,12 @@ export const configCommand = command(
|
||||
try {
|
||||
const { mode, keyValues } = argv._;
|
||||
|
||||
if (mode === 'get') {
|
||||
if (mode === CONFIG_MODES.get) {
|
||||
const config = getConfig() || {};
|
||||
for (const key of keyValues) {
|
||||
outro(`${key}=${config[key as keyof typeof config]}`);
|
||||
}
|
||||
} else if (mode === 'set') {
|
||||
} else if (mode === CONFIG_MODES.set) {
|
||||
await setConfig(
|
||||
keyValues.map((keyValue) => keyValue.split('=') as [string, string])
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { command } from 'cleye';
|
||||
import { assertGitRepo } from '../utils/git.js';
|
||||
import { existsSync } from 'fs';
|
||||
import chalk from 'chalk';
|
||||
import { intro, outro } from '@clack/prompts';
|
||||
import { COMMANDS } from '../CommandsEnum.js';
|
||||
|
||||
const HOOK_NAME = 'prepare-commit-msg';
|
||||
const SYMLINK_URL = `.git/hooks/${HOOK_NAME}`;
|
||||
@@ -16,7 +16,7 @@ const isHookExists = existsSync(SYMLINK_URL);
|
||||
|
||||
export const hookCommand = command(
|
||||
{
|
||||
name: 'hook',
|
||||
name: COMMANDS.hook,
|
||||
parameters: ['<set/unset>']
|
||||
},
|
||||
async (argv) => {
|
||||
|
||||
@@ -37,9 +37,12 @@ export const prepareCommitMessageHook = async () => {
|
||||
|
||||
if (typeof commitMessage !== 'string') throw new Error(commitMessage.error);
|
||||
|
||||
await fs.appendFile(messageFilePath, commitMessage);
|
||||
const fileContent = await fs.readFile(messageFilePath);
|
||||
|
||||
outro(`${chalk.green('✔')} commit done`);
|
||||
await fs.writeFile(
|
||||
messageFilePath,
|
||||
commitMessage + '\n' + fileContent.toString()
|
||||
);
|
||||
} catch (error) {
|
||||
outro(`${chalk.red('✖')} ${error}`);
|
||||
process.exit(1);
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from 'openai';
|
||||
import { api } from './api';
|
||||
import { getConfig } from './commands/config';
|
||||
import { mergeStrings } from './utils/mergeStrings';
|
||||
|
||||
const config = getConfig();
|
||||
|
||||
@@ -48,8 +49,8 @@ const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
|
||||
{
|
||||
role: ChatCompletionRequestMessageRoleEnum.Assistant,
|
||||
// prettier-ignore
|
||||
content: `* ${config?.emoji ? '🐛 ' : ''}fix(server.ts): change port variable case from lowercase port to uppercase PORT
|
||||
* ${config?.emoji ? '✨ ' : ''}feat(server.ts): add support for process.env.PORT environment variable
|
||||
content: `${config?.emoji ? '🐛 ' : ''}fix(server.ts): change port variable case from lowercase port to uppercase PORT
|
||||
${config?.emoji ? '✨ ' : ''}feat(server.ts): add support for process.env.PORT environment variable
|
||||
${config?.description ? 'The port variable is now named PORT, which improves consistency with the naming conventions as PORT is a constant. Support for an environment variable allows the application to be more flexible as it can now run on any available port specified via the process.env.PORT environment variable.' : ''}`
|
||||
}
|
||||
];
|
||||
@@ -81,47 +82,79 @@ const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
|
||||
(msg) => msg.content
|
||||
).join('').length;
|
||||
|
||||
const MAX_REQ_TOKENS = 3900 - INIT_MESSAGES_PROMPT_LENGTH;
|
||||
|
||||
export const generateCommitMessageWithChatCompletion = async (
|
||||
diff: string
|
||||
): Promise<string | GenerateCommitMessageError> => {
|
||||
try {
|
||||
const MAX_REQ_TOKENS = 3900;
|
||||
if (diff.length >= MAX_REQ_TOKENS) {
|
||||
const commitMessagePromises = getCommitMsgsPromisesFromFileDiffs(diff);
|
||||
|
||||
if (INIT_MESSAGES_PROMPT_LENGTH + diff.length >= MAX_REQ_TOKENS) {
|
||||
const separator = 'diff --git ';
|
||||
|
||||
const diffByFiles = diff.split(separator).slice(1);
|
||||
|
||||
const commitMessages = [];
|
||||
|
||||
for (const diffFile of diffByFiles) {
|
||||
if (INIT_MESSAGES_PROMPT_LENGTH + diffFile.length >= MAX_REQ_TOKENS)
|
||||
continue;
|
||||
|
||||
const messages = generateCommitMessageChatCompletionPrompt(
|
||||
separator + diffFile
|
||||
);
|
||||
|
||||
const commitMessage = await api.generateCommitMessage(messages);
|
||||
|
||||
// TODO: handle this edge case
|
||||
if (!commitMessage?.content) continue;
|
||||
|
||||
commitMessages.push(commitMessage?.content);
|
||||
}
|
||||
const commitMessages = await Promise.all(commitMessagePromises);
|
||||
|
||||
return commitMessages.join('\n\n');
|
||||
} else {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(diff);
|
||||
|
||||
const commitMessage = await api.generateCommitMessage(messages);
|
||||
|
||||
if (!commitMessage)
|
||||
return { error: GenerateCommitMessageErrorEnum.emptyMessage };
|
||||
|
||||
return commitMessage;
|
||||
}
|
||||
|
||||
const messages = generateCommitMessageChatCompletionPrompt(diff);
|
||||
|
||||
const commitMessage = await api.generateCommitMessage(messages);
|
||||
|
||||
if (!commitMessage)
|
||||
return { error: GenerateCommitMessageErrorEnum.emptyMessage };
|
||||
|
||||
return commitMessage.content;
|
||||
} catch (error) {
|
||||
return { error: GenerateCommitMessageErrorEnum.internalError };
|
||||
}
|
||||
};
|
||||
|
||||
function getMessagesPromisesByLines(fileDiff: string, separator: string) {
|
||||
const lineSeparator = '\n@@';
|
||||
const [fileHeader, ...fileDiffByLines] = fileDiff.split(lineSeparator);
|
||||
|
||||
// merge multiple line-diffs into 1 to save tokens
|
||||
const mergedLines = mergeStrings(
|
||||
fileDiffByLines.map((line) => lineSeparator + line),
|
||||
MAX_REQ_TOKENS
|
||||
);
|
||||
|
||||
const lineDiffsWithHeader = mergedLines.map(
|
||||
(d) => fileHeader + lineSeparator + d
|
||||
);
|
||||
|
||||
const commitMsgsFromFileLineDiffs = lineDiffsWithHeader.map((d) => {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(separator + d);
|
||||
|
||||
return api.generateCommitMessage(messages);
|
||||
});
|
||||
|
||||
return commitMsgsFromFileLineDiffs;
|
||||
}
|
||||
|
||||
function getCommitMsgsPromisesFromFileDiffs(diff: string) {
|
||||
const separator = 'diff --git ';
|
||||
|
||||
const diffByFiles = diff.split(separator).slice(1);
|
||||
|
||||
// merge multiple files-diffs into 1 prompt to save tokens
|
||||
const mergedFilesDiffs = mergeStrings(diffByFiles, MAX_REQ_TOKENS);
|
||||
|
||||
const commitMessagePromises = [];
|
||||
|
||||
for (const fileDiff of mergedFilesDiffs) {
|
||||
if (fileDiff.length >= MAX_REQ_TOKENS) {
|
||||
// if file-diff is bigger than gpt context — split fileDiff into lineDiff
|
||||
const messagesPromises = getMessagesPromisesByLines(fileDiff, separator);
|
||||
|
||||
commitMessagePromises.push(...messagesPromises);
|
||||
} else {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(
|
||||
separator + fileDiff
|
||||
);
|
||||
|
||||
commitMessagePromises.push(api.generateCommitMessage(messages));
|
||||
}
|
||||
}
|
||||
return commitMessagePromises;
|
||||
}
|
||||
|
||||
14
src/utils/mergeStrings.ts
Normal file
14
src/utils/mergeStrings.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export function mergeStrings(arr: string[], maxStringLength: number): string[] {
|
||||
const mergedArr: string[] = [];
|
||||
let currentItem: string = arr[0];
|
||||
for (const item of arr.slice(1)) {
|
||||
if (currentItem.length + item.length <= maxStringLength) {
|
||||
currentItem += item;
|
||||
} else {
|
||||
mergedArr.push(currentItem);
|
||||
currentItem = item;
|
||||
}
|
||||
}
|
||||
mergedArr.push(currentItem);
|
||||
return mergedArr;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"lib": ["ES5"],
|
||||
"lib": ["ES5", "ES6"],
|
||||
|
||||
"module": "CommonJS",
|
||||
"module": "ESNext",
|
||||
// "rootDir": "./src",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
|
||||
Reference in New Issue
Block a user