bbk-cli 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.
Files changed (76) hide show
  1. package/.claude/bitbucket-config.local.md.example +58 -0
  2. package/.eslintcache +1 -0
  3. package/.github/dependabot.yml +15 -0
  4. package/.github/workflows/convetional-commit.yml +24 -0
  5. package/.github/workflows/publish-on-tag.yml +47 -0
  6. package/.github/workflows/release-please.yml +21 -0
  7. package/.github/workflows/run-tests.yml +75 -0
  8. package/.nvmrc +1 -0
  9. package/.prettierignore +2 -0
  10. package/.prettierrc.cjs +17 -0
  11. package/.release-please-manifest.json +3 -0
  12. package/CHANGELOG.md +21 -0
  13. package/LICENSE +202 -0
  14. package/README.md +381 -0
  15. package/dist/cli/index.d.ts +2 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +2 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/cli/wrapper.d.ts +38 -0
  20. package/dist/cli/wrapper.d.ts.map +1 -0
  21. package/dist/cli/wrapper.js +326 -0
  22. package/dist/cli/wrapper.js.map +1 -0
  23. package/dist/commands/helpers.d.ts +11 -0
  24. package/dist/commands/helpers.d.ts.map +1 -0
  25. package/dist/commands/helpers.js +40 -0
  26. package/dist/commands/helpers.js.map +1 -0
  27. package/dist/commands/index.d.ts +3 -0
  28. package/dist/commands/index.d.ts.map +1 -0
  29. package/dist/commands/index.js +3 -0
  30. package/dist/commands/index.js.map +1 -0
  31. package/dist/commands/runner.d.ts +7 -0
  32. package/dist/commands/runner.d.ts.map +1 -0
  33. package/dist/commands/runner.js +126 -0
  34. package/dist/commands/runner.js.map +1 -0
  35. package/dist/config/constants.d.ts +16 -0
  36. package/dist/config/constants.d.ts.map +1 -0
  37. package/dist/config/constants.js +171 -0
  38. package/dist/config/constants.js.map +1 -0
  39. package/dist/config/index.d.ts +2 -0
  40. package/dist/config/index.d.ts.map +1 -0
  41. package/dist/config/index.js +2 -0
  42. package/dist/config/index.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +24 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/utils/arg-parser.d.ts +7 -0
  48. package/dist/utils/arg-parser.d.ts.map +1 -0
  49. package/dist/utils/arg-parser.js +67 -0
  50. package/dist/utils/arg-parser.js.map +1 -0
  51. package/dist/utils/bitbucket-client.d.ts +122 -0
  52. package/dist/utils/bitbucket-client.d.ts.map +1 -0
  53. package/dist/utils/bitbucket-client.js +182 -0
  54. package/dist/utils/bitbucket-client.js.map +1 -0
  55. package/dist/utils/bitbucket-utils.d.ts +110 -0
  56. package/dist/utils/bitbucket-utils.d.ts.map +1 -0
  57. package/dist/utils/bitbucket-utils.js +491 -0
  58. package/dist/utils/bitbucket-utils.js.map +1 -0
  59. package/dist/utils/config-loader.d.ts +41 -0
  60. package/dist/utils/config-loader.d.ts.map +1 -0
  61. package/dist/utils/config-loader.js +76 -0
  62. package/dist/utils/config-loader.js.map +1 -0
  63. package/dist/utils/index.d.ts +5 -0
  64. package/dist/utils/index.d.ts.map +1 -0
  65. package/dist/utils/index.js +4 -0
  66. package/dist/utils/index.js.map +1 -0
  67. package/eslint.config.ts +15 -0
  68. package/package.json +62 -0
  69. package/release-please-config.json +33 -0
  70. package/tests/integration/cli-integration.test.ts +528 -0
  71. package/tests/unit/cli/wrapper.test.ts +727 -0
  72. package/tests/unit/commands/helpers.test.ts +268 -0
  73. package/tests/unit/commands/runner.test.ts +758 -0
  74. package/tests/unit/utils/arg-parser.test.ts +350 -0
  75. package/tests/unit/utils/config-loader.test.ts +158 -0
  76. package/vitest.config.ts +22 -0
@@ -0,0 +1,76 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import yaml from 'yaml';
4
+ /**
5
+ * Validate email format
6
+ */
7
+ function isValidEmail(email) {
8
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
9
+ return emailRegex.test(email);
10
+ }
11
+ /**
12
+ * Load Bitbucket connection profiles from .claude/bitbucket-config.local.md
13
+ *
14
+ * @param projectRoot - Project root directory
15
+ * @returns Configuration object with profiles and settings
16
+ */
17
+ export function loadConfig(projectRoot) {
18
+ const configPath = path.join(projectRoot, '.claude', 'bitbucket-config.local.md');
19
+ if (!fs.existsSync(configPath)) {
20
+ throw new Error(`Configuration file not found at ${configPath}\n` +
21
+ `Please create .claude/bitbucket-config.local.md with your Bitbucket profiles.`);
22
+ }
23
+ const content = fs.readFileSync(configPath, 'utf-8');
24
+ // Extract YAML frontmatter
25
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---/;
26
+ const frontmatterMatch = frontmatterRegex.exec(content);
27
+ if (!frontmatterMatch) {
28
+ throw new Error(`Invalid configuration file format. Expected YAML frontmatter (---...---) at the beginning.`);
29
+ }
30
+ const frontmatter = frontmatterMatch[1];
31
+ const config = yaml.parse(frontmatter);
32
+ // Validate configuration
33
+ if (!config.profiles || typeof config.profiles !== 'object') {
34
+ throw new Error('Configuration must include "profiles" object');
35
+ }
36
+ // Validate each profile
37
+ for (const [profileName, profile] of Object.entries(config.profiles)) {
38
+ // Email and apiToken are required
39
+ if (!profile.email || !profile.apiToken) {
40
+ throw new Error(`Profile "${profileName}" must have both "email" and "apiToken"`);
41
+ }
42
+ // Validate email format
43
+ if (!isValidEmail(profile.email)) {
44
+ throw new Error(`Profile "${profileName}" has invalid email format: "${profile.email}"`);
45
+ }
46
+ }
47
+ return {
48
+ profiles: config.profiles,
49
+ defaultProfile: config.defaultProfile || Object.keys(config.profiles)[0],
50
+ defaultFormat: config.defaultFormat || 'json',
51
+ };
52
+ }
53
+ /**
54
+ * Get Bitbucket client options for a specific profile
55
+ *
56
+ * @param config - Configuration object
57
+ * @param profileName - Profile name
58
+ * @returns Bitbucket client options object with basic auth
59
+ */
60
+ export function getBitbucketClientOptions(config, profileName) {
61
+ const profile = config.profiles[profileName];
62
+ if (!profile) {
63
+ const availableProfiles = Object.keys(config.profiles).join(', ');
64
+ throw new Error(`Profile "${profileName}" not found. Available profiles: ${availableProfiles}`);
65
+ }
66
+ if (!profile.email || !profile.apiToken) {
67
+ throw new Error(`Profile "${profileName}" must have both "email" and "apiToken"`);
68
+ }
69
+ return {
70
+ auth: {
71
+ email: profile.email,
72
+ apiToken: profile.apiToken,
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/utils/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { parseArguments } from './arg-parser.js';
2
+ export { loadConfig } from './config-loader.js';
3
+ export type { Config } from './config-loader.js';
4
+ export { listRepositories, getRepository, listPullRequests, getPullRequest, createPullRequest, listBranches, listCommits, listIssues, getIssue, createIssue, listPipelines, getUser, testConnection, clearClients, } from './bitbucket-client.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,YAAY,GACb,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { parseArguments } from './arg-parser.js';
2
+ export { loadConfig } from './config-loader.js';
3
+ export { listRepositories, getRepository, listPullRequests, getPullRequest, createPullRequest, listBranches, listCommits, listIssues, getIssue, createIssue, listPipelines, getUser, testConnection, clearClients, } from './bitbucket-client.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,YAAY,GACb,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import tseslint from 'typescript-eslint';
4
+
5
+ import { defineConfig } from 'eslint/config';
6
+
7
+ export default defineConfig([
8
+ {
9
+ files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
10
+ plugins: { js },
11
+ extends: ['js/recommended'],
12
+ languageOptions: { globals: globals.node },
13
+ },
14
+ tseslint.configs.recommended,
15
+ ]);
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "bbk-cli",
3
+ "version": "1.0.0",
4
+ "description": "A powerful command-line interface for Bitbucket interaction with support for repositories, pull requests, issues, and pipelines",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "bbk-cli": "dist/index.js"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "tsx src/index.ts",
13
+ "dev": "tsx src/index.ts",
14
+ "conductor": "tsx src/conductor-cli.ts",
15
+ "conductor:dev": "tsx src/conductor-cli.ts",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "test:ui": "vitest --ui",
19
+ "test:coverage": "vitest run --coverage",
20
+ "find-deadcode": "ts-prune",
21
+ "format": "eslint --cache --fix --quiet . && prettier --write --cache .",
22
+ "pre-commit": "npm run format && npm run find-deadcode"
23
+ },
24
+ "keywords": [
25
+ "bitbucket",
26
+ "cli",
27
+ "api",
28
+ "atlassian",
29
+ "git"
30
+ ],
31
+ "author": "Hesed",
32
+ "license": "Apache-2.0",
33
+ "dependencies": {
34
+ "@toon-format/toon": "^2.0.1",
35
+ "yaml": "^2.8.1"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/js": "^9.39.1",
39
+ "@trivago/prettier-plugin-sort-imports": "^6.0.0",
40
+ "@types/node": "^25.0.10",
41
+ "@vitest/coverage-v8": "^4.0.18",
42
+ "@vitest/ui": "^4.0.9",
43
+ "eslint": "^9.39.1",
44
+ "globals": "^17.1.0",
45
+ "jiti": "^2.6.1",
46
+ "prettier": "3.8.1",
47
+ "ts-prune": "^0.10.3",
48
+ "tsx": "^4.0.0",
49
+ "typescript": "^5.0.0",
50
+ "typescript-eslint": "^8.46.4",
51
+ "vitest": "^4.0.9"
52
+ },
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "git+https://github.com/hesedcasa/bbk-cli.git"
56
+ },
57
+ "types": "./dist/index.d.ts",
58
+ "bugs": {
59
+ "url": "https://github.com/hesedcasa/bbk-cli/issues"
60
+ },
61
+ "homepage": "https://github.com/hesedcasa/bbk-cli#readme"
62
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "changelog-sections": [
3
+ { "type": "feat", "section": "🎉 Features", "hidden": false },
4
+ { "type": "fix", "section": "🛠️ Fixes", "hidden": false },
5
+ { "type": "docs", "section": "📄 Documentation", "hidden": false },
6
+
7
+ { "type": "perf", "section": "♻️ Chores", "hidden": false },
8
+ { "type": "refactor", "section": "♻️ Chores", "hidden": false },
9
+ { "type": "chore", "section": "♻️ Chores", "hidden": true },
10
+ { "type": "test", "section": "♻️ Chores", "hidden": true },
11
+
12
+ { "type": "build", "section": "⚙️ Automation", "hidden": true },
13
+ { "type": "ci", "section": "⚙️ Automation", "hidden": true }
14
+ ],
15
+
16
+ "packages": {
17
+ ".": {
18
+ "changelog-path": "CHANGELOG.md",
19
+ "release-type": "node",
20
+ "bump-minor-pre-major": false,
21
+ "bump-patch-for-minor-pre-major": false,
22
+ "draft": false,
23
+ "prerelease": false,
24
+ "extra-files": [
25
+ {
26
+ "type": "generic",
27
+ "path": "src/commands/helpers.ts"
28
+ }
29
+ ]
30
+ }
31
+ },
32
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
33
+ }