@mexty/cli 1.5.0 → 1.7.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 (38) hide show
  1. package/GITHUB_OAUTH_SETUP.md +247 -0
  2. package/dist/commands/github-disconnect.d.ts +2 -0
  3. package/dist/commands/github-disconnect.d.ts.map +1 -0
  4. package/dist/commands/github-disconnect.js +73 -0
  5. package/dist/commands/github-disconnect.js.map +1 -0
  6. package/dist/commands/github-login.d.ts +2 -0
  7. package/dist/commands/github-login.d.ts.map +1 -0
  8. package/dist/commands/github-login.js +100 -0
  9. package/dist/commands/github-login.js.map +1 -0
  10. package/dist/commands/update-git-url.d.ts +2 -0
  11. package/dist/commands/update-git-url.d.ts.map +1 -0
  12. package/dist/commands/update-git-url.js +153 -0
  13. package/dist/commands/update-git-url.js.map +1 -0
  14. package/dist/index.js +43 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/utils/api.d.ts +24 -0
  17. package/dist/utils/api.d.ts.map +1 -1
  18. package/dist/utils/api.js +24 -0
  19. package/dist/utils/api.js.map +1 -1
  20. package/dist/utils/git.d.ts +5 -0
  21. package/dist/utils/git.d.ts.map +1 -1
  22. package/dist/utils/git.js +55 -2
  23. package/dist/utils/git.js.map +1 -1
  24. package/package.json +2 -1
  25. package/src/commands/github-disconnect.ts +80 -0
  26. package/src/commands/github-login.ts +107 -0
  27. package/src/commands/update-git-url.ts +170 -0
  28. package/src/index.ts +47 -0
  29. package/src/utils/api.ts +29 -0
  30. package/src/utils/git.ts +60 -2
  31. package/dist/commands/fork.d.ts +0 -2
  32. package/dist/commands/fork.d.ts.map +0 -1
  33. package/dist/commands/fork.js +0 -57
  34. package/dist/commands/fork.js.map +0 -1
  35. package/dist/commands/sync.d.ts +0 -2
  36. package/dist/commands/sync.d.ts.map +0 -1
  37. package/dist/commands/sync.js +0 -250
  38. package/dist/commands/sync.js.map +0 -1
@@ -0,0 +1,247 @@
1
+ # GitHub OAuth Setup Guide
2
+
3
+ This guide explains how to set up and use GitHub OAuth authentication in the MEXTY CLI to enable access to private block repositories.
4
+
5
+ ## Overview
6
+
7
+ The GitHub OAuth integration allows users to:
8
+ - Clone private block repositories owned by their organization
9
+ - Access blocks they've purchased or have permission to view
10
+ - Seamlessly authenticate without manual token management
11
+
12
+ ## Backend Setup
13
+
14
+ ### 1. Register a GitHub OAuth App
15
+
16
+ 1. Go to https://github.com/settings/developers
17
+ 2. Click "New OAuth App"
18
+ 3. Fill in the details:
19
+ - **Application name**: MEXTY CLI
20
+ - **Homepage URL**: https://mexty.ai
21
+ - **Authorization callback URL**:
22
+ - Production: `https://api.mexty.ai/api/auth/github/callback`
23
+ - Development: `http://localhost:3001/api/auth/github/callback`
24
+ 4. Click "Register application"
25
+ 5. Note your **Client ID** and generate a **Client Secret**
26
+
27
+ ### 2. Configure Environment Variables
28
+
29
+ Add these to your backend `.env` file:
30
+
31
+ ```bash
32
+ # GitHub OAuth Configuration
33
+
34
+ ```
35
+
36
+ For development:
37
+ ```bash
38
+ GITHUB_REDIRECT_URI=http://localhost:3001/api/auth/github/callback
39
+ ```
40
+
41
+ ### 3. Database Migration
42
+
43
+ The User model has been updated with the following fields:
44
+ - `githubAccessToken` (encrypted, select: false)
45
+ - `githubUsername`
46
+ - `githubId`
47
+ - `githubTokenExpiresAt`
48
+
49
+ No migration script is needed as these fields are optional and will be populated when users connect GitHub.
50
+
51
+ ## CLI Setup
52
+
53
+ ### 1. Install Dependencies
54
+
55
+ The CLI needs the `open` package to launch the browser for OAuth:
56
+
57
+ ```bash
58
+ cd mexty-cli
59
+ npm install open@^8.4.2
60
+ ```
61
+
62
+ Update `package.json`:
63
+ ```json
64
+ {
65
+ "dependencies": {
66
+ "open": "^8.4.2"
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### 2. Build the CLI
72
+
73
+ ```bash
74
+ npm run build
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### Connect GitHub Account
80
+
81
+ ```bash
82
+ mexty github-login
83
+ ```
84
+
85
+ This will:
86
+ 1. Request an OAuth URL from the backend
87
+ 2. Open your browser to GitHub authorization page
88
+ 3. Redirect back to the backend after authorization
89
+ 4. Store your GitHub access token securely
90
+ 5. Poll for connection status and confirm success
91
+
92
+ ### Check GitHub Status
93
+
94
+ ```bash
95
+ mexty github-status
96
+ ```
97
+
98
+ Shows whether GitHub is connected and displays your GitHub username.
99
+
100
+ ### Disconnect GitHub
101
+
102
+ ```bash
103
+ mexty github-disconnect
104
+ ```
105
+
106
+ Removes your GitHub access token from the system.
107
+
108
+ ### Clone Private Repositories
109
+
110
+ Once GitHub is connected, the `mexty create` command will automatically use your GitHub token to clone private repositories:
111
+
112
+ ```bash
113
+ mexty create "My Private Block"
114
+ ```
115
+
116
+ The CLI will:
117
+ 1. Create the block on the backend
118
+ 2. Check if GitHub is connected
119
+ 3. Inject your GitHub token into the clone URL
120
+ 4. Clone the private repository
121
+
122
+ ## API Endpoints
123
+
124
+ ### Backend Routes
125
+
126
+ All routes are under `/api/auth`:
127
+
128
+ - `GET /github/url` - Get GitHub OAuth authorization URL (requires auth)
129
+ - `GET /github/callback` - GitHub OAuth callback (public)
130
+ - `GET /github/status` - Check GitHub connection status (requires auth)
131
+ - `GET /github/token` - Get GitHub access token for CLI (requires auth)
132
+ - `POST /github/disconnect` - Disconnect GitHub account (requires auth)
133
+
134
+ ### Security Considerations
135
+
136
+ 1. **Token Storage**: GitHub tokens are stored in the database with `select: false` to prevent accidental exposure
137
+ 2. **State Validation**: OAuth state parameter includes user ID and timestamp to prevent CSRF attacks
138
+ 3. **Token Scope**: Requests only `repo` scope for repository access
139
+ 4. **Expiration**: Tokens are marked as expiring after 1 year (configurable)
140
+ 5. **HTTPS Only**: In production, cookies are secure and HTTPS-only
141
+
142
+ ## Error Handling
143
+
144
+ ### Common Errors
145
+
146
+ 1. **"GitHub not connected"**
147
+ - Solution: Run `mexty github-login`
148
+
149
+ 2. **"Authentication required"**
150
+ - Solution: Run `mexty login` first
151
+
152
+ 3. **"GitHub OAuth is not configured on the server"**
153
+ - Solution: Admin needs to set up GitHub OAuth app and add credentials to backend
154
+
155
+ 4. **"Repository not found"**
156
+ - Could be a private repository - ensure GitHub is connected
157
+ - Could be an incorrect URL
158
+ - User might not have access to the repository
159
+
160
+ ## Flow Diagram
161
+
162
+ ```
163
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
164
+ │ CLI │ │ Backend │ │ GitHub │
165
+ ā””ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”˜
166
+ │ │ │
167
+ │ mexty github-login │ │
168
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€> │
169
+ │ │ │
170
+ │ GET /api/auth/github/url │ │
171
+ │<─────────────────────────────┤ │
172
+ │ │ │
173
+ │ Open browser with URL │ │
174
+ │──────────────────────────────┼─────────────────────────────>│
175
+ │ │ │
176
+ │ │ GET /callback?code=xxx │
177
+ │ │<─────────────────────────────┤
178
+ │ │ │
179
+ │ │ POST /oauth/access_token │
180
+ │ │─────────────────────────────>│
181
+ │ │ │
182
+ │ │ access_token │
183
+ │ │<─────────────────────────────┤
184
+ │ │ │
185
+ │ │ Store token in DB │
186
+ │ │ │
187
+ │ Poll: GET /api/auth/github/status │
188
+ │<─────────────────────────────┤ │
189
+ │ │ │
190
+ │ connected: true │ │
191
+ │──────────────────────────────┤ │
192
+ │ │ │
193
+ │ āœ… Success! │ │
194
+ │ │ │
195
+ ```
196
+
197
+ ## Development Tips
198
+
199
+ ### Testing Locally
200
+
201
+ 1. Start backend: `npm run dev`
202
+ 2. Use ngrok for callback URL:
203
+ ```bash
204
+ ngrok http 3001
205
+ ```
206
+ 3. Update GitHub OAuth app callback URL to ngrok URL
207
+ 4. Set `GITHUB_REDIRECT_URI` in `.env` to ngrok URL
208
+
209
+ ### Debugging
210
+
211
+ Enable verbose logging:
212
+ ```bash
213
+ DEBUG=* mexty github-login
214
+ ```
215
+
216
+ Check stored auth data:
217
+ ```bash
218
+ cat ~/.mext/auth.json
219
+ ```
220
+
221
+ ## Troubleshooting
222
+
223
+ ### Token Expired
224
+ If you see "GitHub token expired":
225
+ ```bash
226
+ mexty github-disconnect
227
+ mexty github-login
228
+ ```
229
+
230
+ ### Browser Not Opening
231
+ If the browser doesn't open automatically, copy the URL from the terminal and paste it into your browser.
232
+
233
+ ### Multiple GitHub Accounts
234
+ Each MEXTY user account can connect one GitHub account at a time. To switch:
235
+ ```bash
236
+ mexty github-disconnect
237
+ mexty github-login
238
+ ```
239
+
240
+ ## Future Enhancements
241
+
242
+ - [ ] Support for GitLab and Bitbucket
243
+ - [ ] Fine-grained token permissions
244
+ - [ ] Token refresh mechanism
245
+ - [ ] Multiple GitHub account support per user
246
+ - [ ] Organization-level GitHub integration
247
+
@@ -0,0 +1,2 @@
1
+ export declare function githubDisconnectCommand(): Promise<void>;
2
+ //# sourceMappingURL=github-disconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-disconnect.d.ts","sourceRoot":"","sources":["../../src/commands/github-disconnect.ts"],"names":[],"mappings":"AAoBA,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CA0D7D"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.githubDisconnectCommand = githubDisconnectCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const readline_1 = require("readline");
9
+ const api_1 = require("../utils/api");
10
+ const auth_1 = require("../utils/auth");
11
+ // Simple prompt function
12
+ async function prompt(question) {
13
+ return new Promise((resolve) => {
14
+ const rl = (0, readline_1.createInterface)({
15
+ input: process.stdin,
16
+ output: process.stdout
17
+ });
18
+ rl.question(question, (answer) => {
19
+ rl.close();
20
+ resolve(answer.trim());
21
+ });
22
+ });
23
+ }
24
+ async function githubDisconnectCommand() {
25
+ try {
26
+ // Check authentication first
27
+ (0, auth_1.requireAuthentication)();
28
+ console.log(chalk_1.default.blue('šŸ”“ Disconnect GitHub Account'));
29
+ console.log(chalk_1.default.gray(' Remove GitHub access from your MEXTY account\n'));
30
+ // Check if connected
31
+ try {
32
+ const status = await api_1.apiClient.getGitHubStatus();
33
+ if (!status.connected) {
34
+ console.log(chalk_1.default.yellow('ā„¹ļø GitHub is not connected'));
35
+ console.log(chalk_1.default.gray(' Nothing to disconnect\n'));
36
+ console.log(chalk_1.default.blue('To connect GitHub, run: mexty github-login'));
37
+ return;
38
+ }
39
+ console.log(chalk_1.default.yellow('āš ļø Current GitHub connection:'));
40
+ console.log(chalk_1.default.gray(` Username: ${status.githubUsername}\n`));
41
+ // Confirm disconnection
42
+ const confirm = await prompt('Are you sure you want to disconnect GitHub? (y/N): ');
43
+ if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
44
+ console.log(chalk_1.default.gray('Cancelled'));
45
+ return;
46
+ }
47
+ console.log(chalk_1.default.yellow('\nšŸ”„ Disconnecting GitHub...'));
48
+ // Disconnect
49
+ const result = await api_1.apiClient.disconnectGitHub();
50
+ if (result.success) {
51
+ console.log(chalk_1.default.green(`\nāœ… ${result.message}`));
52
+ console.log(chalk_1.default.gray(' You will no longer be able to clone private repositories'));
53
+ console.log(chalk_1.default.blue('\nTo reconnect, run: mexty github-login'));
54
+ }
55
+ else {
56
+ console.error(chalk_1.default.red(`\nāŒ ${result.message}`));
57
+ process.exit(1);
58
+ }
59
+ }
60
+ catch (error) {
61
+ console.error(chalk_1.default.red(`āŒ Failed to disconnect GitHub: ${error.message}`));
62
+ process.exit(1);
63
+ }
64
+ }
65
+ catch (error) {
66
+ console.error(chalk_1.default.red(`āŒ GitHub disconnect failed: ${error.message}`));
67
+ if (error.response?.status === 401) {
68
+ console.log(chalk_1.default.yellow(' Please login first: mexty login'));
69
+ }
70
+ process.exit(1);
71
+ }
72
+ }
73
+ //# sourceMappingURL=github-disconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-disconnect.js","sourceRoot":"","sources":["../../src/commands/github-disconnect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function githubLoginCommand(): Promise<void>;
2
+ //# sourceMappingURL=github-login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-login.d.ts","sourceRoot":"","sources":["../../src/commands/github-login.ts"],"names":[],"mappings":"AASA,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgGxD"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.githubLoginCommand = githubLoginCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const open_1 = __importDefault(require("open"));
9
+ const api_1 = require("../utils/api");
10
+ const auth_1 = require("../utils/auth");
11
+ async function wait(seconds) {
12
+ return new Promise(resolve => setTimeout(resolve, seconds * 1000));
13
+ }
14
+ async function githubLoginCommand() {
15
+ try {
16
+ // Check authentication first
17
+ (0, auth_1.requireAuthentication)();
18
+ console.log(chalk_1.default.blue('šŸ” GitHub Authentication'));
19
+ console.log(chalk_1.default.gray(' Connecting your GitHub account for private repository access\n'));
20
+ // Check if already connected
21
+ try {
22
+ const status = await api_1.apiClient.getGitHubStatus();
23
+ if (status.connected) {
24
+ console.log(chalk_1.default.green('āœ… GitHub already connected!'));
25
+ console.log(chalk_1.default.gray(` Username: ${status.githubUsername}`));
26
+ console.log(chalk_1.default.gray(` Status: ${status.message}\n`));
27
+ console.log(chalk_1.default.yellow('To disconnect and reconnect, run: mexty github-disconnect'));
28
+ return;
29
+ }
30
+ }
31
+ catch (error) {
32
+ // If status check fails, continue with login
33
+ console.log(chalk_1.default.yellow('āš ļø Could not check GitHub status, proceeding with login...'));
34
+ }
35
+ // Get GitHub OAuth URL
36
+ console.log(chalk_1.default.yellow('šŸ“” Requesting GitHub OAuth URL...'));
37
+ const authData = await api_1.apiClient.getGitHubAuthUrl();
38
+ if (!authData.success || !authData.url) {
39
+ console.error(chalk_1.default.red(`āŒ ${authData.message}`));
40
+ process.exit(1);
41
+ }
42
+ console.log(chalk_1.default.green('āœ… OAuth URL generated'));
43
+ console.log(chalk_1.default.blue('\n🌐 Opening browser for GitHub authentication...'));
44
+ console.log(chalk_1.default.gray(` URL: ${authData.url}\n`));
45
+ // Open browser
46
+ try {
47
+ await (0, open_1.default)(authData.url);
48
+ console.log(chalk_1.default.yellow('šŸ‘† Please authorize MEXTY in your browser'));
49
+ }
50
+ catch (error) {
51
+ console.warn(chalk_1.default.yellow('āš ļø Could not open browser automatically'));
52
+ console.log(chalk_1.default.blue('\nPlease open this URL in your browser:'));
53
+ console.log(chalk_1.default.cyan(authData.url));
54
+ }
55
+ console.log(chalk_1.default.gray('\nā³ Waiting for you to authorize...'));
56
+ console.log(chalk_1.default.gray(' This may take a moment\n'));
57
+ // Poll for connection status
58
+ let connected = false;
59
+ let attempts = 0;
60
+ const maxAttempts = 60; // 2 minutes (2 second intervals)
61
+ while (!connected && attempts < maxAttempts) {
62
+ await wait(2);
63
+ attempts++;
64
+ try {
65
+ const status = await api_1.apiClient.getGitHubStatus();
66
+ if (status.connected) {
67
+ connected = true;
68
+ console.log(chalk_1.default.green('\nšŸŽ‰ GitHub connected successfully!'));
69
+ console.log(chalk_1.default.gray(` Username: ${status.githubUsername}`));
70
+ console.log(chalk_1.default.gray(` Status: ${status.message}\n`));
71
+ console.log(chalk_1.default.blue('You can now clone private block repositories!'));
72
+ break;
73
+ }
74
+ }
75
+ catch (error) {
76
+ // Continue polling
77
+ }
78
+ // Show progress indicator every 10 attempts
79
+ if (attempts % 10 === 0) {
80
+ console.log(chalk_1.default.gray(` Still waiting... (${attempts * 2}s)`));
81
+ }
82
+ }
83
+ if (!connected) {
84
+ console.error(chalk_1.default.red('\nāŒ Authentication timeout'));
85
+ console.log(chalk_1.default.yellow(' Please try again: mexty github-login'));
86
+ process.exit(1);
87
+ }
88
+ }
89
+ catch (error) {
90
+ console.error(chalk_1.default.red(`āŒ GitHub login failed: ${error.message}`));
91
+ if (error.response?.status === 401) {
92
+ console.log(chalk_1.default.yellow(' Please login first: mexty login'));
93
+ }
94
+ else if (error.response?.status === 500) {
95
+ console.log(chalk_1.default.yellow(' GitHub OAuth may not be configured on the server'));
96
+ }
97
+ process.exit(1);
98
+ }
99
+ }
100
+ //# sourceMappingURL=github-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-login.js","sourceRoot":"","sources":["../../src/commands/github-login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function updateGitUrlCommand(blockId?: string, gitUrl?: string, reset?: boolean): Promise<void>;
2
+ //# sourceMappingURL=update-git-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-git-url.d.ts","sourceRoot":"","sources":["../../src/commands/update-git-url.ts"],"names":[],"mappings":"AA0CA,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,iBA+H3F"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.updateGitUrlCommand = updateGitUrlCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const api_1 = require("../utils/api");
9
+ const auth_1 = require("../utils/auth");
10
+ const readline_1 = require("readline");
11
+ // Simple prompt function
12
+ async function prompt(question, defaultValue) {
13
+ return new Promise((resolve) => {
14
+ const rl = (0, readline_1.createInterface)({
15
+ input: process.stdin,
16
+ output: process.stdout,
17
+ });
18
+ const promptText = defaultValue
19
+ ? `${question} (${defaultValue}): `
20
+ : `${question}: `;
21
+ rl.question(promptText, (answer) => {
22
+ rl.close();
23
+ resolve(answer.trim() || defaultValue || "");
24
+ });
25
+ });
26
+ }
27
+ // Simple yes/no prompt function
28
+ async function promptYesNo(question) {
29
+ return new Promise((resolve) => {
30
+ const rl = (0, readline_1.createInterface)({
31
+ input: process.stdin,
32
+ output: process.stdout,
33
+ });
34
+ rl.question(`${question} (y/n): `, (answer) => {
35
+ rl.close();
36
+ resolve(answer.toLowerCase().startsWith("y"));
37
+ });
38
+ });
39
+ }
40
+ async function updateGitUrlCommand(blockId, gitUrl, reset) {
41
+ try {
42
+ // Require authentication
43
+ await (0, auth_1.requireAuthentication)();
44
+ const user = (0, auth_1.getAuthenticatedUser)();
45
+ console.log(chalk_1.default.blue("šŸ”— Update Block Git URL"));
46
+ console.log(chalk_1.default.gray("Update the Git repository URL for a block\n"));
47
+ // Get block ID if not provided
48
+ if (!blockId) {
49
+ blockId = await prompt("Enter block ID");
50
+ if (!blockId) {
51
+ console.error(chalk_1.default.red("āŒ Block ID is required"));
52
+ process.exit(1);
53
+ }
54
+ }
55
+ // Validate block ID format
56
+ if (!/^[a-f0-9]{24}$/.test(blockId)) {
57
+ console.error(chalk_1.default.red("āŒ Invalid block ID format"));
58
+ process.exit(1);
59
+ }
60
+ console.log(chalk_1.default.blue(`šŸ“¦ Block ID: ${blockId}`));
61
+ // Get current block information
62
+ try {
63
+ const block = await api_1.apiClient.getBlock(blockId);
64
+ console.log(chalk_1.default.green(`āœ… Found block: ${block.title}`));
65
+ console.log(chalk_1.default.gray(`Current Git URL: ${block.gitUrl || "Not set"}`));
66
+ // Check if current URL is default
67
+ const isDefaultUrl = block.gitUrl?.startsWith("https://github.com/mext-ai/block-");
68
+ if (isDefaultUrl) {
69
+ console.log(chalk_1.default.yellow("ā„¹ļø Current URL is the default Mext URL"));
70
+ }
71
+ }
72
+ catch (error) {
73
+ console.error(chalk_1.default.red(`āŒ Failed to fetch block: ${error.message}`));
74
+ process.exit(1);
75
+ }
76
+ let newGitUrl;
77
+ let resetToDefault = false;
78
+ // Handle reset option
79
+ if (reset) {
80
+ resetToDefault = true;
81
+ newGitUrl = `https://github.com/mext-ai/block-${blockId}`;
82
+ console.log(chalk_1.default.blue(`šŸ”„ Resetting to default URL: ${newGitUrl}`));
83
+ }
84
+ else if (gitUrl) {
85
+ // Validate provided URL
86
+ const isValidUrl = /^https:\/\/github\.com\/[\w\-\.]+\/[\w\-\.]+(?:\.git)?$/.test(gitUrl);
87
+ if (!isValidUrl) {
88
+ console.error(chalk_1.default.red("āŒ Invalid Git URL format. Please provide a valid GitHub URL."));
89
+ process.exit(1);
90
+ }
91
+ newGitUrl = gitUrl;
92
+ console.log(chalk_1.default.blue(`šŸ”— New Git URL: ${newGitUrl}`));
93
+ }
94
+ else {
95
+ // Interactive mode
96
+ const currentBlock = await api_1.apiClient.getBlock(blockId);
97
+ const currentUrl = currentBlock.gitUrl || "";
98
+ // Ask for new URL
99
+ newGitUrl = await prompt("Enter new Git URL", currentUrl);
100
+ if (!newGitUrl) {
101
+ console.error(chalk_1.default.red("āŒ Git URL is required"));
102
+ process.exit(1);
103
+ }
104
+ // Validate URL format
105
+ const isValidUrl = /^https:\/\/github\.com\/[\w\-\.]+\/[\w\-\.]+(?:\.git)?$/.test(newGitUrl);
106
+ if (!isValidUrl) {
107
+ console.error(chalk_1.default.red("āŒ Invalid Git URL format. Please provide a valid GitHub URL."));
108
+ process.exit(1);
109
+ }
110
+ // Check if user wants to reset to default
111
+ if (!newGitUrl.startsWith("https://github.com/mext-ai/block-")) {
112
+ const shouldReset = await promptYesNo("This is not the default Mext URL. Do you want to reset to default instead?");
113
+ if (shouldReset) {
114
+ resetToDefault = true;
115
+ newGitUrl = `https://github.com/mext-ai/block-${blockId}`;
116
+ console.log(chalk_1.default.blue(`šŸ”„ Resetting to default URL: ${newGitUrl}`));
117
+ }
118
+ }
119
+ }
120
+ // Confirm the update
121
+ console.log(chalk_1.default.yellow(`\nāš ļø About to update Git URL to: ${newGitUrl}`));
122
+ const confirmed = await promptYesNo("Do you want to proceed?");
123
+ if (!confirmed) {
124
+ console.log(chalk_1.default.gray("āŒ Update cancelled"));
125
+ process.exit(0);
126
+ }
127
+ // Update the Git URL
128
+ console.log(chalk_1.default.blue("šŸ”„ Updating Git URL..."));
129
+ try {
130
+ const result = await api_1.apiClient.updateBlockGitUrl(blockId, newGitUrl, resetToDefault);
131
+ console.log(chalk_1.default.green("āœ… Git URL updated successfully!"));
132
+ console.log(chalk_1.default.gray(`New URL: ${result.gitUrl}`));
133
+ if (result.resetToDefault) {
134
+ console.log(chalk_1.default.yellow("šŸ”„ URL was reset to default"));
135
+ }
136
+ }
137
+ catch (error) {
138
+ console.error(chalk_1.default.red(`āŒ Failed to update Git URL: ${error.message}`));
139
+ if (error.response?.status === 403) {
140
+ console.error(chalk_1.default.red("Access denied. You can only update blocks you own."));
141
+ }
142
+ else if (error.response?.status === 404) {
143
+ console.error(chalk_1.default.red("Block not found."));
144
+ }
145
+ process.exit(1);
146
+ }
147
+ }
148
+ catch (error) {
149
+ console.error(chalk_1.default.red(`āŒ Error: ${error.message}`));
150
+ process.exit(1);
151
+ }
152
+ }
153
+ //# sourceMappingURL=update-git-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-git-url.js","sourceRoot":"","sources":["../../src/commands/update-git-url.ts"],"names":[],"mappings":"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"}