@elsikora/git-branch-lint 1.2.1 → 1.2.2-dev.1

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 (39) hide show
  1. package/LICENSE.md +3 -15
  2. package/README.md +131 -241
  3. package/bin/application/type/branch-placeholder-definition.type.d.ts +7 -0
  4. package/bin/application/type/build-branch-name-parameters.type.d.ts +4 -0
  5. package/bin/application/type/get-branch-placeholder-definitions-parameters.type.d.ts +4 -0
  6. package/bin/application/type/validate-branch-placeholder-value-parameters.type.d.ts +6 -0
  7. package/bin/application/use-cases/build-branch-name.use-case.d.ts +10 -0
  8. package/bin/application/use-cases/get-branch-pattern.use-case.d.ts +8 -0
  9. package/bin/application/use-cases/get-branch-placeholder-definitions.use-case.d.ts +11 -0
  10. package/bin/application/use-cases/get-current-branch.use-case.d.ts +1 -5
  11. package/bin/application/use-cases/lint-branch-name.use-case.d.ts +3 -9
  12. package/bin/application/use-cases/normalize-ticket-id.use-case.d.ts +9 -0
  13. package/bin/application/use-cases/validate-branch-placeholder-value.use-case.d.ts +8 -0
  14. package/bin/domain/config/default-branch-lint-config.d.ts +2 -0
  15. package/bin/domain/constant/branch-pattern.constant.d.ts +1 -0
  16. package/bin/domain/constant/ticket-id.constant.d.ts +3 -0
  17. package/bin/domain/errors/lint.error.d.ts +6 -0
  18. package/bin/domain/policy/branch-template.policy.d.ts +18 -0
  19. package/bin/domain/policy/ticket-id.policy.d.ts +9 -0
  20. package/bin/domain/type/branch-subject-pattern.type.d.ts +1 -0
  21. package/bin/domain/type/input-validation-result.type.d.ts +4 -0
  22. package/bin/domain/type/rules.type.d.ts +2 -1
  23. package/bin/index.js +340 -166
  24. package/bin/index.js.map +1 -1
  25. package/bin/infrastructure/config/cosmiconfig.repository.d.ts +0 -4
  26. package/bin/presentation/cli/controllers/create-branch.controller.d.ts +11 -1
  27. package/bin/presentation/cli/controllers/lint.controller.d.ts +1 -0
  28. package/bin/presentation/cli/formatters/branch-choice.formatter.d.ts +1 -6
  29. package/bin/presentation/cli/prompts/branch-creation.prompt.d.ts +8 -11
  30. package/bin/presentation/cli/type/branch-choice-formatted.type.d.ts +5 -0
  31. package/bin/presentation/cli/type/branch-placeholder-prompt-options.type.d.ts +6 -0
  32. package/bin/presentation/cli/type/branch-type-answer.type.d.ts +3 -0
  33. package/bin/presentation/cli/type/placeholder-answer.type.d.ts +3 -0
  34. package/bin/presentation/cli/type/push-branch-answer.type.d.ts +3 -0
  35. package/package.json +28 -28
  36. package/bin/application/use-cases/check-working-directory-use-case.d.ts +0 -13
  37. package/bin/application/use-cases/create-branch-use-case.d.ts +0 -14
  38. package/bin/application/use-cases/validate-branch-name-use-case.d.ts +0 -15
  39. package/bin/application/use-cases/validate-branch-name.use-case.d.ts +0 -15
package/LICENSE.md CHANGED
@@ -2,20 +2,8 @@ The MIT License (MIT)
2
2
 
3
3
  Copyright (c) 2022 Bogdan Kolesnyk (bogdan.kolesnyk@gmail.com)
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
11
6
 
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14
8
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,83 +1,66 @@
1
1
  <p align="center">
2
- <img src="https://6jft62zmy9nx2oea.public.blob.vercel-storage.com/git-branch-lint-myXi2xH8jqeEIqScu1S9NymOOJVD9I.png" width="500" alt="project-logo">
2
+ <img src="https://6jft62zmy9nx2oea.public.blob.vercel-storage.com/git-branch-lint-myXi2xH8jqeEIqScu1S9NymOOJVD9I.png" width="500" alt="project-logo" />
3
3
  </p>
4
4
 
5
- <h1 align="center">🌿 Git-Branch-Lint</h1>
6
- <p align="center"><em>Enforce consistent Git branch naming conventions with style and ease</em></p>
5
+ <h1 align="center">Git-Branch-Lint</h1>
6
+ <p align="center"><em>CLI tool for consistent, enforceable Git branch naming.</em></p>
7
7
 
8
- <p align="center">
9
- <a aria-label="ElsiKora logo" href="https://elsikora.com">
10
- <img src="https://img.shields.io/badge/MADE%20BY%20ElsiKora-333333.svg?style=for-the-badge" alt="ElsiKora">
11
- </a> <img src="https://img.shields.io/badge/TypeScript-3178C6.svg?style=for-the-badge&logo=typescript&logoColor=white" alt="TypeScript"> <img src="https://img.shields.io/badge/Node.js-339933.svg?style=for-the-badge&logo=node.js&logoColor=white" alt="Node.js"> <img src="https://img.shields.io/badge/npm-CB3837.svg?style=for-the-badge&logo=npm&logoColor=white" alt="npm"> <img src="https://img.shields.io/badge/ESLint-4B32C3.svg?style=for-the-badge&logo=eslint&logoColor=white" alt="ESLint"> <img src="https://img.shields.io/badge/Prettier-F7B93E.svg?style=for-the-badge&logo=prettier&logoColor=black" alt="Prettier"> <img src="https://img.shields.io/badge/Vitest-6E9F18.svg?style=for-the-badge&logo=vitest&logoColor=white" alt="Vitest"> <img src="https://img.shields.io/badge/Rollup-EC4A3F.svg?style=for-the-badge&logo=rollup&logoColor=white" alt="Rollup"> <img src="https://img.shields.io/badge/Git-F05032.svg?style=for-the-badge&logo=git&logoColor=white" alt="Git"> <img src="https://img.shields.io/badge/GitHub%20Actions-2088FF.svg?style=for-the-badge&logo=github-actions&logoColor=white" alt="GitHub Actions">
12
- </p>
8
+ ## Table Of Contents
13
9
 
10
+ - [Description](#description)
11
+ - [Features](#features)
12
+ - [Installation](#installation)
13
+ - [Usage](#usage)
14
+ - [Configuration](#configuration)
15
+ - [Clean Architecture Rules](#clean-architecture-rules)
16
+ - [Development](#development)
17
+ - [License](#license)
14
18
 
15
- ## 📚 Table of Contents
16
- - [Description](#-description)
17
- - [Features](#-features)
18
- - [Installation](#-installation)
19
- - [Usage](#-usage)
20
- - [Roadmap](#-roadmap)
21
- - [FAQ](#-faq)
22
- - [License](#-license)
19
+ ## Description
23
20
 
21
+ `@elsikora/git-branch-lint` validates branch names against team rules and includes an interactive branch-creation flow.
24
22
 
25
- ## 📖 Description
26
- Git-Branch-Lint is a powerful, TypeScript-based CLI tool that brings order to your Git workflow by enforcing consistent branch naming conventions across your entire development team. Built with clean architecture principles, it not only validates branch names but also provides an interactive branch creation wizard that guides developers through creating properly formatted branches. Whether you're managing a small project or a large enterprise codebase, Git-Branch-Lint helps maintain a clean, organized repository structure that makes tracking features, fixes, and releases effortless. It seamlessly integrates with Git hooks, CI/CD pipelines, and supports multiple configuration formats, making it the perfect addition to any modern development workflow.
23
+ The project follows layered clean architecture:
27
24
 
28
- ## 🚀 Features
29
- - **🎯 **Smart Pattern Matching** - Define flexible branch naming patterns using simple placeholders like `:type/:name` that automatically validate against your configured branch types**
30
- - **🚀 **Interactive Branch Creation** - Built-in wizard guides you through creating branches with beautiful prompts, ensuring compliance before the branch is even created**
31
- - **🛡️ **Prohibited Branch Protection** - Prevent accidental use of protected branch names like 'main', 'master', or any custom prohibited names you define**
32
- - ✨ **📏 **Length Validation** - Set minimum and maximum length constraints to keep branch names concise and meaningful**
33
- - ✨ **🎨 **Beautiful CLI Output** - Colored terminal output with helpful error messages and hints that guide developers to fix issues quickly**
34
- - ✨ **⚙️ **Flexible Configuration** - Support for multiple config formats (JS, TS, JSON, YAML) with intelligent config discovery via cosmiconfig**
35
- - ✨ **🔄 **Git Hooks Ready** - Seamlessly integrate with Husky, lint-staged, or any Git hook manager for automatic validation**
36
- - ✨ **📦 **Zero Config Option** - Works out of the box with sensible defaults while allowing complete customization when needed**
37
- - ✨ **🏗️ **Clean Architecture** - Built with Domain-Driven Design principles, making the codebase maintainable and extensible**
25
+ - `domain` - business rules, entities, policies, contracts
26
+ - `application` - use cases and orchestration logic
27
+ - `infrastructure` - adapters (git, config loading)
28
+ - `presentation` - CLI controllers, prompts, formatters
38
29
 
39
- ## 🛠 Installation
40
- ```bash
41
- ## 📦 Installation
30
+ ## Features
31
+
32
+ - Template-driven branch validation using placeholders (for example `:type/:name` or `:scope/:type/:description`).
33
+ - Optional ticket-id support with pattern `:type/:ticket-:name` (ticket part can be omitted).
34
+ - Interactive branch creation command (`-b` / `--branch`) built directly from configured placeholders.
35
+ - Branch constraints: prohibited names, min/max length, subject regex.
36
+ - Helpful CLI error/hint formatting.
37
+ - Cosmiconfig-based configuration discovery.
42
38
 
43
- Install Git-Branch-Lint as a development dependency in your project:
39
+ ## Installation
44
40
 
41
+ Install as a dev dependency:
45
42
 
46
- # Using npm
43
+ ```bash
47
44
  npm install --save-dev @elsikora/git-branch-lint
45
+ ```
48
46
 
49
- # Using yarn
50
- yarn add -D @elsikora/git-branch-lint
47
+ Or with other package managers:
51
48
 
52
- # Using pnpm
49
+ ```bash
50
+ yarn add -D @elsikora/git-branch-lint
53
51
  pnpm add -D @elsikora/git-branch-lint
54
-
55
- # Using bun
56
52
  bun add -d @elsikora/git-branch-lint
57
-
58
-
59
- ### Global Installation
60
-
61
- For system-wide usage across multiple projects:
62
-
63
-
64
- npm install -g @elsikora/git-branch-lint
65
53
  ```
66
54
 
67
- ## 💡 Usage
68
- ## 🚀 Usage
55
+ ## Usage
69
56
 
70
- ### Basic Branch Validation
71
-
72
- Validate your current Git branch name:
57
+ Validate current branch:
73
58
 
74
59
  ```bash
75
60
  npx @elsikora/git-branch-lint
76
61
  ```
77
62
 
78
- ### Interactive Branch Creation
79
-
80
- Create a new branch with the interactive wizard:
63
+ Start interactive branch creation:
81
64
 
82
65
  ```bash
83
66
  npx @elsikora/git-branch-lint -b
@@ -85,223 +68,130 @@ npx @elsikora/git-branch-lint -b
85
68
  npx @elsikora/git-branch-lint --branch
86
69
  ```
87
70
 
88
- ### Configuration
89
-
90
- Git-Branch-Lint uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for configuration file discovery. Create any of these files:
91
-
92
- #### JavaScript Configuration (`.elsikora/git-branch-lint.config.js`)
93
-
94
- ```javascript
95
- export default {
96
- branches: {
97
- feature: {
98
- title: "Feature",
99
- description: "🆕 New functionality"
100
- },
101
- bugfix: {
102
- title: "Bugfix",
103
- description: "🐛 Bug fixes"
104
- },
105
- hotfix: {
106
- title: "Hotfix",
107
- description: "🚑 Urgent production fixes"
108
- },
109
- release: {
110
- title: "Release",
111
- description: "📦 Release preparation"
112
- },
113
- chore: {
114
- title: "Chore",
115
- description: "🔧 Maintenance tasks"
116
- }
117
- },
118
- ignore: ["dev", "develop", "staging"],
119
- rules: {
120
- "branch-pattern": ":type/:name",
121
- "branch-subject-pattern": "[a-z0-9-]+",
122
- "branch-prohibited": ["main", "master", "prod"],
123
- "branch-min-length": 5,
124
- "branch-max-length": 60
125
- }
126
- };
127
- ```
128
-
129
- #### TypeScript Configuration (`.elsikora/git-branch-lint.config.ts`)
130
-
131
- ```typescript
132
- import type { IBranchLintConfig } from '@elsikora/git-branch-lint';
133
-
134
- const config: IBranchLintConfig = {
135
- branches: {
136
- feat: { title: "Feature", description: "✨ New features" },
137
- fix: { title: "Fix", description: "🐛 Bug fixes" },
138
- docs: { title: "Docs", description: "📚 Documentation" },
139
- style: { title: "Style", description: "💄 Styling" },
140
- refactor: { title: "Refactor", description: "♻️ Code refactoring" },
141
- perf: { title: "Performance", description: "⚡ Performance improvements" },
142
- test: { title: "Test", description: "✅ Testing" },
143
- build: { title: "Build", description: "📦 Build system" },
144
- ci: { title: "CI", description: "👷 CI/CD" }
145
- },
146
- rules: {
147
- "branch-pattern": ":type/:name",
148
- "branch-subject-pattern": "[a-z0-9-]+",
149
- "branch-min-length": 8,
150
- "branch-max-length": 72
151
- }
152
- };
153
-
154
- export default config;
155
- ```
156
-
157
- #### Package.json Configuration
71
+ Behavior notes:
158
72
 
159
- ```json
160
- {
161
- "elsikora": {
162
- "git-branch-lint": {
163
- "branches": ["feature", "bugfix", "hotfix"],
164
- "rules": {
165
- "branch-pattern": ":type/:name",
166
- "branch-prohibited": ["main", "master"]
167
- }
168
- }
169
- }
170
- }
171
- ```
73
+ - When `:ticket` is present in `branch-pattern`, both forms are valid:
74
+ - with ticket: `feature/proj-123-user-authentication`
75
+ - without ticket: `feature/user-authentication`
76
+ - Interactive prompt normalizes ticket-id to lowercase before branch creation.
77
+ - Placeholder prompts are generated from `branch-pattern` in declared order.
78
+ - Validation and branch creation use the same template/pattern rules.
172
79
 
173
- ### Git Hooks Integration
80
+ ## Configuration
174
81
 
175
- #### With Husky
82
+ Configuration is loaded via `cosmiconfig` (for example `package.json`, `.elsikora/git-branch-lint.config.js`, `.elsikora/git-branch-lint.config.ts`).
176
83
 
177
- ```bash
178
- # Install Husky
179
- npm install --save-dev husky
180
-
181
- # Initialize Husky
182
- npx husky init
84
+ Rule semantics:
183
85
 
184
- # Add pre-push hook
185
- echo "npx @elsikora/git-branch-lint" > .husky/pre-push
186
- ```
86
+ - `branch-pattern` defines placeholders with `:placeholder` tokens.
87
+ - Placeholder naming supports lowercase letters, digits, and hyphens (for example `:jira-ticket`).
88
+ - `:type` is validated against configured `branches`.
89
+ - `branch-subject-pattern` supports:
90
+ - `string` - shared regex for all non-`type` placeholders.
91
+ - `object` - regex per placeholder key (for example `scope`, `description`, `ticket`).
92
+ - Optional placeholders are supported when the token is followed by `-` in `branch-pattern` (for example `:ticket-`).
93
+ - Before branch creation, the final assembled name is validated again with full lint rules.
187
94
 
188
- #### With lint-staged
95
+ ### JavaScript Example
189
96
 
190
97
  ```javascript
191
- // lint-staged.config.js
192
98
  export default {
193
- '*': () => 'npx @elsikora/git-branch-lint'
99
+ branches: {
100
+ feature: { title: "Feature", description: "New functionality" },
101
+ bugfix: { title: "Bugfix", description: "Bug fixes" },
102
+ hotfix: { title: "Hotfix", description: "Urgent fixes" },
103
+ },
104
+ ignore: ["dev"],
105
+ rules: {
106
+ "branch-pattern": ":type/:ticket-:name",
107
+ "branch-subject-pattern": "[a-z0-9-]+",
108
+ "branch-prohibited": ["main", "master", "release"],
109
+ "branch-min-length": 5,
110
+ "branch-max-length": 50,
111
+ },
194
112
  };
195
113
  ```
196
114
 
197
- ### CI/CD Integration
198
-
199
- #### GitHub Actions
115
+ ### Advanced Placeholder Example
200
116
 
201
- ```yaml
202
- name: Branch Lint
203
- on: [push, pull_request]
204
-
205
- jobs:
206
- lint-branch:
207
- runs-on: ubuntu-latest
208
- steps:
209
- - uses: actions/checkout@v4
210
- - uses: actions/setup-node@v4
211
- with:
212
- node-version: '20'
213
- - run: npm ci
214
- - run: npx @elsikora/git-branch-lint
117
+ ```javascript
118
+ export default {
119
+ branches: ["feat", "fix", "chore"],
120
+ rules: {
121
+ "branch-pattern": ":scope/:type/:description",
122
+ "branch-subject-pattern": {
123
+ scope: "(web|api|shared)",
124
+ description: "[a-z0-9-]+",
125
+ },
126
+ },
127
+ };
215
128
  ```
216
129
 
217
- #### GitLab CI
130
+ Valid branch example: `web/feat/shopping-cart`.
218
131
 
219
- ```yaml
220
- branch-lint:
221
- stage: test
222
- script:
223
- - npm ci
224
- - npx @elsikora/git-branch-lint
225
- only:
226
- - branches
227
- ```
132
+ ### TypeScript Example
228
133
 
229
- ### Advanced Patterns
134
+ ```typescript
135
+ import type { IBranchLintConfig } from "@elsikora/git-branch-lint";
230
136
 
231
- #### Jira Integration Pattern
137
+ const config: IBranchLintConfig = {
138
+ branches: {
139
+ feature: { title: "Feature", description: "New functionality" },
140
+ bugfix: { title: "Bugfix", description: "Bug fixes" },
141
+ hotfix: { title: "Hotfix", description: "Urgent fixes" },
142
+ },
143
+ ignore: ["dev"],
144
+ rules: {
145
+ "branch-pattern": ":type/:ticket-:name",
146
+ "branch-subject-pattern": "[a-z0-9-]+",
147
+ "branch-prohibited": ["main", "master", "release"],
148
+ "branch-min-length": 5,
149
+ "branch-max-length": 50,
150
+ },
151
+ };
232
152
 
233
- ```javascript
234
- {
235
- rules: {
236
- "branch-pattern": ":type/:ticket-:description",
237
- "branch-subject-pattern": {
238
- "ticket": "[a-z]{2,}-[0-9]+",
239
- "description": "[a-z0-9-]+"
240
- }
241
- }
242
- }
243
- // Valid: feature/proj-123-user-authentication
153
+ export default config;
244
154
  ```
245
155
 
246
- #### Monorepo Pattern
156
+ ### `package.json` Example
247
157
 
248
- ```javascript
158
+ ```json
249
159
  {
250
- rules: {
251
- "branch-pattern": ":scope/:type/:name",
252
- "branch-subject-pattern": {
253
- "scope": "(web|api|shared|docs)",
254
- "type": "(feat|fix|chore)",
255
- "name": "[a-z0-9-]+"
256
- }
257
- }
160
+ "elsikora": {
161
+ "git-branch-lint": {
162
+ "branches": ["feature", "bugfix", "hotfix"],
163
+ "rules": {
164
+ "branch-pattern": ":type/:ticket-:name",
165
+ "branch-subject-pattern": "[a-z0-9-]+",
166
+ "branch-prohibited": ["main", "master", "release"]
167
+ }
168
+ }
169
+ }
258
170
  }
259
- // Valid: web/feat/shopping-cart
260
171
  ```
261
172
 
262
- ## 🛣 Roadmap
263
- | Task / Feature | Status |
264
- |----------------|--------|
265
- | Core branch validation engine | ✅ Done |
266
- | Interactive branch creation wizard | ✅ Done |
267
- | Multiple configuration format support | ✅ Done |
268
- | TypeScript support | ✅ Done |
269
- | Comprehensive test coverage | ✅ Done |
270
- | VS Code extension | 🚧 In Progress |
271
- | Branch name auto-suggestions | 🚧 In Progress |
272
- | Custom validation rules plugin system | 🚧 In Progress |
273
- | Branch naming statistics dashboard | 🚧 In Progress |
274
- | Integration with popular Git GUIs | 🚧 In Progress |
275
- | AI-powered branch name generator | 🚧 In Progress |
276
-
277
- ## ❓ FAQ
278
- ## ❓ Frequently Asked Questions
279
-
280
- ### **Q: Can I use this with existing branches?**
281
- A: Yes! The `ignore` configuration option allows you to exclude existing branches from validation. This is perfect for grandfathering in old branches while enforcing rules on new ones.
282
-
283
- ### **Q: How do I handle different patterns for different teams?**
284
- A: You can create team-specific configuration files and use environment variables or Git config to load the appropriate one:
285
- ```bash
286
- GIT_BRANCH_LINT_CONFIG=.team-frontend.config.js npx @elsikora/git-branch-lint
287
- ```
173
+ ## Clean Architecture Rules
288
174
 
289
- ### **Q: Can I validate branch names in my IDE?**
290
- A: While we're working on official IDE extensions, you can configure your IDE to run the validation as an external tool or use it with pre-commit hooks.
175
+ Repository standards enforced in this codebase:
291
176
 
292
- ### **Q: What happens if I try to push an invalid branch?**
293
- A: When integrated with Git hooks, the push will be prevented and you'll see a helpful error message explaining what's wrong and how to fix it.
177
+ - Business rules live in `domain` and are consumed via `application` use cases.
178
+ - `presentation` does I/O only; it must not own business validation rules.
179
+ - `infrastructure` contains adapters only; default domain rules are defined outside adapter implementation.
180
+ - `application` depends on domain contracts, not concrete infrastructure classes.
181
+ - Types/interfaces are extracted into dedicated type/interface files for reusable contracts.
182
+ - Import order and class member ordering are lint-enforced and must remain consistent.
294
183
 
295
- ### **Q: Can I use custom regex patterns?**
296
- A: Absolutely! The `branch-subject-pattern` rule accepts any valid JavaScript regex pattern, giving you complete control over validation.
184
+ ## Development
297
185
 
298
- ### **Q: Is this compatible with Git Flow or GitHub Flow?**
299
- A: Yes! The default configuration works well with both workflows, and you can easily customize it to match your specific flow requirements.
186
+ Common scripts:
300
187
 
301
- ### **Q: How do I migrate from other branch linting tools?**
302
- A: Git-Branch-Lint's configuration is designed to be intuitive. Most configurations from other tools can be adapted by mapping their patterns to our rule system.
188
+ ```bash
189
+ npm run lint
190
+ npm run lint:types
191
+ npm run test:unit
192
+ npm run test:e2e
193
+ ```
303
194
 
304
- ## 🔒 License
305
- This project is licensed under **MIT License - see the [LICENSE](LICENSE) file for details.
195
+ ## License
306
196
 
307
- Maintained with ❤️ by [ElsiKora](https://github.com/ElsiKora)**.
197
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,7 @@
1
+ export interface IBranchPlaceholderDefinition {
2
+ example?: string;
3
+ isOptional: boolean;
4
+ isTypePlaceholder: boolean;
5
+ patternSource?: string;
6
+ placeholderName: string;
7
+ }
@@ -0,0 +1,4 @@
1
+ export interface IBuildBranchNameParameters {
2
+ branchPattern: string;
3
+ placeholderValues: Record<string, string>;
4
+ }
@@ -0,0 +1,4 @@
1
+ import type { IBranchLintConfig } from "../../domain/type/config.type";
2
+ export interface IGetBranchPlaceholderDefinitionsParameters {
3
+ config: IBranchLintConfig;
4
+ }
@@ -0,0 +1,6 @@
1
+ export interface IValidateBranchPlaceholderValueParameters {
2
+ isOptional: boolean;
3
+ patternSource: string;
4
+ placeholderName: string;
5
+ value: string;
6
+ }
@@ -0,0 +1,10 @@
1
+ import type { IBuildBranchNameParameters } from "../type/build-branch-name-parameters.type";
2
+ import { BranchTemplatePolicy } from "../../domain/policy/branch-template.policy";
3
+ /**
4
+ * Use case for assembling a branch name from validated user inputs.
5
+ */
6
+ export declare class BuildBranchNameUseCase {
7
+ private readonly branchTemplatePolicy;
8
+ constructor(branchTemplatePolicy?: BranchTemplatePolicy);
9
+ execute(parameters: IBuildBranchNameParameters): string;
10
+ }
@@ -0,0 +1,8 @@
1
+ import type { IBranchLintConfig } from "../../domain/type/config.type";
2
+ /**
3
+ * Use case for retrieving effective branch pattern.
4
+ */
5
+ export declare class GetBranchPatternUseCase {
6
+ private readonly DEFAULT_BRANCH_PATTERN;
7
+ execute(config: IBranchLintConfig): string;
8
+ }
@@ -0,0 +1,11 @@
1
+ import type { IBranchPlaceholderDefinition } from "../type/branch-placeholder-definition.type";
2
+ import type { IGetBranchPlaceholderDefinitionsParameters } from "../type/get-branch-placeholder-definitions-parameters.type";
3
+ import { BranchTemplatePolicy } from "../../domain/policy/branch-template.policy";
4
+ /**
5
+ * Use case for resolving placeholder definitions from branch pattern config.
6
+ */
7
+ export declare class GetBranchPlaceholderDefinitionsUseCase {
8
+ private readonly branchTemplatePolicy;
9
+ constructor(branchTemplatePolicy?: BranchTemplatePolicy);
10
+ execute(parameters: IGetBranchPlaceholderDefinitionsParameters): Array<IBranchPlaceholderDefinition>;
11
+ }
@@ -3,11 +3,7 @@ import type { IBranchRepository } from "../../domain/interface/branch.repository
3
3
  * Use case for getting the current branch name
4
4
  */
5
5
  export declare class GetCurrentBranchUseCase {
6
- private readonly BRANCH_REPOSITORY;
7
- /**
8
- * Constructor
9
- * @param branchRepository The branch repository
10
- */
6
+ private readonly branchRepository;
11
7
  constructor(branchRepository: IBranchRepository);
12
8
  /**
13
9
  * Execute the use case
@@ -1,8 +1,11 @@
1
1
  import type { IBranchLintConfig } from "../../domain/type/config.type";
2
+ import { BranchTemplatePolicy } from "../../domain/policy/branch-template.policy";
2
3
  /**
3
4
  * Use case for linting branch names
4
5
  */
5
6
  export declare class LintBranchNameUseCase {
7
+ private readonly BRANCH_TEMPLATE_POLICY;
8
+ constructor(branchTemplatePolicy?: BranchTemplatePolicy);
6
9
  /**
7
10
  * Execute the use case
8
11
  * @param branchName The branch name to lint
@@ -13,15 +16,6 @@ export declare class LintBranchNameUseCase {
13
16
  * @throws {BranchTooLongError} When branch name is longer than the maximum length
14
17
  */
15
18
  execute(branchName: string, config: IBranchLintConfig): void;
16
- /**
17
- * Test a branch name against a specific pattern
18
- * @param branchName The branch name to test
19
- * @param pattern The pattern to test against
20
- * @param branchTypes Available branch types
21
- * @param subjectNamePattern Pattern for the name/description part
22
- * @returns true if pattern matches
23
- */
24
- private testPattern;
25
19
  /**
26
20
  * Validate the branch name against the pattern
27
21
  * @param branchName The branch name to validate
@@ -0,0 +1,9 @@
1
+ import { TicketIdPolicy } from "../../domain/policy/ticket-id.policy";
2
+ /**
3
+ * Use case for normalizing optional ticket identifier input.
4
+ */
5
+ export declare class NormalizeTicketIdUseCase {
6
+ private readonly ticketIdPolicy;
7
+ constructor(ticketIdPolicy?: TicketIdPolicy);
8
+ execute(ticketId: string): string;
9
+ }
@@ -0,0 +1,8 @@
1
+ import type { IInputValidationResult } from "../../domain/type/input-validation-result.type";
2
+ import type { IValidateBranchPlaceholderValueParameters } from "../type/validate-branch-placeholder-value-parameters.type";
3
+ /**
4
+ * Use case for validating interactive placeholder values.
5
+ */
6
+ export declare class ValidateBranchPlaceholderValueUseCase {
7
+ execute(parameters: IValidateBranchPlaceholderValueParameters): IInputValidationResult;
8
+ }
@@ -0,0 +1,2 @@
1
+ import type { IBranchLintConfig } from "../type/config.type";
2
+ export declare const DEFAULT_BRANCH_LINT_CONFIG: IBranchLintConfig;
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_BRANCH_SUBJECT_PATTERN_SOURCE: string;
@@ -0,0 +1,3 @@
1
+ export declare const TICKET_ID_ERROR_MESSAGE: string;
2
+ export declare const TICKET_ID_EXAMPLE: string;
3
+ export declare const TICKET_ID_PATTERN_SOURCE: string;
@@ -16,6 +16,12 @@ export declare class BranchTooLongError extends LintError {
16
16
  export declare class BranchTooShortError extends LintError {
17
17
  constructor(branchName: string, minLength: number);
18
18
  }
19
+ /**
20
+ * Error thrown when a branch placeholder pattern in config is invalid.
21
+ */
22
+ export declare class InvalidBranchPatternConfigError extends LintError {
23
+ constructor(placeholderName: string, patternSource: string);
24
+ }
19
25
  /**
20
26
  * Error thrown when branch name doesn't match the pattern
21
27
  */
@@ -0,0 +1,18 @@
1
+ import type { TBranchSubjectPattern } from "../type/branch-subject-pattern.type";
2
+ /**
3
+ * Domain policy for working with branch templates and placeholders.
4
+ */
5
+ export declare class BranchTemplatePolicy {
6
+ private static readonly PLACEHOLDER_PATTERN;
7
+ buildBranchName(branchPattern: string, placeholderValues: Record<string, string>): string;
8
+ buildValidationPatterns(branchPattern: string): Array<string>;
9
+ getPlaceholders(branchPattern: string): Array<string>;
10
+ isPlaceholderOptional(branchPattern: string, placeholderName: string): boolean;
11
+ resolvePlaceholderPatternSource(placeholderName: string, branchTypes: Array<string>, subjectPattern?: TBranchSubjectPattern): string;
12
+ private createAlternationPattern;
13
+ private escapeRegex;
14
+ private isDelimiter;
15
+ private normalizeBranchNameDelimiters;
16
+ private removeOptionalPlaceholder;
17
+ private trimDelimiterEdges;
18
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Domain policy for ticket identifier normalization and validation.
3
+ */
4
+ export declare class TicketIdPolicy {
5
+ private static readonly TICKET_ID_PATTERN;
6
+ isEmpty(candidate: string): boolean;
7
+ isValid(candidate: string): boolean;
8
+ normalize(candidate: string): string;
9
+ }
@@ -0,0 +1 @@
1
+ export type TBranchSubjectPattern = Record<string, string> | string;