nexusapp-cli 3.0.0 → 3.1.1

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 (81) hide show
  1. package/dist/client.d.ts +6 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +63 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/commands/auth.d.ts +3 -0
  6. package/dist/commands/auth.d.ts.map +1 -0
  7. package/dist/commands/auth.js +178 -0
  8. package/dist/commands/auth.js.map +1 -0
  9. package/dist/commands/bucket.d.ts +3 -0
  10. package/dist/commands/bucket.d.ts.map +1 -0
  11. package/dist/commands/bucket.js +354 -0
  12. package/dist/commands/bucket.js.map +1 -0
  13. package/dist/commands/database.d.ts +3 -0
  14. package/dist/commands/database.d.ts.map +1 -0
  15. package/dist/commands/database.js +350 -0
  16. package/dist/commands/database.js.map +1 -0
  17. package/dist/commands/deploy.d.ts +3 -0
  18. package/dist/commands/deploy.d.ts.map +1 -0
  19. package/dist/commands/deploy.js +1009 -0
  20. package/dist/commands/deploy.js.map +1 -0
  21. package/dist/commands/domain.d.ts +3 -0
  22. package/dist/commands/domain.d.ts.map +1 -0
  23. package/dist/commands/domain.js +174 -0
  24. package/dist/commands/domain.js.map +1 -0
  25. package/dist/commands/exec.d.ts +3 -0
  26. package/dist/commands/exec.d.ts.map +1 -0
  27. package/dist/commands/exec.js +176 -0
  28. package/dist/commands/exec.js.map +1 -0
  29. package/dist/commands/managedDb.d.ts +3 -0
  30. package/dist/commands/managedDb.d.ts.map +1 -0
  31. package/dist/commands/managedDb.js +227 -0
  32. package/dist/commands/managedDb.js.map +1 -0
  33. package/dist/commands/member.d.ts +3 -0
  34. package/dist/commands/member.d.ts.map +1 -0
  35. package/dist/commands/member.js +175 -0
  36. package/dist/commands/member.js.map +1 -0
  37. package/dist/commands/project.d.ts +3 -0
  38. package/dist/commands/project.d.ts.map +1 -0
  39. package/dist/commands/project.js +92 -0
  40. package/dist/commands/project.js.map +1 -0
  41. package/dist/commands/secret.d.ts +3 -0
  42. package/dist/commands/secret.d.ts.map +1 -0
  43. package/dist/commands/secret.js +121 -0
  44. package/dist/commands/secret.js.map +1 -0
  45. package/dist/commands/token.d.ts +3 -0
  46. package/dist/commands/token.d.ts.map +1 -0
  47. package/dist/commands/token.js +179 -0
  48. package/dist/commands/token.js.map +1 -0
  49. package/dist/commands/volume.d.ts +3 -0
  50. package/dist/commands/volume.d.ts.map +1 -0
  51. package/dist/commands/volume.js +149 -0
  52. package/dist/commands/volume.js.map +1 -0
  53. package/dist/config.d.ts +10 -0
  54. package/dist/config.d.ts.map +1 -0
  55. package/dist/config.js +53 -0
  56. package/dist/config.js.map +1 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/output.d.ts +9 -0
  61. package/dist/output.d.ts.map +1 -0
  62. package/dist/output.js +71 -0
  63. package/dist/output.js.map +1 -0
  64. package/package.json +6 -2
  65. package/src/client.ts +0 -68
  66. package/src/commands/auth.ts +0 -186
  67. package/src/commands/bucket.ts +0 -261
  68. package/src/commands/database.ts +0 -305
  69. package/src/commands/deploy.ts +0 -904
  70. package/src/commands/domain.ts +0 -167
  71. package/src/commands/exec.ts +0 -154
  72. package/src/commands/managedDb.ts +0 -170
  73. package/src/commands/member.ts +0 -168
  74. package/src/commands/project.ts +0 -81
  75. package/src/commands/secret.ts +0 -117
  76. package/src/commands/token.ts +0 -173
  77. package/src/commands/volume.ts +0 -113
  78. package/src/config.ts +0 -56
  79. package/src/index.ts +0 -39
  80. package/src/output.ts +0 -65
  81. package/tsconfig.json +0 -19
@@ -1,81 +0,0 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import { client, apiError, unwrap } from '../client.js';
4
- import { printTable, printJson, success, errorMsg, timeAgo } from '../output.js';
5
-
6
- export function registerProject(program: Command): void {
7
- const project = program.command('project').description('Project management commands');
8
-
9
- // list
10
- project
11
- .command('list')
12
- .description('List projects')
13
- .option('--json', 'Output raw JSON')
14
- .action(async (opts) => {
15
- try {
16
- const res = await client.get('/api/projects');
17
- const raw = unwrap(res.data);
18
- const projects = Array.isArray(raw) ? raw : raw.projects || [];
19
-
20
- if (opts.json) { printJson(projects); return; }
21
- if (!projects.length) { console.log('No projects found.'); return; }
22
-
23
- printTable(
24
- ['ID', 'NAME', 'CREATED'],
25
- projects.map((p: any) => [
26
- p.id,
27
- p.name,
28
- p.createdAt ? timeAgo(p.createdAt) : '—',
29
- ])
30
- );
31
- } catch (err) {
32
- errorMsg(apiError(err));
33
- process.exit(1);
34
- }
35
- });
36
-
37
- // create
38
- project
39
- .command('create')
40
- .description('Create a new project')
41
- .requiredOption('--name <name>', 'Project name')
42
- .option('--json', 'Output raw JSON')
43
- .action(async (opts) => {
44
- try {
45
- const res = await client.post('/api/projects', { name: opts.name });
46
- const p = unwrap(res.data);
47
- if (opts.json) { printJson(p); return; }
48
- success(`Project "${p.name}" created (${p.id})`);
49
- } catch (err) {
50
- errorMsg(apiError(err));
51
- process.exit(1);
52
- }
53
- });
54
-
55
- // delete
56
- project
57
- .command('delete <id>')
58
- .description('Delete a project')
59
- .option('--yes', 'Skip confirmation prompt')
60
- .action(async (id, opts) => {
61
- if (!opts.yes) {
62
- const { confirm } = await inquirer.prompt([
63
- {
64
- type: 'confirm',
65
- name: 'confirm',
66
- message: `Delete project "${id}"? All deployments in this project will be removed.`,
67
- default: false,
68
- },
69
- ]);
70
- if (!confirm) { console.log('Cancelled.'); return; }
71
- }
72
-
73
- try {
74
- await client.delete(`/api/projects/${id}`);
75
- success(`Project ${id} deleted.`);
76
- } catch (err) {
77
- errorMsg(apiError(err));
78
- process.exit(1);
79
- }
80
- });
81
- }
@@ -1,117 +0,0 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import { client, apiError, unwrap } from '../client.js';
4
- import { printTable, printJson, success, errorMsg, timeAgo } from '../output.js';
5
-
6
- export function registerSecret(program: Command): void {
7
- const secret = program.command('secret').description('Secret management commands');
8
-
9
- // list
10
- secret
11
- .command('list')
12
- .description('List secrets')
13
- .option('--environment <env>', 'Filter by environment')
14
- .option('--json', 'Output raw JSON')
15
- .action(async (opts) => {
16
- try {
17
- const params: Record<string, string> = {};
18
- if (opts.environment) params.environment = opts.environment;
19
-
20
- const res = await client.get('/api/secrets', { params });
21
- const raw = unwrap(res.data);
22
- const secrets = Array.isArray(raw) ? raw : raw.secrets || [];
23
-
24
- if (opts.json) { printJson(secrets); return; }
25
- if (!secrets.length) { console.log('No secrets found.'); return; }
26
-
27
- printTable(
28
- ['ID', 'NAME', 'ENVIRONMENT', 'CREATED'],
29
- secrets.map((s: any) => [
30
- s.id,
31
- s.name,
32
- s.environment || '—',
33
- s.createdAt ? timeAgo(s.createdAt) : '—',
34
- ])
35
- );
36
- } catch (err) {
37
- errorMsg(apiError(err));
38
- process.exit(1);
39
- }
40
- });
41
-
42
- // create
43
- secret
44
- .command('create')
45
- .description('Create a new secret')
46
- .requiredOption('--name <name>', 'Secret name')
47
- .requiredOption('--environment <env>', 'Target environment')
48
- .option('--value <value>', 'Secret value (prompt if omitted)')
49
- .action(async (opts) => {
50
- let value = opts.value;
51
-
52
- if (!value) {
53
- const ans = await inquirer.prompt([
54
- { type: 'password', name: 'value', message: 'Value:', mask: '•' },
55
- ]);
56
- value = ans.value;
57
- }
58
-
59
- try {
60
- await client.post('/api/secrets', {
61
- name: opts.name,
62
- environment: opts.environment,
63
- value,
64
- });
65
- success(`Secret ${opts.name} created (${opts.environment})`);
66
- } catch (err) {
67
- errorMsg(apiError(err));
68
- process.exit(1);
69
- }
70
- });
71
-
72
- // update
73
- secret
74
- .command('update <id>')
75
- .description('Update a secret value')
76
- .option('--value <value>', 'New secret value (prompt if omitted)')
77
- .action(async (id, opts) => {
78
- let value = opts.value;
79
-
80
- if (!value) {
81
- const ans = await inquirer.prompt([
82
- { type: 'password', name: 'value', message: 'New value:', mask: '•' },
83
- ]);
84
- value = ans.value;
85
- }
86
-
87
- try {
88
- await client.put(`/api/secrets/${id}`, { value });
89
- success(`Secret ${id} updated.`);
90
- } catch (err) {
91
- errorMsg(apiError(err));
92
- process.exit(1);
93
- }
94
- });
95
-
96
- // delete
97
- secret
98
- .command('delete <id>')
99
- .description('Delete a secret')
100
- .option('--yes', 'Skip confirmation prompt')
101
- .action(async (id, opts) => {
102
- if (!opts.yes) {
103
- const { confirm } = await inquirer.prompt([
104
- { type: 'confirm', name: 'confirm', message: `Delete secret "${id}"?`, default: false },
105
- ]);
106
- if (!confirm) { console.log('Cancelled.'); return; }
107
- }
108
-
109
- try {
110
- await client.delete(`/api/secrets/${id}`);
111
- success(`Secret ${id} deleted.`);
112
- } catch (err) {
113
- errorMsg(apiError(err));
114
- process.exit(1);
115
- }
116
- });
117
- }
@@ -1,173 +0,0 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import chalk from 'chalk';
4
- import { client, apiError, unwrap } from '../client.js';
5
- import { printTable, printJson, success, errorMsg, timeAgo } from '../output.js';
6
-
7
- function parseDuration(str: string): Date {
8
- const match = str.match(/^(\d+)(d|h|m)$/);
9
- if (!match) {
10
- throw new Error(`Invalid duration "${str}". Use format like: 90d, 4h, 30m`);
11
- }
12
- const value = parseInt(match[1], 10);
13
- const unit = match[2];
14
- const msMap: Record<string, number> = { d: 86400000, h: 3600000, m: 60000 };
15
- return new Date(Date.now() + value * msMap[unit]);
16
- }
17
-
18
- function formatScopes(scopes: string): string {
19
- return scopes
20
- .split(',')
21
- .map((s) => s.trim())
22
- .join(', ');
23
- }
24
-
25
- function tokenStatus(t: any): string {
26
- if (t.revokedAt) return chalk.red('revoked');
27
- if (t.expiresAt && new Date(t.expiresAt) < new Date()) return chalk.yellow('expired');
28
- return chalk.green('active');
29
- }
30
-
31
- export function registerToken(program: Command): void {
32
- const token = program.command('token').description('Access token management commands');
33
-
34
- // list
35
- token
36
- .command('list')
37
- .description('List access tokens')
38
- .option('--json', 'Output raw JSON')
39
- .option('--show-last-used', 'Show last used column')
40
- .option('--no-expiry', 'Show only tokens with no expiry date')
41
- .option('--unused-since <days>', 'Show tokens unused for N or more days')
42
- .action(async (opts) => {
43
- try {
44
- const res = await client.get('/api/tokens');
45
- let tokens: any[] = unwrap(res.data);
46
- if (!Array.isArray(tokens)) tokens = [];
47
-
48
- if (opts.noExpiry) {
49
- tokens = tokens.filter((t: any) => !t.expiresAt);
50
- }
51
-
52
- if (opts.unusedSince) {
53
- const days = parseInt(opts.unusedSince, 10);
54
- if (isNaN(days) || days < 0) {
55
- errorMsg('--unused-since requires a positive integer (number of days)');
56
- process.exit(1);
57
- }
58
- const cutoff = new Date(Date.now() - days * 86400000);
59
- tokens = tokens.filter((t: any) => {
60
- if (!t.lastUsedAt) return true;
61
- return new Date(t.lastUsedAt) < cutoff;
62
- });
63
- }
64
-
65
- if (opts.json) { printJson(tokens); return; }
66
- if (!tokens.length) { console.log('No tokens found.'); return; }
67
-
68
- const headers = ['ID', 'NAME', 'SCOPES', 'STATUS', 'EXPIRES', 'CREATED'];
69
- if (opts.showLastUsed) headers.push('LAST USED');
70
-
71
- printTable(
72
- headers,
73
- tokens.map((t: any) => {
74
- const row: (string | null)[] = [
75
- t.id,
76
- t.name,
77
- formatScopes(t.scopes || ''),
78
- tokenStatus(t),
79
- t.expiresAt ? timeAgo(t.expiresAt) : '—',
80
- t.createdAt ? timeAgo(t.createdAt) : '—',
81
- ];
82
- if (opts.showLastUsed) {
83
- row.push(t.lastUsedAt ? timeAgo(t.lastUsedAt) : 'never');
84
- }
85
- return row;
86
- })
87
- );
88
- } catch (err) {
89
- errorMsg(apiError(err));
90
- process.exit(1);
91
- }
92
- });
93
-
94
- // create
95
- token
96
- .command('create')
97
- .description('Create a new access token')
98
- .requiredOption('--name <name>', 'Token name')
99
- .requiredOption('--scopes <scopes>', 'Comma-separated scopes (e.g. deploy:write,secrets:read)')
100
- .option('--expires <duration>', 'Expiry duration (e.g. 90d, 4h, 30m)')
101
- .option('--json', 'Output raw JSON')
102
- .action(async (opts) => {
103
- let expiresAt: string | undefined;
104
-
105
- if (opts.expires) {
106
- try {
107
- expiresAt = parseDuration(opts.expires).toISOString();
108
- } catch (e: any) {
109
- errorMsg(e.message);
110
- process.exit(1);
111
- }
112
- }
113
-
114
- try {
115
- const res = await client.post('/api/tokens', {
116
- name: opts.name,
117
- scopes: opts.scopes,
118
- ...(expiresAt ? { expiresAt } : {}),
119
- });
120
-
121
- const data = unwrap(res.data);
122
-
123
- if (opts.json) { printJson(data); return; }
124
-
125
- console.log('');
126
- console.log(chalk.bold('Token created'));
127
- console.log('');
128
- console.log(` ${chalk.dim('ID:')} ${data.id}`);
129
- console.log(` ${chalk.dim('Name:')} ${data.name}`);
130
- console.log(` ${chalk.dim('Scopes:')} ${formatScopes(data.scopes)}`);
131
- if (data.expiresAt) {
132
- console.log(` ${chalk.dim('Expires:')} ${new Date(data.expiresAt).toLocaleDateString()}`);
133
- }
134
- console.log('');
135
- console.log(` ${chalk.dim('Token value (shown once — copy it now):')}`)
136
- console.log('');
137
- console.log(` ${chalk.cyan(data.token)}`);
138
- console.log('');
139
- console.log(chalk.yellow(' This value will not be shown again.'));
140
- console.log('');
141
- } catch (err) {
142
- errorMsg(apiError(err));
143
- process.exit(1);
144
- }
145
- });
146
-
147
- // revoke
148
- token
149
- .command('revoke <id>')
150
- .description('Revoke an access token')
151
- .option('--yes', 'Skip confirmation prompt')
152
- .action(async (id, opts) => {
153
- if (!opts.yes) {
154
- const { confirm } = await inquirer.prompt([
155
- {
156
- type: 'confirm',
157
- name: 'confirm',
158
- message: `Revoke token "${id}"? This cannot be undone.`,
159
- default: false,
160
- },
161
- ]);
162
- if (!confirm) { console.log('Cancelled.'); return; }
163
- }
164
-
165
- try {
166
- await client.post(`/api/tokens/${id}/revoke`, {});
167
- success(`Token ${id} revoked.`);
168
- } catch (err) {
169
- errorMsg(apiError(err));
170
- process.exit(1);
171
- }
172
- });
173
- }
@@ -1,113 +0,0 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import { client, apiError, unwrap } from '../client.js';
4
- import { printTable, printJson, success, errorMsg, timeAgo } from '../output.js';
5
-
6
- function formatBytes(bytes: number | bigint): string {
7
- const n = typeof bytes === 'bigint' ? Number(bytes) : bytes;
8
- if (n < 1024) return `${n} B`;
9
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
10
- if (n < 1024 * 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;
11
- return `${(n / (1024 * 1024 * 1024)).toFixed(2)} GB`;
12
- }
13
-
14
- export function registerVolume(program: Command): void {
15
- const vol = program
16
- .command('volume')
17
- .description('Persistent storage volumes (filesystem mounts attached to deployments)');
18
-
19
- vol
20
- .command('list')
21
- .description('List volumes')
22
- .option('--json', 'Output raw JSON')
23
- .action(async (opts) => {
24
- try {
25
- const res = await client.get('/api/volumes');
26
- const volumes: any[] = unwrap(res.data) || [];
27
- if (opts.json) { printJson(volumes); return; }
28
- if (!volumes.length) { console.log('No volumes found.'); return; }
29
-
30
- printTable(
31
- ['ID', 'NAME', 'SIZE', 'STATUS', 'ATTACHED TO', 'CREATED'],
32
- volumes.map((v: any) => [
33
- v.id,
34
- v.displayName ? `${v.name} (${v.displayName})` : v.name,
35
- formatBytes(v.sizeBytes),
36
- v.status,
37
- v.attachment ? `${v.attachment.deploymentName}:${v.attachment.mountPath}` : '—',
38
- v.createdAt ? timeAgo(v.createdAt) : '—',
39
- ])
40
- );
41
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
42
- });
43
-
44
- vol
45
- .command('create <name>')
46
- .description('Create a new volume (org-scoped)')
47
- .option('--display-name <name>', 'Friendly display name')
48
- .option('--json', 'Output raw JSON')
49
- .action(async (name, opts) => {
50
- try {
51
- const res = await client.post('/api/volumes', { name, displayName: opts.displayName });
52
- const v = unwrap(res.data);
53
- if (opts.json) { printJson(v); return; }
54
- success(`Volume created: ${v.id} (${v.name})`);
55
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
56
- });
57
-
58
- vol
59
- .command('delete <id>')
60
- .description('Delete a volume (must be detached first)')
61
- .option('--yes', 'Skip confirmation prompt')
62
- .action(async (id, opts) => {
63
- if (!opts.yes) {
64
- const { confirm } = await inquirer.prompt([
65
- { type: 'confirm', name: 'confirm', message: `Delete volume "${id}"? Data is destroyed.`, default: false },
66
- ]);
67
- if (!confirm) { console.log('Cancelled.'); return; }
68
- }
69
- try {
70
- await client.delete(`/api/volumes/${id}`);
71
- success(`Volume ${id} deleted.`);
72
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
73
- });
74
-
75
- vol
76
- .command('attach <id> <deployment-id>')
77
- .description('Attach a volume to a deployment (requires redeploy to take effect)')
78
- .option('--mount <path>', 'Mount path inside the container', '/data')
79
- .action(async (id, deploymentId, opts) => {
80
- try {
81
- const res = await client.post(`/api/volumes/${id}/attach`, {
82
- deploymentId,
83
- mountPath: opts.mount,
84
- });
85
- const dv = unwrap(res.data);
86
- success(`Attached volume ${id} to deployment ${deploymentId} at ${dv.mountPath}.`);
87
- console.log(" Run 'nexus deploy redeploy <id>' to mount it.");
88
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
89
- });
90
-
91
- vol
92
- .command('detach <id>')
93
- .description('Detach a volume from its deployment')
94
- .action(async (id) => {
95
- try {
96
- await client.post(`/api/volumes/${id}/detach`);
97
- success(`Volume ${id} detached.`);
98
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
99
- });
100
-
101
- vol
102
- .command('refresh-usage <id>')
103
- .description('Refresh on-disk usage for a volume')
104
- .option('--json', 'Output raw JSON')
105
- .action(async (id, opts) => {
106
- try {
107
- const res = await client.post(`/api/volumes/${id}/refresh-usage`);
108
- const v = unwrap(res.data);
109
- if (opts.json) { printJson(v); return; }
110
- success(`${v.name}: ${formatBytes(v.sizeBytes)}`);
111
- } catch (err) { errorMsg(apiError(err)); process.exit(1); }
112
- });
113
- }
package/src/config.ts DELETED
@@ -1,56 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import os from 'os';
4
-
5
- export interface Config {
6
- apiUrl: string;
7
- token: string;
8
- tokenId: string;
9
- }
10
-
11
- const CONFIG_DIR = path.join(os.homedir(), '.nexusai');
12
- const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
13
-
14
- const DEFAULT_API_URL = 'https://nexusai.run';
15
-
16
- export function getConfig(): Partial<Config> {
17
- const envToken = process.env.NEXUSAI_TOKEN;
18
- const envApiUrl = process.env.NEXUSAI_API_URL;
19
-
20
- let fileConfig: Partial<Config> = {};
21
- if (fs.existsSync(CONFIG_PATH)) {
22
- try {
23
- fileConfig = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
24
- } catch {
25
- // ignore malformed config
26
- }
27
- }
28
-
29
- return {
30
- apiUrl: envApiUrl || fileConfig.apiUrl || DEFAULT_API_URL,
31
- token: envToken || fileConfig.token || '',
32
- tokenId: fileConfig.tokenId || '',
33
- };
34
- }
35
-
36
- export function saveConfig(config: Config): void {
37
- if (!fs.existsSync(CONFIG_DIR)) {
38
- fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
39
- }
40
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600 });
41
- }
42
-
43
- export function clearConfig(): void {
44
- if (fs.existsSync(CONFIG_PATH)) {
45
- fs.unlinkSync(CONFIG_PATH);
46
- }
47
- }
48
-
49
- export function requireToken(): string {
50
- const config = getConfig();
51
- if (!config.token) {
52
- console.error("Not logged in. Run 'nexus auth login' first.");
53
- process.exit(1);
54
- }
55
- return config.token;
56
- }
package/src/index.ts DELETED
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import { registerAuth } from './commands/auth.js';
4
- import { registerDeploy } from './commands/deploy.js';
5
- import { registerSecret } from './commands/secret.js';
6
- import { registerProject } from './commands/project.js';
7
- import { registerDomain } from './commands/domain.js';
8
- import { registerToken } from './commands/token.js';
9
- import { registerMember } from './commands/member.js';
10
- import { registerDatabase } from './commands/database.js';
11
- import { registerVolume } from './commands/volume.js';
12
- import { registerBucket } from './commands/bucket.js';
13
- import { registerManagedDb } from './commands/managedDb.js';
14
- import { registerExec } from './commands/exec.js';
15
-
16
- const program = new Command();
17
-
18
- program
19
- .name('nexus')
20
- .description('NEXUS AI command-line interface')
21
- .version('1.0.0');
22
-
23
- registerAuth(program);
24
- registerDeploy(program);
25
- registerSecret(program);
26
- registerProject(program);
27
- registerDomain(program);
28
- registerToken(program);
29
- registerMember(program);
30
- registerDatabase(program);
31
- registerVolume(program);
32
- registerBucket(program);
33
- registerManagedDb(program);
34
- registerExec(program);
35
-
36
- program.parseAsync(process.argv).catch((err) => {
37
- console.error(err.message || String(err));
38
- process.exit(1);
39
- });
package/src/output.ts DELETED
@@ -1,65 +0,0 @@
1
- import chalk from 'chalk';
2
- import Table from 'cli-table3';
3
- import ora, { Ora } from 'ora';
4
-
5
- const STATUS_COLORS: Record<string, (s: string) => string> = {
6
- RUNNING: chalk.green,
7
- BUILDING: chalk.yellow,
8
- DEPLOYING: chalk.yellow,
9
- FAILED: chalk.red,
10
- STOPPED: chalk.gray,
11
- PENDING: chalk.blue,
12
- QUEUED: chalk.blue,
13
- TERMINATED: chalk.gray,
14
- };
15
-
16
- export function statusBadge(status: string): string {
17
- const colorFn = STATUS_COLORS[status?.toUpperCase()] || chalk.white;
18
- return colorFn(status || 'UNKNOWN');
19
- }
20
-
21
- export function printTable(headers: string[], rows: (string | undefined | null)[][]): void {
22
- const table = new Table({
23
- head: headers.map((h) => chalk.bold(h)),
24
- style: { head: [], border: [] },
25
- chars: {
26
- top: '', 'top-mid': '', 'top-left': '', 'top-right': '',
27
- bottom: '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '',
28
- left: '', 'left-mid': '', mid: '', 'mid-mid': '',
29
- right: '', 'right-mid': '', middle: ' ',
30
- },
31
- });
32
-
33
- for (const row of rows) {
34
- table.push(row.map((cell) => cell ?? chalk.gray('—')));
35
- }
36
-
37
- console.log(table.toString());
38
- }
39
-
40
- export function printJson(obj: unknown): void {
41
- console.log(JSON.stringify(obj, null, 2));
42
- }
43
-
44
- export function spinner(text: string): Ora {
45
- return ora(text).start();
46
- }
47
-
48
- export function timeAgo(dateStr: string): string {
49
- const diff = Date.now() - new Date(dateStr).getTime();
50
- const s = Math.floor(diff / 1000);
51
- if (s < 60) return `${s}s ago`;
52
- const m = Math.floor(s / 60);
53
- if (m < 60) return `${m}m ago`;
54
- const h = Math.floor(m / 60);
55
- if (h < 24) return `${h}h ago`;
56
- return `${Math.floor(h / 24)}d ago`;
57
- }
58
-
59
- export function success(msg: string): void {
60
- console.log(chalk.green('✓') + ' ' + msg);
61
- }
62
-
63
- export function errorMsg(msg: string): void {
64
- console.error(chalk.red('✗') + ' ' + msg);
65
- }
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "resolveJsonModule": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- "sourceMap": true
16
- },
17
- "include": ["src/**/*"],
18
- "exclude": ["node_modules", "dist"]
19
- }