@l4yercak3/cli 1.1.8 → 1.1.10
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/package.json
CHANGED
|
@@ -7,8 +7,8 @@ const crypto = require('crypto');
|
|
|
7
7
|
const fetch = require('node-fetch');
|
|
8
8
|
const configManager = require('../config/config-manager');
|
|
9
9
|
|
|
10
|
-
// API Base URL - All CLI API endpoints go through Convex HTTP
|
|
11
|
-
const API_BASE_URL = 'https://
|
|
10
|
+
// API Base URL - All CLI API endpoints go through Convex HTTP (Production)
|
|
11
|
+
const API_BASE_URL = 'https://agreeable-lion-828.convex.site';
|
|
12
12
|
|
|
13
13
|
// App URL - Only used for browser login page (Next.js serves the OAuth UI)
|
|
14
14
|
const APP_URL = 'https://app.l4yercak3.com';
|
package/src/commands/spread.js
CHANGED
|
@@ -220,79 +220,18 @@ async function handleSpread() {
|
|
|
220
220
|
console.log(chalk.gray(' Could not check existing keys, attempting to generate...'));
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
if (existingKeys && existingKeys.keys && existingKeys.keys.length > 0) {
|
|
224
|
-
//
|
|
225
|
-
console.log(chalk.yellow(` ⚠️
|
|
226
|
-
|
|
223
|
+
if (existingKeys && existingKeys.keys && existingKeys.keys.length > 0 && !existingKeys.canCreateMore) {
|
|
224
|
+
// At API key limit - inform user and exit
|
|
225
|
+
console.log(chalk.yellow(` ⚠️ You've reached your API key limit (${existingKeys.keys.length} key(s))`));
|
|
227
226
|
if (existingKeys.limitDescription) {
|
|
228
|
-
console.log(chalk.gray(`
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Show existing keys (masked)
|
|
232
|
-
existingKeys.keys.forEach((key, i) => {
|
|
233
|
-
const maskedKey = key.key ? `${key.key.substring(0, 10)}...` : key.name || `Key ${i + 1}`;
|
|
234
|
-
console.log(chalk.gray(` • ${key.name || 'Unnamed'}: ${maskedKey}`));
|
|
235
|
-
});
|
|
236
|
-
console.log('');
|
|
237
|
-
|
|
238
|
-
if (!existingKeys.canCreateMore) {
|
|
239
|
-
// At limit - offer to use existing key
|
|
240
|
-
const { useExisting } = await inquirer.prompt([
|
|
241
|
-
{
|
|
242
|
-
type: 'confirm',
|
|
243
|
-
name: 'useExisting',
|
|
244
|
-
message: 'You\'ve reached your API key limit. Use an existing key from your .env.local file?',
|
|
245
|
-
default: true,
|
|
246
|
-
},
|
|
247
|
-
]);
|
|
248
|
-
|
|
249
|
-
if (useExisting) {
|
|
250
|
-
const { manualKey } = await inquirer.prompt([
|
|
251
|
-
{
|
|
252
|
-
type: 'input',
|
|
253
|
-
name: 'manualKey',
|
|
254
|
-
message: 'Enter your existing API key:',
|
|
255
|
-
validate: (input) => input.trim().length > 0 || 'API key is required',
|
|
256
|
-
},
|
|
257
|
-
]);
|
|
258
|
-
apiKey = manualKey.trim();
|
|
259
|
-
console.log(chalk.green(` ✅ Using provided API key\n`));
|
|
260
|
-
} else {
|
|
261
|
-
console.log(chalk.yellow('\n ⚠️ To generate more API keys, upgrade your plan at https://app.l4yercak3.com/settings/billing\n'));
|
|
262
|
-
process.exit(0);
|
|
263
|
-
}
|
|
264
|
-
} else {
|
|
265
|
-
// Can create more - ask what to do
|
|
266
|
-
const { keyAction } = await inquirer.prompt([
|
|
267
|
-
{
|
|
268
|
-
type: 'list',
|
|
269
|
-
name: 'keyAction',
|
|
270
|
-
message: 'What would you like to do?',
|
|
271
|
-
choices: [
|
|
272
|
-
{ name: 'Generate a new API key', value: 'generate' },
|
|
273
|
-
{ name: 'Enter an existing API key', value: 'existing' },
|
|
274
|
-
],
|
|
275
|
-
},
|
|
276
|
-
]);
|
|
277
|
-
|
|
278
|
-
if (keyAction === 'existing') {
|
|
279
|
-
const { manualKey } = await inquirer.prompt([
|
|
280
|
-
{
|
|
281
|
-
type: 'input',
|
|
282
|
-
name: 'manualKey',
|
|
283
|
-
message: 'Enter your existing API key:',
|
|
284
|
-
validate: (input) => input.trim().length > 0 || 'API key is required',
|
|
285
|
-
},
|
|
286
|
-
]);
|
|
287
|
-
apiKey = manualKey.trim();
|
|
288
|
-
console.log(chalk.green(` ✅ Using provided API key\n`));
|
|
289
|
-
} else {
|
|
290
|
-
// Generate new key
|
|
291
|
-
apiKey = await generateNewApiKey(organizationId);
|
|
292
|
-
}
|
|
227
|
+
console.log(chalk.gray(` ${existingKeys.limitDescription}`));
|
|
293
228
|
}
|
|
229
|
+
console.log(chalk.cyan('\n To continue, either:'));
|
|
230
|
+
console.log(chalk.gray(' • Delete an existing key at https://app.l4yercak3.com/settings/api-keys'));
|
|
231
|
+
console.log(chalk.gray(' • Upgrade your plan at https://app.l4yercak3.com/settings/billing\n'));
|
|
232
|
+
process.exit(0);
|
|
294
233
|
} else {
|
|
295
|
-
//
|
|
234
|
+
// Generate new key (either no keys exist or can create more)
|
|
296
235
|
apiKey = await generateNewApiKey(organizationId);
|
|
297
236
|
}
|
|
298
237
|
} catch (error) {
|
|
@@ -302,64 +241,10 @@ async function handleSpread() {
|
|
|
302
241
|
if (error.suggestion) {
|
|
303
242
|
console.log(chalk.gray(` ${error.suggestion}`));
|
|
304
243
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
console.log(chalk.gray(` ${error.upgradeUrl}\n`));
|
|
310
|
-
|
|
311
|
-
const { action } = await inquirer.prompt([
|
|
312
|
-
{
|
|
313
|
-
type: 'list',
|
|
314
|
-
name: 'action',
|
|
315
|
-
message: 'What would you like to do?',
|
|
316
|
-
choices: [
|
|
317
|
-
{ name: 'Open upgrade page in browser', value: 'upgrade' },
|
|
318
|
-
{ name: 'Enter an existing API key', value: 'existing' },
|
|
319
|
-
{ name: 'Exit', value: 'exit' },
|
|
320
|
-
],
|
|
321
|
-
},
|
|
322
|
-
]);
|
|
323
|
-
|
|
324
|
-
if (action === 'upgrade') {
|
|
325
|
-
const { default: open } = require('open');
|
|
326
|
-
console.log(chalk.gray(' Opening browser...'));
|
|
327
|
-
await open(error.upgradeUrl);
|
|
328
|
-
console.log(chalk.gray('\n After upgrading, run "l4yercak3 spread" again.\n'));
|
|
329
|
-
process.exit(0);
|
|
330
|
-
} else if (action === 'existing') {
|
|
331
|
-
const { manualKey } = await inquirer.prompt([
|
|
332
|
-
{
|
|
333
|
-
type: 'input',
|
|
334
|
-
name: 'manualKey',
|
|
335
|
-
message: 'Enter your existing API key:',
|
|
336
|
-
validate: (input) => input.trim().length > 0 || 'API key is required',
|
|
337
|
-
},
|
|
338
|
-
]);
|
|
339
|
-
apiKey = manualKey.trim();
|
|
340
|
-
console.log(chalk.green(` ✅ Using provided API key\n`));
|
|
341
|
-
} else {
|
|
342
|
-
process.exit(0);
|
|
343
|
-
}
|
|
344
|
-
} else {
|
|
345
|
-
// No upgrade URL - fallback to manual entry
|
|
346
|
-
console.log(chalk.gray('\n You can enter an existing API key or upgrade your plan.\n'));
|
|
347
|
-
|
|
348
|
-
const { manualKey } = await inquirer.prompt([
|
|
349
|
-
{
|
|
350
|
-
type: 'input',
|
|
351
|
-
name: 'manualKey',
|
|
352
|
-
message: 'Enter your existing API key (or press Enter to exit):',
|
|
353
|
-
},
|
|
354
|
-
]);
|
|
355
|
-
|
|
356
|
-
if (manualKey.trim()) {
|
|
357
|
-
apiKey = manualKey.trim();
|
|
358
|
-
console.log(chalk.green(` ✅ Using provided API key\n`));
|
|
359
|
-
} else {
|
|
360
|
-
process.exit(0);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
244
|
+
console.log(chalk.cyan('\n To continue, either:'));
|
|
245
|
+
console.log(chalk.gray(' • Delete an existing key at https://app.l4yercak3.com/settings/api-keys'));
|
|
246
|
+
console.log(chalk.gray(' • Upgrade your plan at https://app.l4yercak3.com/settings/billing\n'));
|
|
247
|
+
process.exit(0);
|
|
363
248
|
} else if (error.code === 'SESSION_EXPIRED') {
|
|
364
249
|
console.log(chalk.red(`\n ❌ Session expired. Please run "l4yercak3 login" again.\n`));
|
|
365
250
|
process.exit(1);
|
|
@@ -412,7 +297,7 @@ async function handleSpread() {
|
|
|
412
297
|
}
|
|
413
298
|
|
|
414
299
|
// Step 6: Backend URL (fixed to Convex HTTP endpoint)
|
|
415
|
-
const backendUrl = 'https://
|
|
300
|
+
const backendUrl = 'https://agreeable-lion-828.convex.site';
|
|
416
301
|
|
|
417
302
|
// Step 7: Production domain (for OAuth redirect URIs)
|
|
418
303
|
let productionDomain = null;
|
|
@@ -33,7 +33,7 @@ class ConfigManager {
|
|
|
33
33
|
session: null,
|
|
34
34
|
organizations: [],
|
|
35
35
|
settings: {
|
|
36
|
-
backendUrl: process.env.L4YERCAK3_BACKEND_URL || 'https://
|
|
36
|
+
backendUrl: process.env.L4YERCAK3_BACKEND_URL || 'https://agreeable-lion-828.convex.site',
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
39
|
}
|
|
@@ -119,7 +119,7 @@ class ConfigManager {
|
|
|
119
119
|
*/
|
|
120
120
|
getBackendUrl() {
|
|
121
121
|
const config = this.getConfig();
|
|
122
|
-
return config.settings?.backendUrl || process.env.L4YERCAK3_BACKEND_URL || 'https://
|
|
122
|
+
return config.settings?.backendUrl || process.env.L4YERCAK3_BACKEND_URL || 'https://agreeable-lion-828.convex.site';
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
@@ -15,7 +15,7 @@ configManager.getBackendUrl.mockReturnValue('https://backend.test.com');
|
|
|
15
15
|
const BackendClient = require('../src/api/backend-client');
|
|
16
16
|
|
|
17
17
|
// API Base URL for all CLI endpoints (Convex HTTP)
|
|
18
|
-
const API_BASE_URL = 'https://
|
|
18
|
+
const API_BASE_URL = 'https://agreeable-lion-828.convex.site';
|
|
19
19
|
// App URL only for browser login
|
|
20
20
|
const APP_URL = 'https://app.l4yercak3.com';
|
|
21
21
|
|
|
@@ -461,7 +461,7 @@ describe('BackendClient', () => {
|
|
|
461
461
|
|
|
462
462
|
// Should use Convex URL, not main backend
|
|
463
463
|
expect(fetch).toHaveBeenCalledWith(
|
|
464
|
-
'https://
|
|
464
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications/by-path?organizationId=org-123&hash=hash123',
|
|
465
465
|
expect.objectContaining({ method: 'GET' })
|
|
466
466
|
);
|
|
467
467
|
expect(result.found).toBe(true);
|
|
@@ -522,7 +522,7 @@ describe('BackendClient', () => {
|
|
|
522
522
|
|
|
523
523
|
// Should use Convex URL, not main backend
|
|
524
524
|
expect(fetch).toHaveBeenCalledWith(
|
|
525
|
-
'https://
|
|
525
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications',
|
|
526
526
|
expect.objectContaining({
|
|
527
527
|
method: 'POST',
|
|
528
528
|
body: JSON.stringify(registrationData),
|
|
@@ -552,7 +552,7 @@ describe('BackendClient', () => {
|
|
|
552
552
|
const result = await BackendClient.updateApplication('app-123', updates);
|
|
553
553
|
|
|
554
554
|
expect(fetch).toHaveBeenCalledWith(
|
|
555
|
-
'https://
|
|
555
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications/app-123',
|
|
556
556
|
expect.objectContaining({
|
|
557
557
|
method: 'PATCH',
|
|
558
558
|
body: JSON.stringify(updates),
|
|
@@ -577,7 +577,7 @@ describe('BackendClient', () => {
|
|
|
577
577
|
const result = await BackendClient.getApplication('app-123');
|
|
578
578
|
|
|
579
579
|
expect(fetch).toHaveBeenCalledWith(
|
|
580
|
-
'https://
|
|
580
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications/app-123',
|
|
581
581
|
expect.objectContaining({ method: 'GET' })
|
|
582
582
|
);
|
|
583
583
|
expect(result.id).toBe('app-123');
|
|
@@ -601,7 +601,7 @@ describe('BackendClient', () => {
|
|
|
601
601
|
const result = await BackendClient.listApplications('org-123');
|
|
602
602
|
|
|
603
603
|
expect(fetch).toHaveBeenCalledWith(
|
|
604
|
-
'https://
|
|
604
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications?organizationId=org-123',
|
|
605
605
|
expect.objectContaining({ method: 'GET' })
|
|
606
606
|
);
|
|
607
607
|
expect(result.applications).toHaveLength(2);
|
|
@@ -627,7 +627,7 @@ describe('BackendClient', () => {
|
|
|
627
627
|
const result = await BackendClient.syncApplication('app-123', syncData);
|
|
628
628
|
|
|
629
629
|
expect(fetch).toHaveBeenCalledWith(
|
|
630
|
-
'https://
|
|
630
|
+
'https://agreeable-lion-828.convex.site/api/v1/cli/applications/app-123/sync',
|
|
631
631
|
expect.objectContaining({
|
|
632
632
|
method: 'POST',
|
|
633
633
|
body: JSON.stringify(syncData),
|
|
@@ -36,7 +36,7 @@ describe('ConfigManager', () => {
|
|
|
36
36
|
session: null,
|
|
37
37
|
organizations: [],
|
|
38
38
|
settings: {
|
|
39
|
-
backendUrl: 'https://
|
|
39
|
+
backendUrl: 'https://agreeable-lion-828.convex.site',
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
42
|
});
|
|
@@ -204,7 +204,7 @@ describe('ConfigManager', () => {
|
|
|
204
204
|
|
|
205
205
|
const url = ConfigManager.getBackendUrl();
|
|
206
206
|
|
|
207
|
-
expect(url).toBe('https://
|
|
207
|
+
expect(url).toBe('https://agreeable-lion-828.convex.site');
|
|
208
208
|
});
|
|
209
209
|
|
|
210
210
|
it('returns configured URL from settings', () => {
|