@myapihq/cli 1.0.24 → 1.0.27

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.
@@ -1,2 +1,4 @@
1
1
  export declare function checkForUpdate(currentVersion: string): Promise<void>;
2
2
  export declare function update(): Promise<void>;
3
+ export declare function latestVersion(): Promise<string | null>;
4
+ export declare function isNewer(latest: string, current: string): boolean;
@@ -5,7 +5,7 @@ import { installSkills } from './setup.js';
5
5
  const REGISTRY_URL = 'https://registry.npmjs.org/@myapihq/cli/latest';
6
6
  const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
7
7
  // checkForUpdate runs silently in the background on every command.
8
- // Prints a one-liner if a newer version is available.
8
+ // Auto-installs if a newer version is available.
9
9
  export async function checkForUpdate(currentVersion) {
10
10
  const config = loadConfig();
11
11
  const now = Date.now();
@@ -21,32 +21,53 @@ export async function checkForUpdate(currentVersion) {
21
21
  if (config) {
22
22
  saveConfig({ ...config, last_update_check: now });
23
23
  }
24
- if (latest && latest !== currentVersion && isNewer(latest, currentVersion)) {
25
- // Print after a tiny delay so it appears below command output.
26
- setTimeout(() => {
27
- info(`\n› Update available: ${currentVersion} → ${latest} · run: myapi update`);
28
- }, 50);
24
+ if (latest && isNewer(latest, currentVersion)) {
25
+ info(`\n› New version available (${currentVersion} ${latest}) installing…`);
26
+ execSync('npm install -g @myapihq/cli', { stdio: 'pipe' });
27
+ await installSkills();
28
+ success(`› MyAPI CLI updated to ${latest}. Re-run your command.\n`);
29
+ process.exit(0);
29
30
  }
30
31
  }
31
32
  catch {
32
- // Network errors are silently ignored.
33
+ // Network or install errors are silently ignored.
33
34
  }
34
35
  }
35
- // myapi update — installs the latest CLI version then re-installs skills.
36
+ // myapi update — explicit update, same logic as auto-update.
36
37
  export async function update() {
37
- info('› Updating MyAPI CLI…');
38
+ info('› Checking for updates…');
39
+ try {
40
+ const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(5000) });
41
+ if (!res.ok)
42
+ throw new Error(`registry returned ${res.status}`);
43
+ const data = await res.json();
44
+ info(`› Installing @myapihq/cli@${data.version}…`);
45
+ }
46
+ catch { /* proceed anyway */ }
38
47
  try {
39
48
  execSync('npm install -g @myapihq/cli', { stdio: 'inherit' });
40
49
  }
41
50
  catch {
42
- // npm printed its own error; just exit.
43
51
  process.exit(1);
44
52
  }
45
53
  info('› Refreshing skills…');
46
54
  await installSkills();
47
55
  success('› Up to date.');
48
56
  }
49
- function isNewer(latest, current) {
57
+ // latestVersion fetches the current published version for --version display.
58
+ export async function latestVersion() {
59
+ try {
60
+ const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(3000) });
61
+ if (!res.ok)
62
+ return null;
63
+ const data = await res.json();
64
+ return data.version ?? null;
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ export function isNewer(latest, current) {
50
71
  const toNum = (v) => v.split('.').map(Number);
51
72
  const [lMaj, lMin, lPat] = toNum(latest);
52
73
  const [cMaj, cMin, cPat] = toNum(current);
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  // AUTO-GENERATED by scripts/generate-indexes.js — do not edit manually
3
3
  import { parseArgs } from './utils.js';
4
4
  import { error, info } from './output.js';
5
+ import { loadConfig } from './config.js';
5
6
  import { MyApiError } from '@myapihq/sdk';
6
- import updateNotifier from 'update-notifier';
7
7
  import * as fs from 'fs';
8
8
  const pkgPath = new URL('../package.json', import.meta.url);
9
9
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
@@ -12,15 +12,28 @@ import * as billingCmd from './commands/billing.js';
12
12
  import * as orgCmd from './commands/org.js';
13
13
  import * as setupCmd from './commands/setup.js';
14
14
  import * as configCmd from './commands/config.js';
15
+ import * as authCmd from './commands/auth.js';
16
+ import * as updateCmd from './commands/update.js';
15
17
  import * as domainCmd from './commands/domain.js';
16
18
  import * as funnelCmd from './commands/funnel.js';
17
19
  async function main() {
18
- try {
19
- updateNotifier({ pkg }).notify();
20
- }
21
- catch (e) { }
20
+ // Fire-and-forget auto-update check — never blocks the command.
21
+ updateCmd.checkForUpdate(pkg.version).catch(() => { });
22
22
  const { args, flags } = parseArgs(process.argv.slice(2));
23
+ if (flags.version || flags.v) {
24
+ const latest = await updateCmd.latestVersion();
25
+ const updateNote = latest && updateCmd.isNewer(latest, pkg.version)
26
+ ? ` (update available: ${latest})`
27
+ : '';
28
+ info(`myapi ${pkg.version}${updateNote}`);
29
+ process.exit(0);
30
+ }
23
31
  if (args.length === 0) {
32
+ const config = loadConfig();
33
+ if (!config?.api_key) {
34
+ info('No account found. Run: myapi setup');
35
+ process.exit(0);
36
+ }
24
37
  printHelp();
25
38
  process.exit(0);
26
39
  }
@@ -28,12 +41,19 @@ async function main() {
28
41
  try {
29
42
  switch (command) {
30
43
  case 'setup':
31
- if (flags.help) {
32
- info('Usage: myapi setup\n\nSetup CLI credentials and view integration instructions');
33
- break;
34
- }
35
44
  await setupCmd.setup();
36
45
  break;
46
+ case 'auth':
47
+ if (subcommand === 'signup')
48
+ await authCmd.signup();
49
+ else if (subcommand === 'whoami')
50
+ await authCmd.whoami();
51
+ else
52
+ info('Usage: myapi auth <signup|whoami>');
53
+ break;
54
+ case 'update':
55
+ await updateCmd.update();
56
+ break;
37
57
  case 'keys':
38
58
  if (!subcommand || (flags.help && !subcommand)) {
39
59
  info('Usage: myapi keys <subcommand>\n\nSubcommands:\n list List your API keys\n create Create a new API key\n revoke Revoke an API key (e.g. myapi keys revoke <id>)');
@@ -110,23 +130,24 @@ function printHelp() {
110
130
  info(`myapi - MyAPI command-line interface
111
131
 
112
132
  Usage: myapi <command> [subcommand] [args]
133
+ myapi --version
113
134
 
114
135
  Commands:
115
136
  keys Manage API keys
116
137
  billing Check balance and manage billing
117
138
  org Manage organizations
118
- setup Setup CLI credentials and view integration instructions
139
+ setup Configure credentials and install skills
119
140
  config Manage CLI defaults like org_id and domain
141
+ auth Manage authentication (signup, whoami)
142
+ update Update CLI and skills to the latest version
120
143
  domain Manage domain configurations
121
144
  funnel Manage headless funnels and pages
122
145
 
123
146
  Run "myapi <command> --help" for subcommand help.
124
147
 
125
148
  Quick start:
126
- myapi org create --name "Acme Inc"
127
- myapi domain register acme.com --org <org_id>
128
- myapi domain assign acme.com --org <org_id> --target <org_id>
129
- myapi funnel create --org <org_id>
130
- echo '<h1>Hello!</h1>' | myapi funnel push <funnel_id> / --org <org_id>`);
149
+ myapi setup
150
+ myapi funnel create
151
+ echo '<h1>Hello!</h1>' | myapi funnel push <funnel_id> /`);
131
152
  }
132
153
  main().catch(err => { error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err))); });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
- "version": "1.0.24",
3
+ "version": "1.0.27",
4
4
  "description": "MyAPI command-line interface",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -7,7 +7,7 @@ const REGISTRY_URL = 'https://registry.npmjs.org/@myapihq/cli/latest';
7
7
  const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
8
8
 
9
9
  // checkForUpdate runs silently in the background on every command.
10
- // Prints a one-liner if a newer version is available.
10
+ // Auto-installs if a newer version is available.
11
11
  export async function checkForUpdate(currentVersion: string): Promise<void> {
12
12
  const config = loadConfig();
13
13
  const now = Date.now();
@@ -26,24 +26,31 @@ export async function checkForUpdate(currentVersion: string): Promise<void> {
26
26
  saveConfig({ ...config, last_update_check: now });
27
27
  }
28
28
 
29
- if (latest && latest !== currentVersion && isNewer(latest, currentVersion)) {
30
- // Print after a tiny delay so it appears below command output.
31
- setTimeout(() => {
32
- info(`\n› Update available: ${currentVersion} → ${latest} · run: myapi update`);
33
- }, 50);
29
+ if (latest && isNewer(latest, currentVersion)) {
30
+ info(`\n› New version available (${currentVersion} ${latest}) installing…`);
31
+ execSync('npm install -g @myapihq/cli', { stdio: 'pipe' });
32
+ await installSkills();
33
+ success(`› MyAPI CLI updated to ${latest}. Re-run your command.\n`);
34
+ process.exit(0);
34
35
  }
35
36
  } catch {
36
- // Network errors are silently ignored.
37
+ // Network or install errors are silently ignored.
37
38
  }
38
39
  }
39
40
 
40
- // myapi update — installs the latest CLI version then re-installs skills.
41
+ // myapi update — explicit update, same logic as auto-update.
41
42
  export async function update(): Promise<void> {
42
- info('› Updating MyAPI CLI…');
43
+ info('› Checking for updates…');
44
+ try {
45
+ const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(5000) });
46
+ if (!res.ok) throw new Error(`registry returned ${res.status}`);
47
+ const data = await res.json() as { version?: string };
48
+ info(`› Installing @myapihq/cli@${data.version}…`);
49
+ } catch { /* proceed anyway */ }
50
+
43
51
  try {
44
52
  execSync('npm install -g @myapihq/cli', { stdio: 'inherit' });
45
53
  } catch {
46
- // npm printed its own error; just exit.
47
54
  process.exit(1);
48
55
  }
49
56
  info('› Refreshing skills…');
@@ -51,7 +58,19 @@ export async function update(): Promise<void> {
51
58
  success('› Up to date.');
52
59
  }
53
60
 
54
- function isNewer(latest: string, current: string): boolean {
61
+ // latestVersion fetches the current published version for --version display.
62
+ export async function latestVersion(): Promise<string | null> {
63
+ try {
64
+ const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(3000) });
65
+ if (!res.ok) return null;
66
+ const data = await res.json() as { version?: string };
67
+ return data.version ?? null;
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+
73
+ export function isNewer(latest: string, current: string): boolean {
55
74
  const toNum = (v: string) => v.split('.').map(Number);
56
75
  const [lMaj, lMin, lPat] = toNum(latest);
57
76
  const [cMaj, cMin, cPat] = toNum(current);
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@ import { parseArgs } from './utils.js';
4
4
  import { error, info, success } from './output.js';
5
5
  import { loadConfig } from './config.js';
6
6
  import { MyApiError } from '@myapihq/sdk';
7
- import updateNotifier from 'update-notifier';
8
7
  import * as fs from 'fs';
9
8
 
10
9
  const pkgPath = new URL('../package.json', import.meta.url);
@@ -14,26 +13,50 @@ import * as billingCmd from './commands/billing.js';
14
13
  import * as orgCmd from './commands/org.js';
15
14
  import * as setupCmd from './commands/setup.js';
16
15
  import * as configCmd from './commands/config.js';
16
+ import * as authCmd from './commands/auth.js';
17
+ import * as updateCmd from './commands/update.js';
17
18
  import * as domainCmd from './commands/domain.js';
18
19
  import * as funnelCmd from './commands/funnel.js';
19
20
 
20
21
  async function main() {
21
- try {
22
- updateNotifier({ pkg }).notify();
23
- } catch(e) {}
22
+ // Fire-and-forget auto-update check — never blocks the command.
23
+ updateCmd.checkForUpdate(pkg.version).catch(() => {});
24
24
 
25
25
  const { args, flags } = parseArgs(process.argv.slice(2));
26
- if (args.length === 0) { printHelp(); process.exit(0); }
26
+
27
+ if (flags.version || flags.v) {
28
+ const latest = await updateCmd.latestVersion();
29
+ const updateNote = latest && updateCmd.isNewer(latest, pkg.version)
30
+ ? ` (update available: ${latest})`
31
+ : '';
32
+ info(`myapi ${pkg.version}${updateNote}`);
33
+ process.exit(0);
34
+ }
35
+
36
+ if (args.length === 0) {
37
+ const config = loadConfig();
38
+ if (!config?.api_key) {
39
+ info('No account found. Run: myapi setup');
40
+ process.exit(0);
41
+ }
42
+ printHelp();
43
+ process.exit(0);
44
+ }
45
+
27
46
  const [command, subcommand, ...restArgs] = args;
28
47
  try {
29
48
  switch (command) {
30
49
  case 'setup':
31
- if (flags.help) {
32
- info('Usage: myapi setup\n\nSetup CLI credentials and view integration instructions');
33
- break;
34
- }
35
50
  await setupCmd.setup();
36
51
  break;
52
+ case 'auth':
53
+ if (subcommand === 'signup') await authCmd.signup();
54
+ else if (subcommand === 'whoami') await authCmd.whoami();
55
+ else info('Usage: myapi auth <signup|whoami>');
56
+ break;
57
+ case 'update':
58
+ await updateCmd.update();
59
+ break;
37
60
  case 'keys':
38
61
  if (!subcommand || (flags.help && !subcommand)) {
39
62
  info('Usage: myapi keys <subcommand>\n\nSubcommands:\n list List your API keys\n create Create a new API key\n revoke Revoke an API key (e.g. myapi keys revoke <id>)');
@@ -93,24 +116,25 @@ function printHelp() {
93
116
  info(`myapi - MyAPI command-line interface
94
117
 
95
118
  Usage: myapi <command> [subcommand] [args]
119
+ myapi --version
96
120
 
97
121
  Commands:
98
122
  keys Manage API keys
99
123
  billing Check balance and manage billing
100
124
  org Manage organizations
101
- setup Setup CLI credentials and view integration instructions
125
+ setup Configure credentials and install skills
102
126
  config Manage CLI defaults like org_id and domain
127
+ auth Manage authentication (signup, whoami)
128
+ update Update CLI and skills to the latest version
103
129
  domain Manage domain configurations
104
130
  funnel Manage headless funnels and pages
105
131
 
106
132
  Run "myapi <command> --help" for subcommand help.
107
133
 
108
134
  Quick start:
109
- myapi org create --name "Acme Inc"
110
- myapi domain register acme.com --org <org_id>
111
- myapi domain assign acme.com --org <org_id> --target <org_id>
112
- myapi funnel create --org <org_id>
113
- echo '<h1>Hello!</h1>' | myapi funnel push <funnel_id> / --org <org_id>`);
135
+ myapi setup
136
+ myapi funnel create
137
+ echo '<h1>Hello!</h1>' | myapi funnel push <funnel_id> /`);
114
138
  }
115
139
 
116
140
  main().catch(err => { error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err))); });