@tugudush/bitbucket-mcp 1.0.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/LICENSE +21 -0
- package/README.md +202 -0
- package/build/api.d.ts +19 -0
- package/build/api.d.ts.map +1 -0
- package/build/api.js +105 -0
- package/build/api.js.map +1 -0
- package/build/config.d.ts +46 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +80 -0
- package/build/config.js.map +1 -0
- package/build/errors.d.ts +33 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +100 -0
- package/build/errors.js.map +1 -0
- package/build/index-new.d.ts +3 -0
- package/build/index-new.d.ts.map +1 -0
- package/build/index-new.js +43 -0
- package/build/index-new.js.map +1 -0
- package/build/index-old.d.ts +3 -0
- package/build/index-old.d.ts.map +1 -0
- package/build/index-old.js +1028 -0
- package/build/index-old.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +43 -0
- package/build/index.js.map +1 -0
- package/build/schemas.d.ts +287 -0
- package/build/schemas.d.ts.map +1 -0
- package/build/schemas.js +208 -0
- package/build/schemas.js.map +1 -0
- package/build/tools.d.ts +13 -0
- package/build/tools.d.ts.map +1 -0
- package/build/tools.js +710 -0
- package/build/tools.js.map +1 -0
- package/build/types.d.ts +180 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +5 -0
- package/build/types.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Bitbucket MCP Server
|
|
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:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
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 THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Bitbucket MCP Server
|
|
2
|
+
|
|
3
|
+
A **read-only** Model Context Protocol (MCP) server that provides secure access to Bitbucket repositories, pull requests, issues, and more. Integrates seamlessly with VS Code GitHub Copilot and Claude Desktop.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **Code Search**: Enable at https://bitbucket.org/search for `bb_search_code` functionality
|
|
8
|
+
- **Node.js**: Version 16+ with ES modules support
|
|
9
|
+
- **Authentication**: API token + email or username + app password
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### 1. Install & Build
|
|
14
|
+
```bash
|
|
15
|
+
git clone <repository-url>
|
|
16
|
+
cd bitbucket-mcp
|
|
17
|
+
npm install
|
|
18
|
+
npm run build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Authentication (Optional - for testing only)
|
|
22
|
+
|
|
23
|
+
**⚠️ Note**: This step is only needed for manual testing. If you're going directly to step 3 (Integration), you can skip this step as authentication is configured in the integration files.
|
|
24
|
+
|
|
25
|
+
For manual server testing, choose one authentication method:
|
|
26
|
+
|
|
27
|
+
**API Tokens (Recommended)**
|
|
28
|
+
```bash
|
|
29
|
+
export BITBUCKET_API_TOKEN="your-api-token"
|
|
30
|
+
export BITBUCKET_EMAIL="your-atlassian-email"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**App Passwords (Legacy - deprecated Sept 9, 2025)**
|
|
34
|
+
```bash
|
|
35
|
+
export BITBUCKET_USERNAME="your-username"
|
|
36
|
+
export BITBUCKET_APP_PASSWORD="your-app-password"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Without Authentication**: The server will work with public repositories only.
|
|
40
|
+
|
|
41
|
+
### 3. Integration (Authentication included here)
|
|
42
|
+
|
|
43
|
+
**For most users, this is where you actually configure authentication credentials.**
|
|
44
|
+
|
|
45
|
+
**VS Code GitHub Copilot**
|
|
46
|
+
```json
|
|
47
|
+
// .vscode/mcp.json
|
|
48
|
+
{
|
|
49
|
+
"servers": {
|
|
50
|
+
"bitbucket-mcp": {
|
|
51
|
+
"type": "stdio",
|
|
52
|
+
"command": "node",
|
|
53
|
+
"args": ["/path/to/build/index.js"],
|
|
54
|
+
"env": {
|
|
55
|
+
"BITBUCKET_API_TOKEN": "your-token",
|
|
56
|
+
"BITBUCKET_EMAIL": "your@email.com"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Claude Desktop**
|
|
64
|
+
```json
|
|
65
|
+
// claude_desktop_config.json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"bitbucket": {
|
|
69
|
+
"command": "node",
|
|
70
|
+
"args": ["/path/to/build/index.js"],
|
|
71
|
+
"env": {
|
|
72
|
+
"BITBUCKET_API_TOKEN": "your-token",
|
|
73
|
+
"BITBUCKET_EMAIL": "your@email.com"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**💡 Tip**: Replace `/path/to/build/index.js` with the absolute path to your built server, and add your actual Bitbucket credentials to access private repositories.
|
|
81
|
+
|
|
82
|
+
## Features
|
|
83
|
+
|
|
84
|
+
**Repository Management**
|
|
85
|
+
- `bb_list_workspaces` - Discover accessible workspaces
|
|
86
|
+
- `bb_list_repositories` - List repositories across workspaces
|
|
87
|
+
- `bb_get_repository` - Get repository details
|
|
88
|
+
- `bb_browse_repository` - Explore directory structure (supports branches with slashes like `feature/SSP-1024`)
|
|
89
|
+
- `bb_get_file_content` - Read files with pagination (1-10,000 lines)
|
|
90
|
+
|
|
91
|
+
**Pull Requests & Issues**
|
|
92
|
+
- `bb_get_pull_requests`, `bb_get_pull_request` - Browse pull requests
|
|
93
|
+
- `bb_get_pull_request_comments`, `bb_get_pull_request_activity` - Track reviews
|
|
94
|
+
- `bb_get_issues`, `bb_get_issue` - Monitor issues
|
|
95
|
+
|
|
96
|
+
**Version Control**
|
|
97
|
+
- `bb_get_branches`, `bb_get_commits` - Explore repository history
|
|
98
|
+
|
|
99
|
+
**Search & Discovery**
|
|
100
|
+
- `bb_search_code` - Advanced code search with language filtering
|
|
101
|
+
- `bb_search_repositories` - Find repositories
|
|
102
|
+
|
|
103
|
+
**User & Workspace Info**
|
|
104
|
+
- `bb_get_user`, `bb_get_current_user` - User information
|
|
105
|
+
- `bb_get_workspace` - Workspace details
|
|
106
|
+
|
|
107
|
+
## Usage Examples
|
|
108
|
+
|
|
109
|
+
**Repository Discovery:**
|
|
110
|
+
- "List all my accessible workspaces"
|
|
111
|
+
- "Browse the root directory of myworkspace/myrepo"
|
|
112
|
+
- "Browse the tests directory in feature/deployment-fixes branch"
|
|
113
|
+
|
|
114
|
+
**Advanced File Operations:**
|
|
115
|
+
- "Read lines 100-200 of src/app.py from myworkspace/myrepo"
|
|
116
|
+
- "Get the first 50 lines of README.md"
|
|
117
|
+
- "Show me the package.json file with pagination"
|
|
118
|
+
|
|
119
|
+
**Code Search:**
|
|
120
|
+
- "Search for 'authentication' code in myworkspace/myrepo"
|
|
121
|
+
- "Find all functions containing 'validate' in myworkspace/myrepo"
|
|
122
|
+
- "Search for TypeScript interfaces in myworkspace/myrepo"
|
|
123
|
+
- "Look for 'TODO' comments in myworkspace/myrepo"
|
|
124
|
+
|
|
125
|
+
**Pull Requests & Issues:**
|
|
126
|
+
- "List repositories in myworkspace"
|
|
127
|
+
- "Show open pull requests for myworkspace/myrepo"
|
|
128
|
+
- "Get README.md from myworkspace/myrepo"
|
|
129
|
+
- "Show recent commits on main branch of myworkspace/myrepo"
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm run ltf # Lint + Typecheck + Format
|
|
135
|
+
npm run build # Compile TypeScript
|
|
136
|
+
npm run watch # Development mode
|
|
137
|
+
node build/index.js # Test server
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**VS Code Integration:**
|
|
141
|
+
- Install GitHub Copilot extensions
|
|
142
|
+
- Use provided `.vscode/` configuration
|
|
143
|
+
- Open Copilot Chat with `Ctrl+Alt+I`
|
|
144
|
+
- Try: `using bitbucket, list repositories in myworkspace`
|
|
145
|
+
|
|
146
|
+
## Security & Limitations
|
|
147
|
+
|
|
148
|
+
- ✅ **Read-only by design**: No write/delete/modify operations possible
|
|
149
|
+
- ✅ **Safe for production**: No destructive actions supported
|
|
150
|
+
- ✅ **Authenticated access**: Uses API tokens or App Passwords for private repos
|
|
151
|
+
- ✅ **Branch support**: Handles branch names with special characters (e.g., `feature/SSP-1024`)
|
|
152
|
+
- ✅ **Dynamic commit resolution**: Automatically resolves branch names to commit SHAs for subdirectory browsing
|
|
153
|
+
- ⚠️ **Rate limiting**: Subject to Bitbucket API limits
|
|
154
|
+
- ⚠️ **Code search**: Requires enablement in Bitbucket account settings
|
|
155
|
+
- ⚠️ **File size limits**: Large files may be truncated
|
|
156
|
+
|
|
157
|
+
## Development Status & Related Projects
|
|
158
|
+
|
|
159
|
+
🚧 **This project is under active development** and may contain incomplete features or breaking changes. We welcome contributions and feedback!
|
|
160
|
+
|
|
161
|
+
**Related MCP Servers for Reference:**
|
|
162
|
+
- [bitbucket-server-mcp-server](https://github.com/garc33/bitbucket-server-mcp-server) - MCP server for Bitbucket Server (on-premises)
|
|
163
|
+
- [mcp-server-atlassian-bitbucket](https://github.com/aashari/mcp-server-atlassian-bitbucket) - Alternative Atlassian Bitbucket MCP implementation
|
|
164
|
+
|
|
165
|
+
These repositories provide excellent reference implementations and inspiration for Bitbucket API integration patterns.
|
|
166
|
+
|
|
167
|
+
## API Coverage
|
|
168
|
+
|
|
169
|
+
The server implements tools for the most commonly used Bitbucket API endpoints:
|
|
170
|
+
|
|
171
|
+
- **Repositories API** (read-only operations)
|
|
172
|
+
- **Pull Requests API** (read-only operations)
|
|
173
|
+
- Pull request details and listing
|
|
174
|
+
- Pull request comments (inline and general)
|
|
175
|
+
- Pull request activity (reviews, approvals, state changes)
|
|
176
|
+
- **Issues API** (read-only operations)
|
|
177
|
+
- **Source API** (file content access)
|
|
178
|
+
- **Search API** (code search with language filtering and match highlighting)
|
|
179
|
+
- **Users API** (user information)
|
|
180
|
+
- **Workspaces API** (workspace information)
|
|
181
|
+
- **Branches API** (branch listing and information)
|
|
182
|
+
- **Commits API** (commit history and details)
|
|
183
|
+
|
|
184
|
+
## Contributing
|
|
185
|
+
|
|
186
|
+
1. Fork the repository
|
|
187
|
+
2. Create a feature branch
|
|
188
|
+
3. Make your changes (maintaining read-only nature)
|
|
189
|
+
4. Add tests if applicable
|
|
190
|
+
5. Submit a pull request
|
|
191
|
+
|
|
192
|
+
## Roadmap
|
|
193
|
+
|
|
194
|
+
Future enhancements (all read-only):
|
|
195
|
+
|
|
196
|
+
- Repository statistics and analytics
|
|
197
|
+
- Enhanced search capabilities with more filter options
|
|
198
|
+
- Webhook information retrieval
|
|
199
|
+
- Pipeline status (read-only)
|
|
200
|
+
- More detailed branch and commit information
|
|
201
|
+
- Repository comparison tools
|
|
202
|
+
- Advanced code search filters and sorting
|
package/build/api.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const BITBUCKET_API_BASE = "https://api.bitbucket.org/2.0";
|
|
2
|
+
/**
|
|
3
|
+
* Helper function to make authenticated requests to Bitbucket API
|
|
4
|
+
* Enforces read-only behavior by blocking non-GET requests
|
|
5
|
+
*/
|
|
6
|
+
export declare function makeRequest<T = unknown>(url: string, options?: RequestInit): Promise<T>;
|
|
7
|
+
/**
|
|
8
|
+
* Build URL for Bitbucket API endpoints
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildApiUrl(endpoint: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Helper to build URL parameters for pagination and filtering
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildUrlParams(params: Record<string, unknown>): URLSearchParams;
|
|
15
|
+
/**
|
|
16
|
+
* Helper to add query parameters to URL
|
|
17
|
+
*/
|
|
18
|
+
export declare function addQueryParams(url: string, params: Record<string, unknown>): string;
|
|
19
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,kBAAkB,kCAAkC,CAAC;AAElE;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CA0DZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,eAAe,CAgBjB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAUR"}
|
package/build/api.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { loadConfig } from './config.js';
|
|
2
|
+
import { createApiError } from './errors.js';
|
|
3
|
+
import { API_CONSTANTS } from './schemas.js';
|
|
4
|
+
/**
|
|
5
|
+
* Bitbucket API configuration and request handling
|
|
6
|
+
*/
|
|
7
|
+
// Get config dynamically to handle environment changes
|
|
8
|
+
function getConfig() {
|
|
9
|
+
return loadConfig();
|
|
10
|
+
}
|
|
11
|
+
// Bitbucket API base URL
|
|
12
|
+
export const BITBUCKET_API_BASE = 'https://api.bitbucket.org/2.0';
|
|
13
|
+
/**
|
|
14
|
+
* Helper function to make authenticated requests to Bitbucket API
|
|
15
|
+
* Enforces read-only behavior by blocking non-GET requests
|
|
16
|
+
*/
|
|
17
|
+
export async function makeRequest(url, options = {}) {
|
|
18
|
+
// Enforce read-only behavior: block any non-GET methods at runtime
|
|
19
|
+
const requestedMethod = (options.method || 'GET').toString().toUpperCase();
|
|
20
|
+
if (requestedMethod !== 'GET') {
|
|
21
|
+
throw new Error(`Only GET requests are allowed. Attempted: ${requestedMethod} ${url}`);
|
|
22
|
+
}
|
|
23
|
+
const headers = {
|
|
24
|
+
Accept: 'application/json',
|
|
25
|
+
'User-Agent': 'bitbucket-mcp-server/1.0.0',
|
|
26
|
+
...(options.headers || {}),
|
|
27
|
+
};
|
|
28
|
+
// Add authentication if available
|
|
29
|
+
// Priority: API Token (Basic auth with email) > App Password (Basic auth with username)
|
|
30
|
+
const config = getConfig();
|
|
31
|
+
const apiToken = config.BITBUCKET_API_TOKEN;
|
|
32
|
+
const email = config.BITBUCKET_EMAIL;
|
|
33
|
+
const username = config.BITBUCKET_USERNAME;
|
|
34
|
+
const appPassword = config.BITBUCKET_APP_PASSWORD;
|
|
35
|
+
if (apiToken && email) {
|
|
36
|
+
// Use API Token with Basic authentication (recommended)
|
|
37
|
+
// Username should be your Atlassian email, password is the API token
|
|
38
|
+
const auth = Buffer.from(`${email}:${apiToken}`).toString('base64');
|
|
39
|
+
headers.Authorization = `Basic ${auth}`;
|
|
40
|
+
}
|
|
41
|
+
else if (username && appPassword) {
|
|
42
|
+
// Fallback to App Password with Basic authentication (legacy)
|
|
43
|
+
const auth = Buffer.from(`${username}:${appPassword}`).toString('base64');
|
|
44
|
+
headers.Authorization = `Basic ${auth}`;
|
|
45
|
+
}
|
|
46
|
+
const response = await fetch(url, {
|
|
47
|
+
...options,
|
|
48
|
+
// Force GET to prevent accidental method overrides downstream
|
|
49
|
+
method: 'GET',
|
|
50
|
+
headers,
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const errorText = await response.text();
|
|
54
|
+
// Try to parse error details
|
|
55
|
+
let errorData;
|
|
56
|
+
try {
|
|
57
|
+
errorData = JSON.parse(errorText);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// If JSON parsing fails, use raw error text
|
|
61
|
+
errorData = { message: errorText };
|
|
62
|
+
}
|
|
63
|
+
// Create and throw appropriate error type
|
|
64
|
+
throw createApiError(response.status, response.statusText, errorData, url);
|
|
65
|
+
}
|
|
66
|
+
return await response.json();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build URL for Bitbucket API endpoints
|
|
70
|
+
*/
|
|
71
|
+
export function buildApiUrl(endpoint) {
|
|
72
|
+
return `${BITBUCKET_API_BASE}${endpoint}`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Helper to build URL parameters for pagination and filtering
|
|
76
|
+
*/
|
|
77
|
+
export function buildUrlParams(params) {
|
|
78
|
+
const urlParams = new URLSearchParams();
|
|
79
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
80
|
+
if (value !== undefined && value !== null) {
|
|
81
|
+
// Handle pagination limits
|
|
82
|
+
if ((key === 'pagelen' || key === 'limit') && typeof value === 'number') {
|
|
83
|
+
const limitedValue = Math.min(value, API_CONSTANTS.MAX_PAGE_SIZE);
|
|
84
|
+
urlParams.append(key, limitedValue.toString());
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
urlParams.append(key, String(value));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return urlParams;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Helper to add query parameters to URL
|
|
95
|
+
*/
|
|
96
|
+
export function addQueryParams(url, params) {
|
|
97
|
+
const urlParams = buildUrlParams(params);
|
|
98
|
+
const paramString = urlParams.toString();
|
|
99
|
+
if (!paramString) {
|
|
100
|
+
return url;
|
|
101
|
+
}
|
|
102
|
+
const separator = url.includes('?') ? '&' : '?';
|
|
103
|
+
return `${url}${separator}${paramString}`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=api.js.map
|
package/build/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management with validation and type safety
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
6
|
+
BITBUCKET_API_TOKEN: z.ZodOptional<z.ZodString>;
|
|
7
|
+
BITBUCKET_EMAIL: z.ZodOptional<z.ZodString>;
|
|
8
|
+
BITBUCKET_USERNAME: z.ZodOptional<z.ZodString>;
|
|
9
|
+
BITBUCKET_APP_PASSWORD: z.ZodOptional<z.ZodString>;
|
|
10
|
+
BITBUCKET_API_BASE: z.ZodDefault<z.ZodString>;
|
|
11
|
+
BITBUCKET_REQUEST_TIMEOUT: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
|
|
12
|
+
BITBUCKET_DEBUG: z.ZodDefault<z.ZodEffects<z.ZodString, boolean, string>>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
BITBUCKET_API_BASE: string;
|
|
15
|
+
BITBUCKET_REQUEST_TIMEOUT: number;
|
|
16
|
+
BITBUCKET_DEBUG: boolean;
|
|
17
|
+
BITBUCKET_API_TOKEN?: string | undefined;
|
|
18
|
+
BITBUCKET_EMAIL?: string | undefined;
|
|
19
|
+
BITBUCKET_USERNAME?: string | undefined;
|
|
20
|
+
BITBUCKET_APP_PASSWORD?: string | undefined;
|
|
21
|
+
}, {
|
|
22
|
+
BITBUCKET_API_TOKEN?: string | undefined;
|
|
23
|
+
BITBUCKET_EMAIL?: string | undefined;
|
|
24
|
+
BITBUCKET_USERNAME?: string | undefined;
|
|
25
|
+
BITBUCKET_APP_PASSWORD?: string | undefined;
|
|
26
|
+
BITBUCKET_API_BASE?: string | undefined;
|
|
27
|
+
BITBUCKET_REQUEST_TIMEOUT?: string | undefined;
|
|
28
|
+
BITBUCKET_DEBUG?: string | undefined;
|
|
29
|
+
}>;
|
|
30
|
+
export type Config = z.infer<typeof ConfigSchema>;
|
|
31
|
+
export declare function loadConfig(): Config;
|
|
32
|
+
export interface AuthMethod {
|
|
33
|
+
method: 'api-token' | 'app-password' | 'none';
|
|
34
|
+
isValid: boolean;
|
|
35
|
+
warning?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function validateAuthentication(config: Config): AuthMethod;
|
|
38
|
+
/**
|
|
39
|
+
* Initialize and validate configuration, logging warnings as needed
|
|
40
|
+
*/
|
|
41
|
+
export declare function initializeConfig(): {
|
|
42
|
+
config: Config;
|
|
43
|
+
auth: AuthMethod;
|
|
44
|
+
};
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;EAgBhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAgB,UAAU,IAAI,MAAM,CAanC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,MAAM,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAoBjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAoCvE"}
|
package/build/config.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management with validation and type safety
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
// Configuration schema with validation
|
|
6
|
+
const ConfigSchema = z.object({
|
|
7
|
+
// Authentication (prioritized order)
|
|
8
|
+
BITBUCKET_API_TOKEN: z.string().optional(),
|
|
9
|
+
BITBUCKET_EMAIL: z.string().email().optional(),
|
|
10
|
+
BITBUCKET_USERNAME: z.string().optional(),
|
|
11
|
+
BITBUCKET_APP_PASSWORD: z.string().optional(),
|
|
12
|
+
// API Configuration
|
|
13
|
+
BITBUCKET_API_BASE: z.string().url().default('https://api.bitbucket.org/2.0'),
|
|
14
|
+
BITBUCKET_REQUEST_TIMEOUT: z.string().transform(Number).default('30000'),
|
|
15
|
+
// Debugging
|
|
16
|
+
BITBUCKET_DEBUG: z
|
|
17
|
+
.string()
|
|
18
|
+
.transform(val => val === 'true')
|
|
19
|
+
.default('false'),
|
|
20
|
+
});
|
|
21
|
+
export function loadConfig() {
|
|
22
|
+
try {
|
|
23
|
+
return ConfigSchema.parse(process.env);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error instanceof z.ZodError) {
|
|
27
|
+
const missingFields = error.errors
|
|
28
|
+
.map(err => `${err.path.join('.')}: ${err.message}`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
throw new Error(`Configuration validation failed:\n${missingFields}`);
|
|
31
|
+
}
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function validateAuthentication(config) {
|
|
36
|
+
if (config.BITBUCKET_API_TOKEN && config.BITBUCKET_EMAIL) {
|
|
37
|
+
return { method: 'api-token', isValid: true };
|
|
38
|
+
}
|
|
39
|
+
if (config.BITBUCKET_USERNAME && config.BITBUCKET_APP_PASSWORD) {
|
|
40
|
+
return {
|
|
41
|
+
method: 'app-password',
|
|
42
|
+
isValid: true,
|
|
43
|
+
warning: 'App Passwords are deprecated (Sept 9, 2025). Consider migrating to API tokens.',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
method: 'none',
|
|
48
|
+
isValid: false,
|
|
49
|
+
warning: 'No authentication configured. Only public repositories will be accessible.',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Initialize and validate configuration, logging warnings as needed
|
|
54
|
+
*/
|
|
55
|
+
export function initializeConfig() {
|
|
56
|
+
const config = loadConfig();
|
|
57
|
+
const auth = validateAuthentication(config);
|
|
58
|
+
// Log authentication status
|
|
59
|
+
if (!auth.isValid) {
|
|
60
|
+
console.error('⚠️', auth.warning);
|
|
61
|
+
}
|
|
62
|
+
else if (auth.warning) {
|
|
63
|
+
console.error('⚠️', auth.warning);
|
|
64
|
+
}
|
|
65
|
+
// Log operational mode
|
|
66
|
+
console.error('🔒 Mode: READ-ONLY (by design)');
|
|
67
|
+
console.error(`🔐 Auth: ${auth.method.toUpperCase()}`);
|
|
68
|
+
if (config.BITBUCKET_DEBUG) {
|
|
69
|
+
console.error('🐛 Debug mode enabled');
|
|
70
|
+
console.error('Debug - Environment variables:');
|
|
71
|
+
console.error(' BITBUCKET_API_TOKEN:', config.BITBUCKET_API_TOKEN
|
|
72
|
+
? `SET (length: ${config.BITBUCKET_API_TOKEN.length})`
|
|
73
|
+
: 'NOT SET');
|
|
74
|
+
console.error(' BITBUCKET_EMAIL:', config.BITBUCKET_EMAIL || 'NOT SET');
|
|
75
|
+
console.error(' BITBUCKET_USERNAME:', config.BITBUCKET_USERNAME || 'NOT SET');
|
|
76
|
+
console.error(' BITBUCKET_APP_PASSWORD:', config.BITBUCKET_APP_PASSWORD ? 'SET' : 'NOT SET');
|
|
77
|
+
}
|
|
78
|
+
return { config, auth };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for better error handling and user feedback
|
|
3
|
+
*/
|
|
4
|
+
export declare class BitbucketApiError extends Error {
|
|
5
|
+
status: number;
|
|
6
|
+
statusText: string;
|
|
7
|
+
details?: string | undefined;
|
|
8
|
+
suggestion?: string | undefined;
|
|
9
|
+
constructor(status: number, statusText: string, details?: string | undefined, suggestion?: string | undefined);
|
|
10
|
+
}
|
|
11
|
+
export declare class AuthenticationError extends BitbucketApiError {
|
|
12
|
+
constructor(details?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class NotFoundError extends BitbucketApiError {
|
|
15
|
+
constructor(resource: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class ForbiddenError extends BitbucketApiError {
|
|
18
|
+
constructor(resource?: string);
|
|
19
|
+
}
|
|
20
|
+
export declare class RateLimitError extends BitbucketApiError {
|
|
21
|
+
constructor();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates appropriate error instance based on HTTP status code
|
|
25
|
+
*/
|
|
26
|
+
export declare function createApiError(status: number, statusText: string, errorData?: {
|
|
27
|
+
error?: {
|
|
28
|
+
message?: string;
|
|
29
|
+
detail?: string;
|
|
30
|
+
};
|
|
31
|
+
message?: string;
|
|
32
|
+
}, url?: string): BitbucketApiError;
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,iBAAkB,SAAQ,KAAK;IAEjC,MAAM,EAAE,MAAM;IACd,UAAU,EAAE,MAAM;IAClB,OAAO,CAAC,EAAE,MAAM;IAChB,UAAU,CAAC,EAAE,MAAM;gBAHnB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,YAAA,EAChB,UAAU,CAAC,EAAE,MAAM,YAAA;CAO7B;AAED,qBAAa,mBAAoB,SAAQ,iBAAiB;gBAC5C,OAAO,CAAC,EAAE,MAAM;CAS7B;AAED,qBAAa,aAAc,SAAQ,iBAAiB;gBACtC,QAAQ,EAAE,MAAM;CAS7B;AAED,qBAAa,cAAe,SAAQ,iBAAiB;gBACvC,QAAQ,CAAC,EAAE,MAAM;CAS9B;AAED,qBAAa,cAAe,SAAQ,iBAAiB;;CAUpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE;IACV,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,EACD,GAAG,CAAC,EAAE,MAAM,GACX,iBAAiB,CAmCnB"}
|
package/build/errors.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for better error handling and user feedback
|
|
3
|
+
*/
|
|
4
|
+
export class BitbucketApiError extends Error {
|
|
5
|
+
status;
|
|
6
|
+
statusText;
|
|
7
|
+
details;
|
|
8
|
+
suggestion;
|
|
9
|
+
constructor(status, statusText, details, suggestion) {
|
|
10
|
+
super(`Bitbucket API error: ${status} ${statusText}${details ? ` - ${details}` : ''}`);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.statusText = statusText;
|
|
13
|
+
this.details = details;
|
|
14
|
+
this.suggestion = suggestion;
|
|
15
|
+
this.name = 'BitbucketApiError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class AuthenticationError extends BitbucketApiError {
|
|
19
|
+
constructor(details) {
|
|
20
|
+
super(401, 'Unauthorized', details, 'Check your authentication credentials (BITBUCKET_API_TOKEN + BITBUCKET_EMAIL or BITBUCKET_USERNAME + BITBUCKET_APP_PASSWORD)');
|
|
21
|
+
this.name = 'AuthenticationError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export class NotFoundError extends BitbucketApiError {
|
|
25
|
+
constructor(resource) {
|
|
26
|
+
super(404, 'Not Found', `The requested ${resource} was not found`, 'Check the workspace/repository names and ensure you have access');
|
|
27
|
+
this.name = 'NotFoundError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class ForbiddenError extends BitbucketApiError {
|
|
31
|
+
constructor(resource) {
|
|
32
|
+
super(403, 'Forbidden', resource ? `Access denied to ${resource}` : 'Access denied', 'Your credentials may not have sufficient permissions for this resource');
|
|
33
|
+
this.name = 'ForbiddenError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class RateLimitError extends BitbucketApiError {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(429, 'Too Many Requests', 'Rate limit exceeded', 'Please wait before retrying');
|
|
39
|
+
this.name = 'RateLimitError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates appropriate error instance based on HTTP status code
|
|
44
|
+
*/
|
|
45
|
+
export function createApiError(status, statusText, errorData, url) {
|
|
46
|
+
let details = '';
|
|
47
|
+
// Try to extract error details from response
|
|
48
|
+
if (errorData) {
|
|
49
|
+
if (errorData.error?.message) {
|
|
50
|
+
details = errorData.error.message;
|
|
51
|
+
if (errorData.error.detail) {
|
|
52
|
+
details += ` (${errorData.error.detail})`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (errorData.message) {
|
|
56
|
+
details = errorData.message;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Extract resource type from URL for better error messages
|
|
60
|
+
const resource = extractResourceFromUrl(url);
|
|
61
|
+
switch (status) {
|
|
62
|
+
case 401:
|
|
63
|
+
return new AuthenticationError(details);
|
|
64
|
+
case 403:
|
|
65
|
+
return new ForbiddenError(resource);
|
|
66
|
+
case 404:
|
|
67
|
+
return new BitbucketApiError(404, 'Not Found', details || `The requested ${resource || 'resource'} was not found`, 'Check the workspace/repository names and ensure you have access');
|
|
68
|
+
case 429:
|
|
69
|
+
return new RateLimitError();
|
|
70
|
+
default:
|
|
71
|
+
return new BitbucketApiError(status, statusText, details);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extracts resource type from Bitbucket API URL for better error messages
|
|
76
|
+
*/
|
|
77
|
+
function extractResourceFromUrl(url) {
|
|
78
|
+
if (!url)
|
|
79
|
+
return undefined;
|
|
80
|
+
const patterns = [
|
|
81
|
+
{ pattern: /\/repositories\/[^/]+\/[^/]+$/, resource: 'repository' },
|
|
82
|
+
{
|
|
83
|
+
pattern: /\/repositories\/[^/]+\/[^/]+\/pullrequests/,
|
|
84
|
+
resource: 'pull request',
|
|
85
|
+
},
|
|
86
|
+
{ pattern: /\/repositories\/[^/]+\/[^/]+\/issues/, resource: 'issue' },
|
|
87
|
+
{ pattern: /\/repositories\/[^/]+\/[^/]+\/src/, resource: 'file' },
|
|
88
|
+
{ pattern: /\/repositories\/[^/]+\/[^/]+\/commits/, resource: 'commit' },
|
|
89
|
+
{ pattern: /\/repositories\/[^/]+\/[^/]+\/refs/, resource: 'branch' },
|
|
90
|
+
{ pattern: /\/workspaces\/[^/]+$/, resource: 'workspace' },
|
|
91
|
+
{ pattern: /\/user/, resource: 'user' },
|
|
92
|
+
];
|
|
93
|
+
for (const { pattern, resource } of patterns) {
|
|
94
|
+
if (pattern.test(url)) {
|
|
95
|
+
return resource;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return 'resource';
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-new.d.ts","sourceRoot":"","sources":["../src/index-new.ts"],"names":[],"mappings":""}
|