commitlint-config-spellbookx 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +19 -7
- package/.turbo/turbo-test.log +59 -0
- package/README.md +211 -30
- package/__tests__/index.test.ts +47 -0
- package/__tests__/lint.test.ts +65 -0
- package/__tests__/scopes.test.ts +55 -0
- package/__tests__/workspaces.test.ts +76 -0
- package/dist/constants/commit-types.d.ts +13 -0
- package/dist/constants/commit-types.d.ts.map +1 -0
- package/dist/constants/commit-types.js +24 -0
- package/dist/get-scopes-D9bIfVqN.js +5698 -0
- package/dist/get-workspaces-raw-path-Cg196xaD.js +2043 -0
- package/dist/helpers.d.ts +8 -17
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +21 -0
- package/dist/index.d.ts +14 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -7878
- package/dist/lib/find-git-root.d.ts +16 -0
- package/dist/lib/find-git-root.d.ts.map +1 -0
- package/dist/lib/find-git-root.js +30 -0
- package/dist/lib/get-scope-description.d.ts +21 -0
- package/dist/lib/get-scope-description.d.ts.map +1 -0
- package/dist/lib/get-scope-description.js +35 -0
- package/dist/lib/get-scopes.d.ts +16 -0
- package/dist/lib/get-scopes.d.ts.map +1 -0
- package/dist/lib/get-scopes.js +4 -0
- package/dist/lib/get-workspaces-raw-path.d.ts +19 -0
- package/dist/lib/get-workspaces-raw-path.d.ts.map +1 -0
- package/dist/lib/get-workspaces-raw-path.js +3 -0
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +7 -0
- package/dist/lib/package-json.d.ts +14 -0
- package/dist/lib/package-json.d.ts.map +1 -0
- package/dist/lib/package-json.js +16 -0
- package/dist/prompt.d.ts +10 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +99 -0
- package/dist/rules.d.ts +10 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +45 -0
- package/dist/scopes.d.ts +23 -0
- package/dist/scopes.d.ts.map +1 -0
- package/dist/scopes.js +38 -0
- package/package.json +43 -9
- package/rolldown.config.ts +13 -1
- package/src/constants/commit-types.ts +26 -0
- package/src/index.ts +26 -153
- package/src/lib/find-git-root.ts +31 -0
- package/src/lib/get-scope-description.ts +38 -0
- package/src/lib/get-scopes.ts +89 -0
- package/src/lib/get-workspaces-raw-path.ts +53 -0
- package/src/lib/index.ts +10 -0
- package/src/lib/package-json.ts +22 -0
- package/src/prompt.ts +99 -0
- package/src/rules.ts +22 -0
- package/src/scopes.ts +40 -0
- package/tsconfig.json +1 -0
- package/src/helpers.ts +0 -123
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
> commitlint-config-spellbookx@0.
|
|
3
|
-
> rolldown -c && tsc
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
|
|
2
|
+
> commitlint-config-spellbookx@0.12.0 build /home/dcdavidev/spellbookx/packages/commitlint-config-spellbookx
|
|
3
|
+
> rolldown -c && tsc
|
|
4
|
+
|
|
5
|
+
<DIR>/lib/get-workspaces-raw-path.js chunk │ size: 0.12 kB
|
|
6
|
+
<DIR>/lib/get-scopes.js chunk │ size: 0.13 kB
|
|
7
|
+
<DIR>/constants/commit-types.js chunk │ size: 0.39 kB
|
|
8
|
+
<DIR>/lib/index.js chunk │ size: 0.40 kB
|
|
9
|
+
<DIR>/lib/package-json.js chunk │ size: 0.50 kB
|
|
10
|
+
<DIR>/rules.js chunk │ size: 0.66 kB
|
|
11
|
+
<DIR>/lib/find-git-root.js chunk │ size: 0.80 kB
|
|
12
|
+
<DIR>/index.js chunk │ size: 1.03 kB
|
|
13
|
+
<DIR>/lib/get-scope-description.js chunk │ size: 1.05 kB
|
|
14
|
+
<DIR>/scopes.js chunk │ size: 1.10 kB
|
|
15
|
+
<DIR>/prompt.js chunk │ size: 2.59 kB
|
|
16
|
+
<DIR>/get-workspaces-raw-path-Cg196xaD.js chunk │ size: 80.88 kB
|
|
17
|
+
<DIR>/get-scopes-D9bIfVqN.js chunk │ size: 188.65 kB
|
|
18
|
+
|
|
19
|
+
✔ rolldown v1.0.0-rc.5 Finished in 89.57 ms
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
> commitlint-config-spellbookx@0.11.1 test /home/dcdavidev/spellbookx/packages/commitlint-config-spellbookx
|
|
3
|
+
> vitest run
|
|
4
|
+
|
|
5
|
+
[?25l
|
|
6
|
+
RUN v5.0.5 /home/dcdavidev/spellbookx/packages/commitlint-config-spellbookx
|
|
7
|
+
|
|
8
|
+
[?2026h
|
|
9
|
+
❯ __tests__/index.test.ts [queued]
|
|
10
|
+
|
|
11
|
+
Test Files 0 passed (4)
|
|
12
|
+
Tests 0 passed (0)
|
|
13
|
+
Start at 16:06:47
|
|
14
|
+
Duration 100ms
|
|
15
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K
|
|
16
|
+
❯ __tests__/index.test.ts [queued]
|
|
17
|
+
❯ __tests__/lint.test.ts [queued]
|
|
18
|
+
❯ __tests__/workspaces.test.ts [queued]
|
|
19
|
+
|
|
20
|
+
Test Files 0 passed (4)
|
|
21
|
+
Tests 0 passed (0)
|
|
22
|
+
Start at 16:06:47
|
|
23
|
+
Duration 301ms
|
|
24
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K
|
|
25
|
+
❯ __tests__/index.test.ts 1/3
|
|
26
|
+
❯ __tests__/lint.test.ts [queued]
|
|
27
|
+
❯ __tests__/scopes.test.ts [queued]
|
|
28
|
+
❯ __tests__/workspaces.test.ts [queued]
|
|
29
|
+
|
|
30
|
+
Test Files 0 passed (4)
|
|
31
|
+
Tests 1 passed (3)
|
|
32
|
+
Start at 16:06:47
|
|
33
|
+
Duration 402ms
|
|
34
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K ✓ __tests__/index.test.ts (3 tests) 15ms
|
|
35
|
+
✓ __tests__/workspaces.test.ts (5 tests) 46ms
|
|
36
|
+
|
|
37
|
+
❯ __tests__/lint.test.ts [queued]
|
|
38
|
+
❯ __tests__/scopes.test.ts 0/4
|
|
39
|
+
|
|
40
|
+
Test Files 2 passed (4)
|
|
41
|
+
Tests 8 passed (12)
|
|
42
|
+
Start at 16:06:47
|
|
43
|
+
Duration 603ms
|
|
44
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K ✓ __tests__/scopes.test.ts (4 tests) 20ms
|
|
45
|
+
|
|
46
|
+
❯ __tests__/lint.test.ts 0/7
|
|
47
|
+
|
|
48
|
+
Test Files 3 passed (4)
|
|
49
|
+
Tests 12 passed (19)
|
|
50
|
+
Start at 16:06:47
|
|
51
|
+
Duration 904ms
|
|
52
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K ✓ __tests__/lint.test.ts (7 tests) 24ms
|
|
53
|
+
|
|
54
|
+
Test Files 4 passed (4)
|
|
55
|
+
Tests 19 passed (19)
|
|
56
|
+
Start at 16:06:47
|
|
57
|
+
Duration 1.02s (import 81%, transform 9%, tests 7%, worker 3%)
|
|
58
|
+
|
|
59
|
+
[?2026l[?2026h[?2026l[?25h
|
package/README.md
CHANGED
|
@@ -1,63 +1,234 @@
|
|
|
1
1
|
# commitlint-config-spellbookx
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modern, highly modular, and opinionated [Commitlint](https://commitlint.js.org/) configuration for the Spellbookx ecosystem. It enforces the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification, automatically discovers monorepo package scopes, and provides an interactive [cz-git](https://cz-git.qbenben.com/) Commitizen prompt with emojis.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Features
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
9
|
+
| Feature | Description |
|
|
10
|
+
| :---------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
|
+
| **Conventional Commits** | Extends `@commitlint/config-conventional` with strict, opinionated rules (72-char headers, 100-char bodies/footers, no trailing periods). |
|
|
12
|
+
| **Dynamic Monorepo Scopes** | Automatically discovers workspace packages from `pnpm-workspace.yaml`, `package.json`, and `lerna.json`. |
|
|
13
|
+
| **Standard Special Scopes** | Built-in support for `workspace` (root/infra changes) and `release` (versioning commits). |
|
|
14
|
+
| **Interactive cz-git Prompt** | Out-of-the-box support for `commitizen` with rich emojis, descriptions, and multi-scope selection. |
|
|
15
|
+
| **Modular Architecture** | Import individual building blocks (`rules`, `prompt`, `scopes`, `COMMIT_TYPES`) or atomic functions (`lib/`). |
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
---
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
## Supported Commit Types
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
| Type | Emoji | Title | Description |
|
|
22
|
+
| :------------- | :---: | :---------------------- | :-------------------------------------------------------------------------------- |
|
|
23
|
+
| **`feat`** | ✨ | Features | A new feature for the user or codebase |
|
|
24
|
+
| **`fix`** | 🐛 | Bug Fixes | A bug fix |
|
|
25
|
+
| **`docs`** | 📚 | Documentation | Documentation only changes |
|
|
26
|
+
| **`style`** | 💎 | Styles | Changes that do not affect the meaning of the code (whitespace, formatting, etc.) |
|
|
27
|
+
| **`refactor`** | 📦 | Code Refactoring | A code change that neither fixes a bug nor adds a feature |
|
|
28
|
+
| **`perf`** | 🚀 | Performance | A code change that improves performance |
|
|
29
|
+
| **`test`** | 🚨 | Tests | Adding missing tests or correcting existing tests |
|
|
30
|
+
| **`build`** | 🛠 | Builds | Changes that affect the build system or external dependencies |
|
|
31
|
+
| **`ci`** | ⚙️ | Continuous Integrations | Changes to CI configuration files and scripts |
|
|
32
|
+
| **`chore`** | ♻️ | Chores | Other changes that don't modify src or test files |
|
|
33
|
+
| **`revert`** | 🗑 | Reverts | Reverts a previous commit |
|
|
21
34
|
|
|
22
|
-
|
|
35
|
+
---
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
## Installation
|
|
25
38
|
|
|
26
|
-
**npm
|
|
39
|
+
Install the package and commitlint using **npm**:
|
|
27
40
|
|
|
28
41
|
```bash
|
|
29
42
|
npm install --save-dev commitlint-config-spellbookx @commitlint/cli
|
|
30
43
|
```
|
|
31
44
|
|
|
32
|
-
|
|
45
|
+
---
|
|
33
46
|
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
Commitlint loads configuration from standard config files in your repository root. You can use this package in multiple ways depending on your project needs:
|
|
50
|
+
|
|
51
|
+
### 1. Default Export (Recommended)
|
|
52
|
+
|
|
53
|
+
The simplest way to use this preset:
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// commitlint.config.mjs
|
|
57
|
+
export { default } from 'commitlint-config-spellbookx';
|
|
36
58
|
```
|
|
37
59
|
|
|
38
|
-
|
|
60
|
+
### 2. Customizing Rules
|
|
39
61
|
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
Extend and customize specific commitlint rules while keeping the shared defaults:
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
// commitlint.config.mjs
|
|
66
|
+
import { config, rules } from 'commitlint-config-spellbookx';
|
|
67
|
+
|
|
68
|
+
export default {
|
|
69
|
+
...config,
|
|
70
|
+
rules: {
|
|
71
|
+
...rules,
|
|
72
|
+
'header-max-length': [2, 'always', 100],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
42
75
|
```
|
|
43
76
|
|
|
44
|
-
|
|
77
|
+
### 3. Adding Custom Scopes
|
|
45
78
|
|
|
46
|
-
|
|
47
|
-
|
|
79
|
+
You can extend the dynamically discovered monorepo scopes with custom scopes:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
// commitlint.config.mjs
|
|
83
|
+
import { config, rules, scopesArray } from 'commitlint-config-spellbookx';
|
|
84
|
+
|
|
85
|
+
export default {
|
|
86
|
+
...config,
|
|
87
|
+
rules: {
|
|
88
|
+
...rules,
|
|
89
|
+
'scope-enum': [2, 'always', [...scopesArray, 'custom-scope', 'analytics']],
|
|
90
|
+
},
|
|
91
|
+
};
|
|
48
92
|
```
|
|
49
93
|
|
|
50
|
-
|
|
94
|
+
### 4. Fully Modular Building Blocks
|
|
95
|
+
|
|
96
|
+
Assemble your configuration from modular pieces:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// commitlint.config.mjs
|
|
100
|
+
import {
|
|
101
|
+
rules,
|
|
102
|
+
prompt,
|
|
103
|
+
scopesArray,
|
|
104
|
+
scopesEnum,
|
|
105
|
+
COMMIT_TYPES,
|
|
106
|
+
} from 'commitlint-config-spellbookx';
|
|
107
|
+
|
|
108
|
+
export default {
|
|
109
|
+
extends: ['@commitlint/config-conventional'],
|
|
110
|
+
parserPreset: 'conventional-changelog-conventionalcommits',
|
|
111
|
+
rules,
|
|
112
|
+
prompt,
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Available building blocks:
|
|
117
|
+
|
|
118
|
+
- `config`: Complete, ready-to-use commitlint configuration object.
|
|
119
|
+
- `rules`: Strict Conventional Commit rules (`type-enum`, `scope-enum`, `header-max-length`, etc.).
|
|
120
|
+
- `prompt`: Commitizen / `cz-git` interactive questionnaire configuration with emojis and multi-scope support.
|
|
121
|
+
- `scopesArray`: Array of discovered workspace package names plus `'workspace'` and `'release'`.
|
|
122
|
+
- `scopesEnum`: Record of scopes with human-readable descriptions for interactive CLI prompts.
|
|
123
|
+
- `COMMIT_TYPES`: Array of all 11 allowed commit type strings.
|
|
124
|
+
- `SCOPE_WORKSPACE`: Constant `'workspace'`.
|
|
125
|
+
- `SCOPE_RELEASE`: Constant `'release'`.
|
|
126
|
+
|
|
127
|
+
### 5. Atomic Utility Functions (`lib`)
|
|
128
|
+
|
|
129
|
+
Every helper and utility function is implemented atomically under `lib/` and can be imported either from the package root or from `commitlint-config-spellbookx/lib`:
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
import {
|
|
133
|
+
findGitRoot,
|
|
134
|
+
getScopes,
|
|
135
|
+
getScopeDescription,
|
|
136
|
+
getWorkspacesRawPath,
|
|
137
|
+
} from 'commitlint-config-spellbookx/lib';
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- `getScopes(cwd?)`: Scans the monorepo configuration files and returns all workspace package names.
|
|
141
|
+
- `findGitRoot(startDir?)`: Traverses upwards to locate the root of the current git repository.
|
|
142
|
+
- `getScopeDescription(scope)`: Generates a human-friendly description string for a given scope identifier.
|
|
143
|
+
- `getWorkspacesRawPath(configPath, parser, property?)`: Parses JSON or YAML configuration files to extract workspace glob patterns.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Configuration File Formats
|
|
148
|
+
|
|
149
|
+
According to the [Commitlint Configuration Documentation](https://commitlint.js.org/#/reference-configuration), you can define your configuration in any of the following formats:
|
|
150
|
+
|
|
151
|
+
### In `commitlint.config.mjs` (ES Modules)
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
export { default } from 'commitlint-config-spellbookx';
|
|
155
|
+
```
|
|
51
156
|
|
|
52
|
-
|
|
157
|
+
### In `commitlint.config.cjs` (CommonJS)
|
|
53
158
|
|
|
54
159
|
```javascript
|
|
160
|
+
module.exports = require('commitlint-config-spellbookx').default;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### In `commitlint.config.ts` (TypeScript)
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import type { UserConfig } from '@commitlint/types';
|
|
55
167
|
import config from 'commitlint-config-spellbookx';
|
|
56
168
|
|
|
57
|
-
|
|
169
|
+
const userConfig: UserConfig = {
|
|
170
|
+
...config,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export default userConfig;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### In `.commitlintrc.json`
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"extends": ["commitlint-config-spellbookx"]
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### In `.commitlintrc.yml`
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
extends:
|
|
188
|
+
- commitlint-config-spellbookx
|
|
58
189
|
```
|
|
59
190
|
|
|
60
|
-
|
|
191
|
+
### In `package.json`
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
{
|
|
195
|
+
"name": "my-project",
|
|
196
|
+
"commitlint": {
|
|
197
|
+
"extends": ["commitlint-config-spellbookx"]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Git Hooks Integration
|
|
205
|
+
|
|
206
|
+
To enforce commit message conventions automatically before commits are finalized, configure a git hook manager:
|
|
207
|
+
|
|
208
|
+
### Using Lefthook
|
|
209
|
+
|
|
210
|
+
Add a `commit-msg` hook in your `lefthook.yml`:
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
commit-msg:
|
|
214
|
+
commands:
|
|
215
|
+
commitlint:
|
|
216
|
+
run: pnpm exec commitlint --edit {1}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Using Husky
|
|
220
|
+
|
|
221
|
+
Add a `commit-msg` hook with Husky:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Interactive Commits with Commitizen
|
|
230
|
+
|
|
231
|
+
For a guided, interactive commit experience with `cz-git`, configure Commitizen in your `package.json`:
|
|
61
232
|
|
|
62
233
|
```json
|
|
63
234
|
{
|
|
@@ -72,10 +243,20 @@ For an interactive commit experience, you can use `commitizen` with `cz-git`. Up
|
|
|
72
243
|
}
|
|
73
244
|
```
|
|
74
245
|
|
|
246
|
+
Then run:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm run commit
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
75
254
|
## License
|
|
76
255
|
|
|
77
256
|
This project is licensed under the MIT License.
|
|
78
257
|
|
|
79
|
-
**
|
|
258
|
+
- **Author & Creator**: [Davide Di Criscito](https://github.com/dcdavidev)
|
|
259
|
+
- **GitHub Organization**: [Spellbookx](https://github.com/spellbookx)
|
|
260
|
+
- **Copyright**: © 2026 Davide Di Criscito and [Spellbookx](https://github.com/spellbookx) contributors.
|
|
80
261
|
|
|
81
|
-
For
|
|
262
|
+
For full details, see the [LICENSE](LICENSE) file.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file index.test.ts
|
|
3
|
+
* Tests verifying the main configuration export and metadata of commitlint-config-spellbookx.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import defaultExport, {
|
|
9
|
+
COMMIT_TYPES,
|
|
10
|
+
config,
|
|
11
|
+
prompt,
|
|
12
|
+
rules,
|
|
13
|
+
SCOPE_RELEASE,
|
|
14
|
+
SCOPE_WORKSPACE,
|
|
15
|
+
scopesArray,
|
|
16
|
+
scopesEnum,
|
|
17
|
+
} from '../src/index.js';
|
|
18
|
+
import { packageJson } from '../src/lib/package-json.js';
|
|
19
|
+
|
|
20
|
+
describe('commitlint-config-spellbookx entrypoint', () => {
|
|
21
|
+
test('should export valid configuration object', () => {
|
|
22
|
+
expect(defaultExport).toBe(config);
|
|
23
|
+
expect(typeof config).toBe('object');
|
|
24
|
+
expect(Array.isArray(config.extends)).toBe(true);
|
|
25
|
+
expect(config.extends).toContain('@commitlint/config-conventional');
|
|
26
|
+
expect(config.parserPreset).toBe(
|
|
27
|
+
'conventional-changelog-conventionalcommits'
|
|
28
|
+
);
|
|
29
|
+
expect(config.rules).toBe(rules);
|
|
30
|
+
expect(config.prompt).toBe(prompt);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should contain valid package metadata in helpers', () => {
|
|
34
|
+
expect(packageJson.name).toBe('commitlint-config-spellbookx');
|
|
35
|
+
expect(packageJson.version).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('should export conventional commit types and scope constants', () => {
|
|
39
|
+
expect(Array.isArray(COMMIT_TYPES)).toBe(true);
|
|
40
|
+
expect(COMMIT_TYPES).toContain('feat');
|
|
41
|
+
expect(COMMIT_TYPES).toContain('fix');
|
|
42
|
+
expect(SCOPE_WORKSPACE).toBe('workspace');
|
|
43
|
+
expect(SCOPE_RELEASE).toBe('release');
|
|
44
|
+
expect(Array.isArray(scopesArray)).toBe(true);
|
|
45
|
+
expect(typeof scopesEnum).toBe('object');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file lint.test.ts
|
|
3
|
+
* Tests verifying conventional commit validation rules using `@commitlint/lint`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import lint from '@commitlint/lint';
|
|
9
|
+
|
|
10
|
+
import config from '../src/index.js';
|
|
11
|
+
|
|
12
|
+
describe('commitlint validation rules', () => {
|
|
13
|
+
test('should validate valid conventional commits', async () => {
|
|
14
|
+
const result = await lint(
|
|
15
|
+
'feat(eslint-plugin-spellbookx): add new awesome feature',
|
|
16
|
+
config.rules
|
|
17
|
+
);
|
|
18
|
+
expect(result.valid).toBe(true);
|
|
19
|
+
expect(result.errors).toHaveLength(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('should validate valid workspace scope commits', async () => {
|
|
23
|
+
const result = await lint(
|
|
24
|
+
'chore(workspace): update root configs',
|
|
25
|
+
config.rules
|
|
26
|
+
);
|
|
27
|
+
expect(result.valid).toBe(true);
|
|
28
|
+
expect(result.errors).toHaveLength(0);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('should validate valid release scope commits', async () => {
|
|
32
|
+
const result = await lint('feat(release): publish v1.0.0', config.rules);
|
|
33
|
+
expect(result.valid).toBe(true);
|
|
34
|
+
expect(result.errors).toHaveLength(0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should fail when type is invalid', async () => {
|
|
38
|
+
const result = await lint('unknown(workspace): some change', config.rules);
|
|
39
|
+
expect(result.valid).toBe(false);
|
|
40
|
+
expect(result.errors.some((e) => e.name === 'type-enum')).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('should fail when scope is not in scope-enum', async () => {
|
|
44
|
+
const result = await lint(
|
|
45
|
+
'feat(nonexistent-scope): some change',
|
|
46
|
+
config.rules
|
|
47
|
+
);
|
|
48
|
+
expect(result.valid).toBe(false);
|
|
49
|
+
expect(result.errors.some((e) => e.name === 'scope-enum')).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('should fail when subject has a trailing period', async () => {
|
|
53
|
+
const result = await lint('fix(workspace): fix config typo.', config.rules);
|
|
54
|
+
expect(result.valid).toBe(false);
|
|
55
|
+
expect(result.errors.some((e) => e.name === 'subject-full-stop')).toBe(
|
|
56
|
+
true
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('should fail when subject is empty', async () => {
|
|
61
|
+
const result = await lint('fix(workspace): ', config.rules);
|
|
62
|
+
expect(result.valid).toBe(false);
|
|
63
|
+
expect(result.errors.some((e) => e.name === 'subject-empty')).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file scopes.test.ts
|
|
3
|
+
* Tests for scope identifiers, scope descriptions, and scopes enumeration.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getScopeDescription,
|
|
10
|
+
SCOPE_RELEASE,
|
|
11
|
+
SCOPE_WORKSPACE,
|
|
12
|
+
scopesArray,
|
|
13
|
+
scopesEnum,
|
|
14
|
+
} from '../src/index.js';
|
|
15
|
+
|
|
16
|
+
describe('commitlint scopes', () => {
|
|
17
|
+
test('constants should be properly defined', () => {
|
|
18
|
+
expect(SCOPE_WORKSPACE).toBe('workspace');
|
|
19
|
+
expect(SCOPE_RELEASE).toBe('release');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('scopesArray should contain workspace, release, and monorepo packages', () => {
|
|
23
|
+
expect(Array.isArray(scopesArray)).toBe(true);
|
|
24
|
+
expect(scopesArray).toContain(SCOPE_WORKSPACE);
|
|
25
|
+
expect(scopesArray).toContain(SCOPE_RELEASE);
|
|
26
|
+
expect(scopesArray).toContain('commitlint-config-spellbookx');
|
|
27
|
+
expect(scopesArray).toContain('cspell-config-spellbookx');
|
|
28
|
+
expect(scopesArray).toContain('eslint-plugin-spellbookx');
|
|
29
|
+
expect(scopesArray).toContain('prettier-config-spellbookx');
|
|
30
|
+
expect(scopesArray).toContain('@spellbookx/recipes');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('getScopeDescription should return user-friendly descriptions', () => {
|
|
34
|
+
expect(getScopeDescription(SCOPE_WORKSPACE)).toBe(
|
|
35
|
+
'workspace scope - root files such as config files, root package.json, etc'
|
|
36
|
+
);
|
|
37
|
+
expect(getScopeDescription(SCOPE_RELEASE)).toBe(
|
|
38
|
+
'Special scope for release commits'
|
|
39
|
+
);
|
|
40
|
+
expect(getScopeDescription('custom-pkg')).toBe('custom-pkg scope');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('scopesEnum should populate descriptions for all scopes', () => {
|
|
44
|
+
expect(scopesEnum[SCOPE_WORKSPACE]?.description).toBe(
|
|
45
|
+
getScopeDescription(SCOPE_WORKSPACE)
|
|
46
|
+
);
|
|
47
|
+
expect(scopesEnum[SCOPE_RELEASE]?.description).toBe(
|
|
48
|
+
getScopeDescription(SCOPE_RELEASE)
|
|
49
|
+
);
|
|
50
|
+
for (const scope of scopesArray) {
|
|
51
|
+
expect(scopesEnum[scope]).toBeDefined();
|
|
52
|
+
expect(scopesEnum[scope]?.description).toBe(getScopeDescription(scope));
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file workspaces.test.ts
|
|
3
|
+
* Tests for git root discovery, workspace config parsing, and scopes gathering.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
import { afterAll, beforeAll, describe, expect, test } from 'vitest';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
findGitRoot,
|
|
14
|
+
getScopes,
|
|
15
|
+
getWorkspacesRawPath,
|
|
16
|
+
} from '../src/lib/index.js';
|
|
17
|
+
|
|
18
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
const testDir = path.resolve(__dirname, '../temp-test-commitlint');
|
|
20
|
+
|
|
21
|
+
describe('workspace discovery and parsing', () => {
|
|
22
|
+
beforeAll(() => {
|
|
23
|
+
if (existsSync(testDir)) rmSync(testDir, { recursive: true, force: true });
|
|
24
|
+
mkdirSync(testDir, { recursive: true });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterAll(() => {
|
|
28
|
+
if (existsSync(testDir)) rmSync(testDir, { recursive: true, force: true });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('findGitRoot should locate git root directory', () => {
|
|
32
|
+
const root = findGitRoot(__dirname);
|
|
33
|
+
expect(root).not.toBeNull();
|
|
34
|
+
expect(existsSync(path.join(root!, '.git'))).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should parse workspaces from JSON correctly', () => {
|
|
38
|
+
const jsonPath = path.join(testDir, 'package.json');
|
|
39
|
+
mkdirSync(testDir, { recursive: true });
|
|
40
|
+
writeFileSync(
|
|
41
|
+
jsonPath,
|
|
42
|
+
JSON.stringify({ workspaces: ['packages/*', 'apps/*'] })
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const workspaces = getWorkspacesRawPath(jsonPath, 'json', 'workspaces');
|
|
46
|
+
expect(workspaces).toEqual(['packages/*', 'apps/*']);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('should parse packages from YAML correctly', () => {
|
|
50
|
+
const yamlPath = path.join(testDir, 'pnpm-workspace.yaml');
|
|
51
|
+
mkdirSync(testDir, { recursive: true });
|
|
52
|
+
writeFileSync(yamlPath, 'packages:\n - "packages/*"\n - "plugins/*"\n');
|
|
53
|
+
|
|
54
|
+
const packages = getWorkspacesRawPath(yamlPath, 'yaml', 'packages');
|
|
55
|
+
expect(packages).toEqual(['packages/*', 'plugins/*']);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should throw on unsupported parser', () => {
|
|
59
|
+
const filePath = path.join(testDir, 'config.txt');
|
|
60
|
+
writeFileSync(filePath, 'some text');
|
|
61
|
+
expect(() => {
|
|
62
|
+
// @ts-expect-error Testing invalid parser
|
|
63
|
+
getWorkspacesRawPath(filePath, 'xml');
|
|
64
|
+
}).toThrow(/Unsupported parser type/);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should return scopes including workspace and monorepo packages', () => {
|
|
68
|
+
const scopes = getScopes();
|
|
69
|
+
expect(Array.isArray(scopes)).toBe(true);
|
|
70
|
+
expect(scopes).toContain('commitlint-config-spellbookx');
|
|
71
|
+
expect(scopes).toContain('cspell-config-spellbookx');
|
|
72
|
+
expect(scopes).toContain('eslint-plugin-spellbookx');
|
|
73
|
+
expect(scopes).toContain('prettier-config-spellbookx');
|
|
74
|
+
expect(scopes).toContain('@spellbookx/recipes');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file commit-types.ts
|
|
3
|
+
* Standard Conventional Commit types supported by Spellbookx.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* List of allowed commit types based on the Conventional Commits specification.
|
|
7
|
+
*/
|
|
8
|
+
export declare const COMMIT_TYPES: readonly ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "ci", "build", "revert"];
|
|
9
|
+
/**
|
|
10
|
+
* Valid Conventional Commit type string.
|
|
11
|
+
*/
|
|
12
|
+
export type CommitType = (typeof COMMIT_TYPES)[number];
|
|
13
|
+
//# sourceMappingURL=commit-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-types.d.ts","sourceRoot":"","sources":["../../src/constants/commit-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,YAAY,yGAYf,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/constants/commit-types.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file commit-types.ts
|
|
4
|
+
* Standard Conventional Commit types supported by Spellbookx.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* List of allowed commit types based on the Conventional Commits specification.
|
|
8
|
+
*/
|
|
9
|
+
const COMMIT_TYPES = [
|
|
10
|
+
"feat",
|
|
11
|
+
"fix",
|
|
12
|
+
"docs",
|
|
13
|
+
"style",
|
|
14
|
+
"refactor",
|
|
15
|
+
"perf",
|
|
16
|
+
"test",
|
|
17
|
+
"chore",
|
|
18
|
+
"ci",
|
|
19
|
+
"build",
|
|
20
|
+
"revert"
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { COMMIT_TYPES };
|