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.
Files changed (60) hide show
  1. package/.turbo/turbo-build.log +19 -7
  2. package/.turbo/turbo-test.log +59 -0
  3. package/README.md +211 -30
  4. package/__tests__/index.test.ts +47 -0
  5. package/__tests__/lint.test.ts +65 -0
  6. package/__tests__/scopes.test.ts +55 -0
  7. package/__tests__/workspaces.test.ts +76 -0
  8. package/dist/constants/commit-types.d.ts +13 -0
  9. package/dist/constants/commit-types.d.ts.map +1 -0
  10. package/dist/constants/commit-types.js +24 -0
  11. package/dist/get-scopes-D9bIfVqN.js +5698 -0
  12. package/dist/get-workspaces-raw-path-Cg196xaD.js +2043 -0
  13. package/dist/helpers.d.ts +8 -17
  14. package/dist/helpers.d.ts.map +1 -1
  15. package/dist/helpers.js +21 -0
  16. package/dist/index.d.ts +14 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +15 -7878
  19. package/dist/lib/find-git-root.d.ts +16 -0
  20. package/dist/lib/find-git-root.d.ts.map +1 -0
  21. package/dist/lib/find-git-root.js +30 -0
  22. package/dist/lib/get-scope-description.d.ts +21 -0
  23. package/dist/lib/get-scope-description.d.ts.map +1 -0
  24. package/dist/lib/get-scope-description.js +35 -0
  25. package/dist/lib/get-scopes.d.ts +16 -0
  26. package/dist/lib/get-scopes.d.ts.map +1 -0
  27. package/dist/lib/get-scopes.js +4 -0
  28. package/dist/lib/get-workspaces-raw-path.d.ts +19 -0
  29. package/dist/lib/get-workspaces-raw-path.d.ts.map +1 -0
  30. package/dist/lib/get-workspaces-raw-path.js +3 -0
  31. package/dist/lib/index.d.ts +10 -0
  32. package/dist/lib/index.d.ts.map +1 -0
  33. package/dist/lib/index.js +7 -0
  34. package/dist/lib/package-json.d.ts +14 -0
  35. package/dist/lib/package-json.d.ts.map +1 -0
  36. package/dist/lib/package-json.js +16 -0
  37. package/dist/prompt.d.ts +10 -0
  38. package/dist/prompt.d.ts.map +1 -0
  39. package/dist/prompt.js +99 -0
  40. package/dist/rules.d.ts +10 -0
  41. package/dist/rules.d.ts.map +1 -0
  42. package/dist/rules.js +45 -0
  43. package/dist/scopes.d.ts +23 -0
  44. package/dist/scopes.d.ts.map +1 -0
  45. package/dist/scopes.js +38 -0
  46. package/package.json +43 -9
  47. package/rolldown.config.ts +13 -1
  48. package/src/constants/commit-types.ts +26 -0
  49. package/src/index.ts +26 -153
  50. package/src/lib/find-git-root.ts +31 -0
  51. package/src/lib/get-scope-description.ts +38 -0
  52. package/src/lib/get-scopes.ts +89 -0
  53. package/src/lib/get-workspaces-raw-path.ts +53 -0
  54. package/src/lib/index.ts +10 -0
  55. package/src/lib/package-json.ts +22 -0
  56. package/src/prompt.ts +99 -0
  57. package/src/rules.ts +22 -0
  58. package/src/scopes.ts +40 -0
  59. package/tsconfig.json +1 -0
  60. package/src/helpers.ts +0 -123
@@ -1,7 +1,19 @@
1
-
2
- > commitlint-config-spellbookx@0.11.0 build /home/runner/work/spellbookx/spellbookx/packages/commitlint-config-spellbookx
3
- > rolldown -c && tsc
4
-
5
- [log] <DIR>/index.js chunk │ size: 272.64 kB
6
- [log]
7
- [success] rolldown v1.0.0-rc.5 Finished in 51.92 ms
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
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
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 ✓ __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 ✓ __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 ✓ __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
- Shared [Commitlint](https://commitlint.js.org/) configuration for the Spellbookx project. This package ensures that all commits adhere to the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
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
- ## Description
5
+ ---
6
6
 
7
- This package provides a base commitlint configuration that:
7
+ ## Features
8
8
 
9
- - Extends the widely-used `@commitlint/config-conventional`.
10
- - Dynamically generates commit scopes based on the packages present in the `@spellbookx` monorepo.
11
- - Includes pre-defined commit types with emojis for better readability.
12
- - Offers a customized `commitizen` prompt for an enhanced commit experience.
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
- ## Why use this?
17
+ ---
15
18
 
16
- Using this package ensures consistent and readable commit messages across the entire project. This helps in:
19
+ ## Supported Commit Types
17
20
 
18
- - Automatically generating changelogs.
19
- - Simplifying the release process.
20
- - Improving the readability of the project's history.
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
- ## Installation
35
+ ---
23
36
 
24
- Install the package using your favorite package manager:
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
- **pnpm**
45
+ ---
33
46
 
34
- ```bash
35
- pnpm add -D commitlint-config-spellbookx @commitlint/cli
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
- **yarn**
60
+ ### 2. Customizing Rules
39
61
 
40
- ```bash
41
- yarn add -D commitlint-config-spellbookx @commitlint/cli
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
- **bun**
77
+ ### 3. Adding Custom Scopes
45
78
 
46
- ```bash
47
- bun add -d commitlint-config-spellbookx @commitlint/cli
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
- ## Usage
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
- To use this configuration, create a `commitlint.config.mjs` file in your project's root and extend this package:
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
- export default config;
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
- For an interactive commit experience, you can use `commitizen` with `cz-git`. Update your `package.json` with the following configuration:
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
- **Copyright (c) 2026 Davide Di Criscito**
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 the full details, see the [LICENSE](LICENSE) file.
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 };