Compare commits

..

53 Commits

Author SHA1 Message Date
di-sukharev
b54ff02930 1.1.18 2023-03-21 15:06:47 +08:00
di-sukharev
7fb46de105 1.1.17 2023-03-21 15:06:43 +08:00
di-sukharev
2f6e98dc30 style(commit.ts): format code with prettier
refactor(commit.ts): add types to commit function parameters
fix(git.ts): handle empty string returned from getStagedFiles function

refactor(mergeStrings.ts): remove unnecessary blank line and add missing semicolon
2023-03-21 15:06:30 +08:00
di-sukharev
2aa6582c52 Merge remote-tracking branch 'origin/dev' 2023-03-21 14:51:44 +08:00
openefit
2acf833cd0 fix(generateCommitMessageFromGitDiff.ts): remove unnecessary character at the end of the line (#36) 2023-03-19 16:04:06 +08:00
Stuart van Beek
3f7025d50a feat: add support for .opencommitignore file (#22)
* feat: add support for .opencommitignore
2023-03-19 16:01:57 +08:00
Nader Zouaoui
d793bf1340 feat: Add support for extra args to be passed to the git commit command (#17)
* feat: Add support for extra args to be passed to the git commit command
2023-03-19 15:58:21 +08:00
di-sukharev
0092e92061 1.1.16 2023-03-17 17:51:42 +08:00
di-sukharev
0f33b74942 1.1.15 2023-03-17 17:51:36 +08:00
di-sukharev
8f0a32275e 1.1.14 2023-03-17 17:50:39 +08:00
di-sukharev
b3509e34d0 1.1.13 2023-03-17 14:20:51 +08:00
di-sukharev
5449d5cd61 1.1.12 2023-03-17 14:20:39 +08:00
di-sukharev
b0d27e62ba Merge remote-tracking branch 'origin/master' into dev 2023-03-17 14:19:23 +08:00
openefit
5ae52cd8bb 🚀 i18n: add internationalization support (#31)
* 🚀  i18n: add internationalization support
2023-03-17 13:57:26 +08:00
Sukharev
57baedd0b0 Feature: add staged files multiple selection (#6) (#27)
* feat: add staged files multiple selection (#6)
2023-03-17 13:53:22 +08:00
di-sukharev
d4fc651fec refactor(git.ts): remove unused code and simplify getDiff function
feat(git.ts): add message for excluded lock files in getDiff function
2023-03-16 23:41:08 +08:00
di-sukharev
04d40b5379 refactor(git.ts): rename someFilesExcludedMessage to showSomeFilesExcludedMessage
feat(git.ts): replace text prompt with outro prompt in showSomeFilesExcludedMessage function
feat(git.ts): add support for showing excluded files message in getStagedFiles, getChangedFiles, gitAdd and getDiff functions
2023-03-16 23:28:47 +08:00
di-sukharev
ec2e4c628c fix(commit.ts): fix typo in outro message
feat(commit.ts): add support for staging all files and generating commit message when no files are staged
feat(commit.ts): add support for committing changes when no files are staged and some files are changed but not staged
2023-03-16 23:15:56 +08:00
di-sukharev
c787329710 chore(README.md): fix capitalization of OpenCommit in setup and usage sections
docs(README.md): fix typo in Git hook section
2023-03-16 23:14:29 +08:00
Vladyslav Kapkan
0d1f72bdec Feature: add staged files multiple selection (#6)
* chore(package.json): add "@bdsqqq/try" dependency
* refactor(api.ts): remove unnecessary whitespace
* refactor(cli.ts): remove unused imports and variables

* refactor(commit.ts): rename getStagedGitDiff to getDif
* refactor(commit.ts): add getStagedFiles and getChangedFiles functions
* feat(commit.ts): add multiselect prompt to select files to stage
* feat(commit.ts): add gitAdd function to stage selected files
* feat(commit.ts): add trytm function to handle errors
* feat(commit.ts): add exitProgram function to exit the program with an error message if an error occurs during execution

* refactor(commit.ts): refactor commit function to handle unstaged files
* feat(commit.ts): add multiselect prompt to select files to add to commit when there are unstaged files

* feat(git.ts): add getStagedFiles function to get list of staged files
* feat(git.ts): add getChangedFiles function to get list of changed files
* feat(git.ts): add gitAdd function to add files to commit
* feat(git.ts): add getDif function to get diff of staged files

* refactor(commit.ts): replace exitProgram function with process.exit(1) to exit the program

* refactor(commit.ts): change message prompt to English in multiselect function

* chore(package.json): add prettier to format code
* refactor(api.ts): remove unnecessary whitespace and comments

* refactor(commit.ts): add missing semicolons and fix formatting
* feat(commit.ts): add support for selecting files to add to the commit when there are changed files but no staged files

* refactor(commit.ts): add isStageAllFlag parameter to commit function
* refactor(commit.ts): add whitespace to getDif function call
* refactor(commit.ts): add whitespace to generateCommitMessageFromGitDiff function call

* refactor(git.ts): reformat code for better readability
* chore(git.ts): add semicolons to the end of each statement

* chore(package.json): remove "@bdsqqq/try" dependency
* refactor(commit.ts): move trytm function to utils/trytm.ts
* refactor(commit.ts): add isStageAllFlag parameter to gitAdd function call in commit function
* refactor(commit.ts): remove getStagedGitDiff function call and use getStagedFiles function call instead
* refactor(commit.ts): add error handling to generateCommitMessageFromGitDiff function call in commit function

* refactor(prepare-commit-msg-hook.ts): rename getStagedGitDiff to getStagedFiles
* feat(prepare-commit-msg-hook.ts): add gitAdd function to stage changes before generating commit message
* refactor(prepare-commit-msg-hook.ts): use getDif function to get staged changes diff instead of staged.diff
* refactor(prepare-commit-msg-hook.ts): remove unnecessary if statement and return statement

* refactor(git.ts): remove StagedDiff interface and getStagedGitDiff function
* feat(git.ts): add support for untracked files in getChangedFiles function
* refactor(git.ts): rename stdout variable in getChangedFiles function
* refactor(git.ts): add excludeBigFilesFromDiff to getDif function
* feat(trytm.ts): add trytm utility function for handling promises with try-catch block

* fix(commit.ts): add missing function call parentheses in return statement

* refactor(commit.ts): remove unused variable generateCommitResponse
* refactor(commit.ts): exit process with code 0 after successful commit

* fix(commit.ts): add check for no changes detected before opening commit prompt

* fix(commit.ts): fix typo in function name from getDif to getDiff
* fix(prepare-commit-msg-hook.ts): fix typo in function name from getDif to getDiff
* refactor(git.ts): rename getDif function to getDiff for consistency and clarity

* chore(git.ts): add excludeBigFilesFromDiff option to getStagedFiles function

* chore(git.ts): import text function from @clack/prompts package

* refactor(git.ts): remove excludeBigFilesFromDiff constant and filter out .lock files from getStagedFiles and getChangedFiles functions
* feat(git.ts): add error message when all staged files are .lock files
* feat(git.ts): add error message when all changed files are .lock files
* feat(git.ts): add warning message when some files are .lock files and excluded from git add and git diff

* refactor(git.ts): add filter to remove empty strings from returned array in getStagedFiles and getChangedFiles functions

* refactor(commit.ts): pass isStageAllFlag to getChangedFiles function
* fix(commit.ts): handle errorStagedFiles and errorChangedFiles variables

* fix(git.ts): filter out empty strings from excludedFiles array
* feat(git.ts): add isStageAllFlag parameter to getChangedFiles function to handle git add --all command

* refactor(git.ts): remove console.log statement from getChangedFiles function and refactor code to improve readability

* refactor(commit.ts): remove unnecessary parameter from getChangedFiles function call
* refactor(git.ts): remove isStageAllFlag parameter from getChangedFiles function and add check for .lock files in the returned files list

* refactor(commit.ts): remove unnecessary line breaks and whitespace
* refactor(commit.ts): remove unnecessary parentheses in function calls

* feat(git.ts): add someFilesExcludedMessage function to display excluded files message
* refactor(git.ts): use someFilesExcludedMessage function instead of text function in getChangedFiles, gitAdd, and getDiff functions

* refactor(git.ts): extract someFilesExcludedMessage function to handle excluded files message
* fix(git.ts): use someFilesExcludedMessage function instead of throwing an error when all staged files are excluded files

* refactor(git.ts): pad excluded files list with 5 spaces

* refactor(git.ts): remove unnecessary padStart method call in someFilesExcludedMessage function
* chore(git.ts): update someFilesExcludedMessage function to improve readability

---------

Co-authored-by: Sukharev <57486732+di-sukharev@users.noreply.github.com>
2023-03-16 22:41:21 +08:00
di-sukharev
5d0c69e849 1.1.11 2023-03-16 11:48:42 +08:00
di-sukharev
9754442efa chore(README.md): update Twitter handle in header 2023-03-16 11:48:31 +08:00
di-sukharev
a619cd1f78 docs(README.md): update payment information to include GPT-4 cost comparison 2023-03-15 17:35:25 +08:00
di-sukharev
1fc4a6b6c0 1.1.10 2023-03-15 17:33:55 +08:00
di-sukharev
798bddba81 docs(README.md): remove outdated information about minimum supported version of Node.js 2023-03-15 17:33:43 +08:00
di-sukharev
42ed2a31f4 fix(commit.ts): remove '-u' and 'origin' arguments from git push command to push to the current branch 2023-03-15 14:51:26 +08:00
di-sukharev
571e1e9d8f chore(TODO.md): mark batch small files in one request as completed
refactor(TODO.md): rephrase optimize prompt TODO to suggest exploring cleaner alternatives to prompt
2023-03-15 14:49:38 +08:00
di-sukharev
bd8de7a8ea feat(commit.ts): add '-u origin HEAD' flag to 'git push' command to set upstream branch and push current branch to it 2023-03-15 14:46:15 +08:00
di-sukharev
913bcd379f 1.1.9 2023-03-14 18:51:06 +08:00
di-sukharev
25468f67ad 1.1.8 2023-03-14 18:50:57 +08:00
Benny Neugebauer
6766f62848 Replace type assertion with built-in error detection (#10)
* refactor(api.ts): use built-in axios error detection
2023-03-14 18:50:25 +08:00
di-sukharev
71c36db265 1.1.7 2023-03-13 16:44:36 +08:00
di-sukharev
ed66e403e7 1.1.6 2023-03-13 16:44:19 +08:00
di-sukharev
b89e50ebbf * fix(generateCommitMessageFromGitDiff.ts): fix formatting of commit message prompt
* feat(generateCommitMessageFromGitDiff.ts): add description to commit message prompt
2023-03-13 16:43:59 +08:00
di-sukharev
38ebe49daa 1.1.5 2023-03-11 18:04:04 +08:00
di-sukharev
6ccded1f23 1.1.4 2023-03-11 13:24:58 +08:00
di-sukharev
31357132e4 * chore(api.ts): add error handling for openAI api error
* chore(generateCommitMessageFromGitDiff.ts): remove console.log statement
2023-03-11 13:24:02 +08:00
di-sukharev
b35a393152 * docs(README.md): add reminder to add payment details to OpenAI API key
* docs(api.ts): update error message to remind user to add payment details to OpenAI API key
* refactor(cli.ts): remove unused import
* refactor(config.ts): update error message to use outro instead of throwing an error and exit the process

* chore(generateCommitMessageFromGitDiff.ts): add console.log for error debugging
2023-03-11 13:23:46 +08:00
di-sukharev
8fe382a072 1.1.3 2023-03-11 01:02:37 +08:00
di-sukharev
4b703c634a * chore(TODO.md): update TODO list, remove completed task
* refactor(cli.ts): remove unnecessary async/await keywords, remove version check and "new version available" message
2023-03-11 01:01:26 +08:00
di-sukharev
6821e937cf 1.1.2 2023-03-11 00:58:18 +08:00
di-sukharev
69f3c48b2c * chore(TODO.md): mark "show new version available message" as completed
* chore(package.json): add `--tag latest` flag to `npm publish` command in `deploy` script
* refactor(cli.ts): add async/await to `prepareCommitMessageHook` and `commit` functions, and check for new version of `opencommit` after commit is made
2023-03-11 00:57:48 +08:00
di-sukharev
f49f1a86df * chore(package.json): update version from 1.0.17 to 1.1.1 2023-03-11 00:55:36 +08:00
di-sukharev
98945df561 1.0.17 2023-03-11 00:53:29 +08:00
di-sukharev
e8e190ff3d 1.0.16 2023-03-11 00:49:50 +08:00
di-sukharev
9c3f28b7c6 * chore(TODO.md): move TODO.md to .github/TODO.md
* chore(TODO.md): set prepare-commit-msg hook
* chore(cli.ts): remove async/await from commit and prepareCommitMessageHook calls
* feat(cli.ts): add check for new version available after commit
2023-03-11 00:49:22 +08:00
di-sukharev
e146d4d60d * fix(cli.ts): add curly braces to if statement in cli function to improve readability 2023-03-11 00:32:37 +08:00
di-sukharev
2ae35749a5 1.0.15 2023-03-11 00:28:58 +08:00
di-sukharev
8836c57fa4 * chore(commit.ts): add TODO comment to show proper error messages 2023-03-11 00:24:52 +08:00
di-sukharev
4b523e5782 1.0.14 2023-03-11 00:23:55 +08:00
di-sukharev
33491486bb * feat(CommandsEnum.ts): add COMMANDS enum
* refactor(api.ts): use CONFIG_MODES enum from config.ts
* refactor(config.ts): use COMMANDS and CONFIG_MODES enums, extract validateConfig function
* feat(config.ts): add CONFIG_MODES enum and refactor configCommand function to use it

* refactor(githook.ts): import COMMANDS enum from CommandsEnum.js file
2023-03-11 00:23:30 +08:00
di-sukharev
e76db8276b 1.0.13 2023-03-11 00:20:09 +08:00
di-sukharev
c2ae98170c * refactor(api.ts): move apiKey initialization to the top of the file
* feat(api.ts): add check for process arguments to avoid intro message if 'config set' command is used
2023-03-11 00:19:29 +08:00
26 changed files with 873 additions and 249 deletions

10
.github/TODO.md vendored Normal file
View File

@@ -0,0 +1,10 @@
# TODOs
- [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
- [x] batch small files in one request
- [] add tests
- [] optimize prompt, maybe no prompt would be cleaner

3
.gitignore vendored
View File

@@ -10,4 +10,5 @@ application.log
logfile.log
uncaughtExceptions.log
.vscode
src/*.json
src/*.json
.idea

View File

@@ -2,7 +2,7 @@
<div>
<img src=".github/logo-grad.svg" alt="OpenCommit logo"/>
<h1 align="center">OpenCommit</h1>
<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 align="center">Follow the bird <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>
<h2>GPT CLI to auto-generate impressive commits in 1 second</h2>
@@ -20,17 +20,15 @@ All the commits in this repo are done with OpenCommit — look into [the commits
## Setup
> The minimum supported version of Node.js is the latest v14. Check your Node.js version with `node --version`.
1. Install opencommit globally to use in any repository:
1. Install OpenCommit globally to use in any repository:
```sh
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:
3. Set the key to OpenCommit config:
```sh
opencommit config set OPENAI_API_KEY=<your_api_key>
@@ -40,7 +38,7 @@ All the commits in this repo are done with OpenCommit — look into [the commits
## Usage
You can call `opencommit` directly to generate a commit message for your staged changes:
You can call OpenCommit directly to generate a commit message for your staged changes:
```sh
git add <files...>
@@ -86,9 +84,35 @@ To remove description:
oc config set description=false
```
### Git flags
The `opencommit` or `oc` commands can be used in place of the `git commit -m "${generatedMessage}"` command. This means that any regular flags that are used with the `git commit` command will also be applied when using `opencommit` or `oc`.
```sh
oc --no-verify
```
is translated to :
```sh
git commit -m "${generatedMessage}" --no-verify
```
### Ignore files
You can ignore files from submission to OpenAI by creating a `.opencommitignore` file. For example:
```ignorelang
path/to/large-asset.zip
**/*.jpg
```
This is useful for preventing opencommit from uploading artifacts and large files.
By default, opencommit ignores files matching: `*-lock.*` and `*.lock`
## Git hook
You can set opencommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. Hook integrates with you IDE Source Control and allows you edit the message before commit.
You can set OpenCommit as Git [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. Hook integrates with you IDE Source Control and allows you edit the message before commit.
To set the hook:
@@ -113,4 +137,4 @@ Or follow the process of your IDE Source Control feature, when it calls `git com
## Payments
You pay for your own requests to OpenAI API. OpenCommit uses ChatGPT official model, that is ~10x times cheaper than GPT-3.
You pay for your own requests to OpenAI API. OpenCommit uses ChatGPT official model, that is ~10x times cheaper than GPT-3 and ~6x times cheaper than GPT-4.

View File

@@ -1,8 +0,0 @@
# TODOs
- [] 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

596
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "open-commit",
"version": "1.0.12",
"name": "opencommit",
"version": "1.1.18",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "open-commit",
"version": "1.0.12",
"name": "opencommit",
"version": "1.1.18",
"license": "ISC",
"dependencies": {
"@clack/prompts": "^0.6.1",
@@ -14,13 +14,14 @@
"chalk": "^5.2.0",
"cleye": "^1.3.2",
"execa": "^7.0.0",
"ignore": "^5.2.4",
"ini": "^3.0.1",
"inquirer": "^9.1.4",
"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",
@@ -31,28 +32,29 @@
"dotenv": "^16.0.3",
"esbuild": "^0.15.18",
"eslint": "^8.28.0",
"prettier": "^2.8.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.3"
}
},
"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 +83,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 +308,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 +342,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 +369,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 +386,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 +413,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 +426,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 +453,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 +479,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 +576,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 +965,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 +1029,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 +1403,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 +1474,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 +1555,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",
@@ -1557,7 +1881,6 @@
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
}
@@ -1890,11 +2213,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 +2293,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"
@@ -2172,6 +2498,21 @@
"node": ">= 0.8.0"
}
},
"node_modules/prettier": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
"integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -2207,9 +2548,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 +2596,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 +2682,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 +2941,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 +2960,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 +3089,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",

View File

@@ -1,6 +1,6 @@
{
"name": "opencommit",
"version": "1.0.12",
"version": "1.1.18",
"description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
"keywords": [
"git",
@@ -41,8 +41,9 @@
"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",
"lint": "eslint src --ext ts && tsc --noEmit"
"deploy": "npm run build && npm version patch && npm publish --tag latest",
"lint": "eslint src --ext ts && tsc --noEmit",
"format": "prettier --write src"
},
"devDependencies": {
"@types/ini": "^1.3.31",
@@ -53,6 +54,7 @@
"dotenv": "^16.0.3",
"esbuild": "^0.15.18",
"eslint": "^8.28.0",
"prettier": "^2.8.4",
"ts-node": "^10.9.1",
"typescript": "^4.9.3"
},
@@ -62,6 +64,7 @@
"chalk": "^5.2.0",
"cleye": "^1.3.2",
"execa": "^7.0.0",
"ignore": "^5.2.4",
"ini": "^3.0.1",
"inquirer": "^9.1.4",
"openai": "^3.2.1"

4
src/CommandsEnum.ts Normal file
View File

@@ -0,0 +1,4 @@
export enum COMMANDS {
config = 'config',
hook = 'hook'
}

View File

@@ -1,38 +1,33 @@
import { intro, outro } from '@clack/prompts';
import axios from 'axios';
import chalk from 'chalk';
import {
ChatCompletionRequestMessage,
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
@@ -55,9 +50,19 @@ class OpenAi {
const message = data.choices[0].message;
return message?.content;
} catch (error) {
// console.error('openAI api error', { error });
throw error;
} catch (error: unknown) {
outro(`${chalk.red('✖')} ${error}`);
if (axios.isAxiosError<{ error?: { message: string } }>(error) && error.response?.status === 401) {
const openAiError = error.response.data.error;
if (openAiError?.message) outro(openAiError.message);
outro(
'For help look into README https://github.com/di-sukharev/opencommit#setup'
);
}
process.exit(1);
}
};
}

View File

@@ -7,10 +7,8 @@ import { configCommand } from './commands/config';
import { hookCommand, isHookCalled } from './commands/githook.js';
import { prepareCommitMessageHook } from './commands/prepare-commit-msg-hook';
import { commit } from './commands/commit';
import { execa } from 'execa';
import { outro } from '@clack/prompts';
const rawArgv = process.argv.slice(2);
const extraArgs = process.argv.slice(2);
cli(
{
@@ -21,18 +19,12 @@ cli(
ignoreArgv: (type) => type === 'unknown-flag' || type === 'argument',
help: { description: packageJSON.description }
},
async () => {
() => {
if (isHookCalled) {
await prepareCommitMessageHook();
prepareCommitMessageHook();
} else {
await commit();
const { stdout } = await execa('npm', ['view', 'opencommit', 'version']);
if (stdout !== packageJSON.version)
outro(
'new opencommit version is available, update with `npm i -g opencommit`'
);
commit(extraArgs);
}
},
rawArgv
extraArgs
);

View File

@@ -3,12 +3,27 @@ import {
GenerateCommitMessageErrorEnum,
generateCommitMessageWithChatCompletion
} from '../generateCommitMessageFromGitDiff';
import { assertGitRepo, getStagedGitDiff } from '../utils/git';
import { spinner, confirm, outro, isCancel, intro } from '@clack/prompts';
import {
assertGitRepo,
getChangedFiles,
getDiff,
getStagedFiles,
gitAdd
} from '../utils/git';
import {
spinner,
confirm,
outro,
isCancel,
intro,
multiselect
} from '@clack/prompts';
import chalk from 'chalk';
import { trytm } from '../utils/trytm';
const generateCommitMessageFromGitDiff = async (
diff: string
diff: string,
extraArgs: string[]
): Promise<void> => {
await assertGitRepo();
@@ -16,6 +31,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,9 +60,17 @@ ${chalk.grey('——————————————————')}`
});
if (isCommitConfirmedByUser && !isCancel(isCommitConfirmedByUser)) {
const { stdout } = await execa('git', ['commit', '-m', commitMessage]);
const { stdout } = await execa('git', [
'commit',
'-m',
commitMessage,
...extraArgs
]);
outro(`${chalk.green('✔')} successfully committed`);
outro(stdout);
const isPushConfirmedByUser = await confirm({
message: 'Do you want to run `git push`?'
});
@@ -56,6 +80,7 @@ ${chalk.grey('——————————————————')}`
pushSpinner.start('Running `git push`');
const { stdout } = await execa('git', ['push']);
pushSpinner.stop(`${chalk.green('✔')} successfully pushed all commits`);
if (stdout) outro(stdout);
@@ -63,36 +88,39 @@ ${chalk.grey('——————————————————')}`
} else outro(`${chalk.gray('✖')} process cancelled`);
};
export async function commit(isStageAllFlag = false) {
intro('open-commit');
export async function commit(
extraArgs: string[] = [],
isStageAllFlag: Boolean = false
) {
if (isStageAllFlag) {
const changedFiles = await getChangedFiles();
const stagedFilesSpinner = spinner();
stagedFilesSpinner.start('Counting staged files');
const staged = await getStagedGitDiff(isStageAllFlag);
if (changedFiles) await gitAdd({ files: changedFiles });
else {
outro('No changes detected, write some code and run `oc` again');
process.exit(1);
}
}
if (!staged && isStageAllFlag) {
outro(
`${chalk.red(
'No changes detected'
)} — write some code, stage the files ${chalk
.hex('0000FF')
.bold('`git add .`')} and rerun ${chalk
.hex('0000FF')
.bold('`oc`')} command.`
);
const [stagedFiles, errorStagedFiles] = await trytm(getStagedFiles());
const [changedFiles, errorChangedFiles] = await trytm(getChangedFiles());
if (!changedFiles?.length && !stagedFiles?.length) {
outro(chalk.red('No changes detected'));
process.exit(1);
}
if (!staged) {
outro(
`${chalk.red('Nothing to commit')} — stage the files ${chalk
.hex('0000FF')
.bold('`git add .`')} and rerun ${chalk
.hex('0000FF')
.bold('`oc`')} command.`
);
intro('open-commit');
if (errorChangedFiles ?? errorStagedFiles) {
outro(`${chalk.red('✖')} ${errorChangedFiles ?? errorStagedFiles}`);
process.exit(1);
}
const stagedFilesSpinner = spinner();
stagedFilesSpinner.start('Counting staged files');
if (!stagedFiles.length) {
stagedFilesSpinner.stop('No files are staged');
const isStageAllAndCommitConfirmedByUser = await confirm({
message: 'Do you want to stage all files and generate commit message?'
@@ -102,17 +130,45 @@ export async function commit(isStageAllFlag = false) {
isStageAllAndCommitConfirmedByUser &&
!isCancel(isStageAllAndCommitConfirmedByUser)
) {
await commit(true);
await commit(extraArgs, true);
process.exit(1);
}
if (stagedFiles.length === 0 && changedFiles.length > 0) {
const files = (await multiselect({
message: chalk.cyan('Select the files you want to add to the commit:'),
options: changedFiles.map((file) => ({
value: file,
label: file
}))
})) as string[];
if (isCancel(files)) process.exit(1);
await gitAdd({ files });
}
await commit(extraArgs, false);
process.exit(1);
}
stagedFilesSpinner.stop(
`${staged.files.length} staged files:\n${staged.files
`${stagedFiles.length} staged files:\n${stagedFiles
.map((file) => ` ${file}`)
.join('\n')}`
);
await generateCommitMessageFromGitDiff(staged.diff);
const [, generateCommitError] = await trytm(
generateCommitMessageFromGitDiff(
await getDiff({ files: stagedFiles }),
extraArgs
)
);
if (generateCommitError) {
outro(`${chalk.red('✖')} ${generateCommitError}`);
process.exit(1);
}
process.exit(0);
}

View File

@@ -5,11 +5,19 @@ import { existsSync, writeFileSync, readFileSync } from 'fs';
import { homedir } from 'os';
import { intro, outro } from '@clack/prompts';
import chalk from 'chalk';
import { COMMANDS } from '../CommandsEnum';
import { getI18nLocal } from '../i18n';
export enum CONFIG_KEYS {
OPENAI_API_KEY = 'OPENAI_API_KEY',
description = 'description',
emoji = 'emoji'
emoji = 'emoji',
language = 'language'
}
export enum CONFIG_MODES {
get = 'get',
set = 'set'
}
const validateConfig = (
@@ -18,7 +26,10 @@ const validateConfig = (
validationMessage: string
) => {
if (!condition) {
throw new Error(`Unsupported config key ${key}: ${validationMessage}`);
outro(
`${chalk.red('✖')} Unsupported config key ${key}: ${validationMessage}`
);
process.exit(1);
}
};
@@ -55,6 +66,14 @@ export const configValidators = {
);
return value;
},
[CONFIG_KEYS.language](value: any) {
validateConfig(
CONFIG_KEYS.language,
getI18nLocal(value),
`${value} is not supported yet`
);
return getI18nLocal(value);
}
};
@@ -110,7 +129,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 +137,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])
);

View File

@@ -5,6 +5,7 @@ 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}`;
@@ -15,7 +16,7 @@ const isHookExists = existsSync(SYMLINK_URL);
export const hookCommand = command(
{
name: 'hook',
name: COMMANDS.hook,
parameters: ['<set/unset>']
},
async (argv) => {

View File

@@ -1,7 +1,7 @@
import fs from 'fs/promises';
import chalk from 'chalk';
import { intro, outro } from '@clack/prompts';
import { getStagedGitDiff } from '../utils/git';
import { getChangedFiles, getDiff, getStagedFiles, gitAdd } from '../utils/git';
import { getConfig } from './config';
import { generateCommitMessageWithChatCompletion } from '../generateCommitMessageFromGitDiff';
@@ -17,7 +17,14 @@ export const prepareCommitMessageHook = async () => {
if (commitSource) return;
const staged = await getStagedGitDiff();
const changedFiles = await getChangedFiles();
if (changedFiles) await gitAdd({ files: changedFiles });
else {
outro("No changes detected, write some code and run `oc` again");
process.exit(1);
}
const staged = await getStagedFiles();
if (!staged) return;
@@ -32,7 +39,7 @@ export const prepareCommitMessageHook = async () => {
}
const commitMessage = await generateCommitMessageWithChatCompletion(
staged.diff
await getDiff({ files: staged })
);
if (typeof commitMessage !== 'string') throw new Error(commitMessage.error);

View File

@@ -5,8 +5,10 @@ import {
import { api } from './api';
import { getConfig } from './commands/config';
import { mergeStrings } from './utils/mergeStrings';
import { i18n, I18nLocals } from './i18n';
const config = getConfig();
const translation = i18n[config?.language as I18nLocals || 'en']
const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
{
@@ -18,8 +20,8 @@ const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
}, use the present tense. ${
config?.description
? 'Add a short description of what commit is about after the commit message. Don\'t start it with "This commit", just describe the changes.'
: "Don't add any descriptions to the commit, only commit message."
}`
: 'Don\'t add any descriptions to the commit, only commit message.'
} Use ${translation.localLanguage} to answer.`
},
{
role: ChatCompletionRequestMessageRoleEnum.User,
@@ -48,10 +50,9 @@ 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
${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.' : ''}`
content: `${config?.emoji ? '🐛 ' : ''}${translation.commitFix}
${config?.emoji ? ' ' : ''}${translation.commitFeat}
${config?.description ? translation.commitDescription : ''}`
}
];

6
src/i18n/de.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "Deutsch",
"commitFix": "fix(server.ts): Ändere die Groß- und Kleinschreibung der Port-Variable von Kleinbuchstaben auf Großbuchstaben PORT.",
"commitFeat": "Funktion(server.ts): Unterstützung für die Umgebungsvariable process.env.PORT hinzufügen",
"commitDescription": "Die Port-Variable heißt jetzt PORT, was die Konsistenz mit den Namenskonventionen verbessert, da PORT eine Konstante ist. Die Unterstützung für eine Umgebungsvariable ermöglicht es der Anwendung, flexibler zu sein, da sie jetzt auf jedem verfügbaren Port laufen kann, der über die Umgebungsvariable process.env.PORT angegeben wird."
}

6
src/i18n/en.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "english",
"commitFix": "fix(server.ts): change port variable case from lowercase port to uppercase PORT",
"commitFeat": "feat(server.ts): add support for process.env.PORT environment variable",
"commitDescription": "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."
}

6
src/i18n/fr.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "française",
"commitFix": "corriger(server.ts) : changer la casse de la variable de port de minuscules à majuscules (PORT)",
"commitFeat": "fonctionnalité(server.ts) : ajouter la prise en charge de la variable d'environnement process.env.PORT",
"commitDescription": "La variable de port est maintenant nommée PORT, ce qui améliore la cohérence avec les conventions de nommage car PORT est une constante. La prise en charge d'une variable d'environnement permet à l'application d'être plus flexible car elle peut maintenant s'exécuter sur n'importe quel port disponible spécifié via la variable d'environnement process.env.PORT."
}

50
src/i18n/index.ts Normal file
View File

@@ -0,0 +1,50 @@
import en from '../i18n/en.json' assert { type: 'json' };
import de from '../i18n/de.json' assert { type: 'json' };
import fr from '../i18n/fr.json' assert { type: 'json' };
import it from '../i18n/it.json' assert { type: 'json' };
import ko from '../i18n/ko.json' assert { type: 'json' };
import zh_CN from '../i18n/zh_CN.json' assert { type: 'json' };
import zh_TW from '../i18n/zh_TW.json' assert { type: 'json' };
import ja from '../i18n/ja.json' assert { type: 'json' };
export enum I18nLocals {
'en' = 'en',
'zh_CN' = 'zh_CN',
'zh_TW' = 'zh_TW',
'ja' = 'ja',
'de' = 'de',
'fr' = 'fr',
'it' = 'it',
'ko' = 'ko'
};
export const i18n = {
en,
zh_CN,
zh_TW,
ja,
de,
fr,
it,
ko,
};
export const I18N_CONFIG_ALIAS: { [key: string]: string[] } = {
zh_CN: ['zh_CN', '简体中文', '中文', '简体'],
zh_TW: ['zh_TW', '繁體中文', '繁體'],
ja: ['ja', 'Japanese', 'にほんご'],
ko: ['ko', 'Korean', '한국어'],
de: ['de', 'German' ,'Deutsch'],
fr: ['fr', 'French', 'française'],
it: ['it', 'Italian', 'italiano'],
};
export function getI18nLocal(value: string): string | boolean {
for (const key in I18N_CONFIG_ALIAS) {
const aliases = I18N_CONFIG_ALIAS[key];
if (aliases.includes(value)) {
return key;
}
}
return false;
}

6
src/i18n/it.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "italiano",
"commitFix": "fix(server.ts): cambia il caso della variabile di porta da minuscolo port a maiuscolo PORT",
"commitFeat": "funzionalità(server.ts): aggiungi supporto per la variabile di ambiente process.env.PORT",
"commitDescription": "La variabile di porta è ora chiamata PORT, il che migliora la coerenza con le convenzioni di denominazione in quanto PORT è una costante. Il supporto per una variabile di ambiente consente all'applicazione di essere più flessibile poiché ora può essere eseguita su qualsiasi porta disponibile specificata tramite la variabile di ambiente process.env.PORT."
}

6
src/i18n/ja.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "にほんご",
"commitFix": "修正(server.ts): ポート変数のケースを小文字のポートから大文字のPORTに変更",
"commitFeat": "新機能(server.ts): process.env.PORT環境変数のサポートを追加する",
"commitDescription": "ポート変数は現在PORTという名前になっており、PORTは定数であるため命名規則に一貫性があります。環境変数のサポートにより、アプリケーションはより柔軟になり、process.env.PORT環境変数で指定された任意の利用可能なポートで実行できるようになりまし"
}

6
src/i18n/ko.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "한국어",
"commitFix": "fix(server.ts): 포트 변수를 소문자 port에서 대문자 PORT로 변경",
"commitFeat": "피트(server.ts): process.env.PORT 환경 변수 지원 추가",
"commitDescription": "포트 변수는 이제 PORT로 이름이 지정되어 상수인 PORT와 일관성 있는 이름 규칙을 따릅니다. 환경 변수 지원을 통해 애플리케이션은 이제 process.env.PORT 환경 변수로 지정된 사용 가능한 모든 포트에서 실행할 수 있으므로 더 유연해졌습니다."
}

6
src/i18n/zh_CN.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "简体中文",
"commitFix": "修复(server.ts)将端口变量从小写port改为大写PORT",
"commitFeat": "功能(server.ts)添加对process.env.PORT环境变量的支持",
"commitDescription": "现在端口变量被命名为PORT这提高了命名约定的一致性因为PORT是一个常量。环境变量的支持使应用程序更加灵活因为它现在可以通过process.env.PORT环境变量在任何可用端口上运行。"
}

6
src/i18n/zh_TW.json Normal file
View File

@@ -0,0 +1,6 @@
{
"localLanguage": "繁體中文",
"commitFix": "修正(server.ts)將端口變數從小寫端口改為大寫PORT",
"commitFeat": "功能(server.ts)新增對process.env.PORT環境變數的支援",
"commitDescription": "現在port變數已更名為PORT以符合命名慣例因為PORT是一個常量。支援環境變數可以使應用程序更靈活因為它現在可以通過process.env.PORT環境變數運行在任何可用端口上。"
}

View File

@@ -1,5 +1,7 @@
import { execa } from 'execa';
import { spinner } from '@clack/prompts';
import { outro, spinner } from '@clack/prompts';
import { readFileSync } from 'fs';
import ignore, { Ignore } from 'ignore';
export const assertGitRepo = async () => {
try {
@@ -9,41 +11,84 @@ export const assertGitRepo = async () => {
}
};
const excludeBigFilesFromDiff = ['*-lock.*', '*.lock'].map(
(file) => `:(exclude)${file}`
);
// const excludeBigFilesFromDiff = ['*-lock.*', '*.lock'].map(
// (file) => `:(exclude)${file}`
// );
export interface StagedDiff {
files: string[];
diff: string;
}
export const getOpenCommitIgnore = (): Ignore => {
const ig = ignore();
export const getStagedGitDiff = async (
isStageAllFlag = false
): Promise<StagedDiff | null> => {
if (isStageAllFlag) {
const stageAllSpinner = spinner();
stageAllSpinner.start('Staging all changes');
await execa('git', ['add', '.']);
stageAllSpinner.stop('Done');
try {
ig.add(readFileSync('.opencommitignore').toString().split('\n'));
} catch (e) {}
return ig;
};
export const getStagedFiles = async (): Promise<string[]> => {
const { stdout: files } = await execa('git', [
'diff',
'--name-only',
'--cached'
]);
if (!files) return [];
const filesList = files.split('\n');
const ig = getOpenCommitIgnore();
const allowedFiles = filesList.filter((file) => !ig.ignores(file));
if (!allowedFiles) return [];
return allowedFiles.sort();
};
export const getChangedFiles = async (): Promise<string[]> => {
const { stdout: modified } = await execa('git', ['ls-files', '--modified']);
const { stdout: others } = await execa('git', [
'ls-files',
'--others',
'--exclude-standard'
]);
const files = [...modified.split('\n'), ...others.split('\n')].filter(
(file) => !!file
);
return files.sort();
};
export const gitAdd = async ({ files }: { files: string[] }) => {
const gitAddSpinner = spinner();
gitAddSpinner.start('Adding files to commit');
await execa('git', ['add', ...files]);
gitAddSpinner.stop('Done');
};
export const getDiff = async ({ files }: { files: string[] }) => {
const lockFiles = files.filter(
(file) => file.includes('.lock') || file.includes('-lock.')
);
if (lockFiles.length) {
outro(
`Some files are '.lock' files which are excluded by default from 'git diff'. No commit messages are generated for this files:\n${lockFiles.join(
'\n'
)}`
);
}
const diffStaged = ['diff', '--staged'];
const { stdout: files } = await execa('git', [
...diffStaged,
'--name-only',
...excludeBigFilesFromDiff
]);
if (!files) return null;
const filesWithoutLocks = files.filter(
(file) => !file.includes('.lock') && !file.includes('-lock.')
);
const { stdout: diff } = await execa('git', [
...diffStaged,
...excludeBigFilesFromDiff
'diff',
'--staged',
'--',
...filesWithoutLocks
]);
return {
files: files.split('\n').sort(),
diff
};
return diff;
};

View File

@@ -9,6 +9,8 @@ export function mergeStrings(arr: string[], maxStringLength: number): string[] {
currentItem = item;
}
}
mergedArr.push(currentItem);
return mergedArr;
}

12
src/utils/trytm.ts Normal file
View File

@@ -0,0 +1,12 @@
export const trytm = async <T>(
promise: Promise<T>
): Promise<[T, null] | [null, Error]> => {
try {
const data = await promise;
return [data, null];
} catch (throwable) {
if (throwable instanceof Error) return [null, throwable];
throw throwable;
}
};