@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@l4yercak3/cli",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "description": "Icing on the L4yercak3 - The sweet finishing touch for your Layer Cake integration",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -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://aromatic-akita-723.convex.site';
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';
@@ -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
- // Organization has existing keys
225
- console.log(chalk.yellow(` ⚠️ Found ${existingKeys.keys.length} existing API key(s)`));
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(` Limit: ${existingKeys.limitDescription}`));
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
- // No existing keys - generate one
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
- // Show upgrade option if available
307
- if (error.upgradeUrl) {
308
- console.log(chalk.cyan(`\n 🚀 Upgrade your plan to get more API keys:`));
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://aromatic-akita-723.convex.site';
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://aromatic-akita-723.convex.site',
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://aromatic-akita-723.convex.site';
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://aromatic-akita-723.convex.site';
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://aromatic-akita-723.convex.site/api/v1/cli/applications/by-path?organizationId=org-123&hash=hash123',
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://aromatic-akita-723.convex.site/api/v1/cli/applications',
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://aromatic-akita-723.convex.site/api/v1/cli/applications/app-123',
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://aromatic-akita-723.convex.site/api/v1/cli/applications/app-123',
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://aromatic-akita-723.convex.site/api/v1/cli/applications?organizationId=org-123',
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://aromatic-akita-723.convex.site/api/v1/cli/applications/app-123/sync',
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://aromatic-akita-723.convex.site',
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://aromatic-akita-723.convex.site');
207
+ expect(url).toBe('https://agreeable-lion-828.convex.site');
208
208
  });
209
209
 
210
210
  it('returns configured URL from settings', () => {