@globio/cli 0.1.8 → 0.1.9
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/dist/index.js +276 -146
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/auth/login.ts +9 -10
- package/src/auth/logout.ts +5 -5
- package/src/auth/whoami.ts +58 -19
- package/src/commands/functions.ts +60 -34
- package/src/commands/init.ts +3 -2
- package/src/commands/migrate.ts +11 -10
- package/src/commands/profiles.ts +39 -12
- package/src/commands/projects.ts +51 -29
- package/src/commands/services.ts +62 -22
- package/src/lib/banner.ts +1 -6
- package/src/lib/config.ts +2 -0
- package/src/lib/manage.ts +4 -0
- package/src/lib/table.ts +97 -0
package/src/commands/services.ts
CHANGED
|
@@ -1,30 +1,70 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import { config } from '../lib/config.js';
|
|
2
|
+
import { manageRequest, type ManageProjectServices } from '../lib/manage.js';
|
|
3
|
+
import {
|
|
4
|
+
footer,
|
|
5
|
+
getCliVersion,
|
|
6
|
+
green,
|
|
7
|
+
header,
|
|
8
|
+
inactive,
|
|
9
|
+
muted,
|
|
10
|
+
orange,
|
|
11
|
+
renderTable,
|
|
12
|
+
} from '../lib/banner.js';
|
|
3
13
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
|
|
14
|
+
const version = getCliVersion();
|
|
15
|
+
|
|
16
|
+
const SERVICE_DESCRIPTIONS: Record<string, string> = {
|
|
17
|
+
id: 'Authentication and user management',
|
|
18
|
+
doc: 'Document database',
|
|
19
|
+
vault: 'File storage',
|
|
20
|
+
pulse: 'Feature flags and remote config',
|
|
21
|
+
scope: 'Analytics and event tracking',
|
|
22
|
+
sync: 'Real-time multiplayer rooms',
|
|
23
|
+
signal: 'Push notifications',
|
|
24
|
+
mart: 'Game economy and payments',
|
|
25
|
+
brain: 'AI agents and LLM routing',
|
|
26
|
+
code: 'Edge functions and GC Hooks',
|
|
27
|
+
};
|
|
16
28
|
|
|
17
29
|
export async function servicesList(options: { profile?: string } = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
const profileName = options.profile ?? config.getActiveProfile() ?? 'default';
|
|
31
|
+
const profile = config.getProfile(profileName);
|
|
32
|
+
let serviceStatuses: ManageProjectServices = {};
|
|
33
|
+
|
|
34
|
+
if (profile?.active_project_id) {
|
|
35
|
+
try {
|
|
36
|
+
serviceStatuses = await manageRequest<ManageProjectServices>(
|
|
37
|
+
`/projects/${profile.active_project_id}/services`,
|
|
38
|
+
{ profileName }
|
|
39
|
+
);
|
|
40
|
+
} catch {
|
|
41
|
+
serviceStatuses = {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const rows = Object.entries(SERVICE_DESCRIPTIONS).map(([slug, desc]) => {
|
|
46
|
+
const enabled = serviceStatuses[slug] ?? null;
|
|
47
|
+
return [
|
|
48
|
+
orange(slug),
|
|
49
|
+
muted(desc),
|
|
50
|
+
enabled === true
|
|
51
|
+
? green('enabled')
|
|
52
|
+
: enabled === false
|
|
53
|
+
? inactive('disabled')
|
|
54
|
+
: inactive('—'),
|
|
55
|
+
];
|
|
24
56
|
});
|
|
25
|
-
|
|
57
|
+
|
|
58
|
+
console.log(header(version));
|
|
26
59
|
console.log(
|
|
27
|
-
|
|
60
|
+
renderTable({
|
|
61
|
+
columns: [
|
|
62
|
+
{ header: 'Service', width: 10 },
|
|
63
|
+
{ header: 'Description', width: 42 },
|
|
64
|
+
{ header: 'Status', width: 10 },
|
|
65
|
+
],
|
|
66
|
+
rows,
|
|
67
|
+
})
|
|
28
68
|
);
|
|
29
|
-
console.log('');
|
|
69
|
+
console.log(footer('Manage services at console.globio.stanlink.online'));
|
|
30
70
|
}
|
package/src/lib/banner.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from 'fs';
|
|
2
2
|
import figlet from 'figlet';
|
|
3
3
|
import gradientString from 'gradient-string';
|
|
4
|
+
export * from './table.js';
|
|
4
5
|
|
|
5
6
|
const globioGradient = gradientString(
|
|
6
7
|
'#e85d04',
|
|
@@ -39,12 +40,6 @@ export function printInfo(message: string) {
|
|
|
39
40
|
console.log('\x1b[2m›\x1b[0m ' + message);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
export const orange = (s: string) => '\x1b[38;2;244;140;6m' + s + '\x1b[0m';
|
|
43
|
-
|
|
44
|
-
export const gold = (s: string) => '\x1b[38;2;255;208;0m' + s + '\x1b[0m';
|
|
45
|
-
|
|
46
|
-
export const muted = (s: string) => '\x1b[2m' + s + '\x1b[0m';
|
|
47
|
-
|
|
48
43
|
export function getCliVersion() {
|
|
49
44
|
const file = readFileSync(new URL('../package.json', import.meta.url), 'utf8');
|
|
50
45
|
return (JSON.parse(file) as { version: string }).version;
|
package/src/lib/config.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface ProfileData {
|
|
|
11
11
|
pat: string;
|
|
12
12
|
account_email: string;
|
|
13
13
|
account_name: string;
|
|
14
|
+
org_name?: string;
|
|
14
15
|
active_project_id?: string;
|
|
15
16
|
active_project_name?: string;
|
|
16
17
|
project_api_key?: string;
|
|
@@ -88,6 +89,7 @@ export const config = {
|
|
|
88
89
|
pat: data.pat ?? existing?.pat ?? '',
|
|
89
90
|
account_email: data.account_email ?? existing?.account_email ?? '',
|
|
90
91
|
account_name: data.account_name ?? existing?.account_name ?? '',
|
|
92
|
+
org_name: data.org_name ?? existing?.org_name,
|
|
91
93
|
active_project_id: data.active_project_id ?? existing?.active_project_id,
|
|
92
94
|
active_project_name: data.active_project_name ?? existing?.active_project_name,
|
|
93
95
|
project_api_key: data.project_api_key ?? existing?.project_api_key,
|
package/src/lib/manage.ts
CHANGED
package/src/lib/table.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export interface Column {
|
|
2
|
+
header: string;
|
|
3
|
+
width: number;
|
|
4
|
+
color?: (val: string) => string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface TableOptions {
|
|
8
|
+
columns: Column[];
|
|
9
|
+
rows: string[][];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ANSI_PATTERN = /\x1b\[[0-9;]*m/g;
|
|
13
|
+
|
|
14
|
+
export const orange = (s: string) => '\x1b[38;2;244;140;6m' + s;
|
|
15
|
+
export const gold = (s: string) => '\x1b[38;2;255;208;0m' + s;
|
|
16
|
+
export const dim = (s: string) => '\x1b[2m' + s + '\x1b[0m';
|
|
17
|
+
export const white = (s: string) => '\x1b[97m' + s;
|
|
18
|
+
export const green = (s: string) => '\x1b[38;2;34;197;94m' + s;
|
|
19
|
+
export const muted = (s: string) => '\x1b[38;2;85;85;85m' + s;
|
|
20
|
+
export const inactive = (s: string) => '\x1b[38;2;68;68;68m' + s;
|
|
21
|
+
export const failure = (s: string) => '\x1b[38;2;232;93;4m' + s;
|
|
22
|
+
export const reset = '\x1b[0m';
|
|
23
|
+
|
|
24
|
+
function stripAnsi(value: string): string {
|
|
25
|
+
return value.replace(ANSI_PATTERN, '');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fitCell(value: string, width: number): string {
|
|
29
|
+
const plain = stripAnsi(value);
|
|
30
|
+
if (plain.length <= width) {
|
|
31
|
+
return value + ' '.repeat(width - plain.length);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const truncated = plain.slice(0, width);
|
|
35
|
+
return truncated;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function renderTable(options: TableOptions): string {
|
|
39
|
+
const { columns, rows } = options;
|
|
40
|
+
const lines: string[] = [];
|
|
41
|
+
|
|
42
|
+
lines.push(
|
|
43
|
+
' ┌' + columns.map((c) => '─'.repeat(c.width + 2)).join('┬') + '┐'
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
lines.push(
|
|
47
|
+
' │' +
|
|
48
|
+
columns
|
|
49
|
+
.map((c) => ' ' + dim(c.header.padEnd(c.width)) + ' │')
|
|
50
|
+
.join('')
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
lines.push(
|
|
54
|
+
' ├' + columns.map((c) => '─'.repeat(c.width + 2)).join('┼') + '┤'
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
for (const row of rows) {
|
|
58
|
+
lines.push(
|
|
59
|
+
' │' +
|
|
60
|
+
columns
|
|
61
|
+
.map((c, i) => {
|
|
62
|
+
const raw = row[i] ?? '';
|
|
63
|
+
const fitted = fitCell(raw, c.width);
|
|
64
|
+
const colored = c.color
|
|
65
|
+
? fitCell(c.color(stripAnsi(raw)), c.width)
|
|
66
|
+
: fitted;
|
|
67
|
+
return ' ' + colored + ' ' + reset + '│';
|
|
68
|
+
})
|
|
69
|
+
.join('')
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
lines.push(
|
|
74
|
+
' └' + columns.map((c) => '─'.repeat(c.width + 2)).join('┴') + '┘'
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return lines.join('\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function header(version: string, subtitle?: string): string {
|
|
81
|
+
const lines = [
|
|
82
|
+
'',
|
|
83
|
+
orange(' ⇒⇒') + reset + ' globio ' + dim(version),
|
|
84
|
+
dim(' ──────────────────────────────────────────'),
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
if (subtitle) {
|
|
88
|
+
lines.push(' ' + subtitle);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
lines.push('');
|
|
92
|
+
return lines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function footer(text: string): string {
|
|
96
|
+
return '\n' + dim(' ' + text) + '\n';
|
|
97
|
+
}
|