@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/jsr.json
CHANGED
package/package.json
CHANGED
package/src/auth/login.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
2
|
import { exec } from 'child_process';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
3
|
import { config } from '../lib/config.js';
|
|
5
4
|
import { getConsoleCliAuthUrl, manageRequest, type ManageAccount } from '../lib/manage.js';
|
|
6
|
-
import { getCliVersion, muted, orange, printBanner } from '../lib/banner.js';
|
|
5
|
+
import { failure, getCliVersion, muted, orange, printBanner, white } from '../lib/banner.js';
|
|
7
6
|
|
|
8
7
|
const version = getCliVersion();
|
|
9
8
|
|
|
@@ -37,11 +36,11 @@ function warnOnDuplicateAccount(accountEmail: string, targetProfileName: string)
|
|
|
37
36
|
|
|
38
37
|
console.log('');
|
|
39
38
|
console.log(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
failure(' ⚠ ') +
|
|
40
|
+
white(accountEmail) +
|
|
41
|
+
'\x1b[2m is already logged in under profile \x1b[0m' +
|
|
43
42
|
orange(`"${duplicate}"`) +
|
|
44
|
-
|
|
43
|
+
'\x1b[2m.\x1b[0m'
|
|
45
44
|
);
|
|
46
45
|
console.log('');
|
|
47
46
|
}
|
|
@@ -81,7 +80,7 @@ async function runTokenLogin(profileName: string) {
|
|
|
81
80
|
p.outro(`Logged in as ${account.email}\nProfile: ${profileName}`);
|
|
82
81
|
} catch (error) {
|
|
83
82
|
spinner.stop('Validation failed.');
|
|
84
|
-
p.outro(
|
|
83
|
+
p.outro(failure(error instanceof Error ? error.message : 'Could not validate token') + '\x1b[0m');
|
|
85
84
|
process.exit(1);
|
|
86
85
|
}
|
|
87
86
|
}
|
|
@@ -112,7 +111,7 @@ async function runBrowserLogin(profileName: string) {
|
|
|
112
111
|
|
|
113
112
|
if (status.status === 'expired') {
|
|
114
113
|
spinner.stop('Approval window expired.');
|
|
115
|
-
p.outro(
|
|
114
|
+
p.outro(failure('CLI auth request expired. Try again or use globio login --token.') + '\x1b[0m');
|
|
116
115
|
process.exit(1);
|
|
117
116
|
}
|
|
118
117
|
|
|
@@ -148,7 +147,7 @@ async function runBrowserLogin(profileName: string) {
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
spinner.stop('Approval timed out.');
|
|
151
|
-
p.outro(
|
|
150
|
+
p.outro(failure('Timed out waiting for browser approval. Try again or use globio login --token.') + '\x1b[0m');
|
|
152
151
|
process.exit(1);
|
|
153
152
|
}
|
|
154
153
|
|
|
@@ -195,7 +194,7 @@ export async function login(options: { token?: boolean; profile?: string } = {})
|
|
|
195
194
|
try {
|
|
196
195
|
await runBrowserLogin(profileName);
|
|
197
196
|
} catch (error) {
|
|
198
|
-
p.outro(
|
|
197
|
+
p.outro(failure(error instanceof Error ? error.message : 'Could not connect to Globio.') + '\x1b[0m');
|
|
199
198
|
process.exit(1);
|
|
200
199
|
}
|
|
201
200
|
}
|
package/src/auth/logout.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import { config } from '../lib/config.js';
|
|
2
|
+
import { green, inactive } from '../lib/banner.js';
|
|
3
3
|
|
|
4
4
|
export async function logout(options: { profile?: string } = {}) {
|
|
5
5
|
const activeProfile = config.getActiveProfile();
|
|
@@ -7,7 +7,7 @@ export async function logout(options: { profile?: string } = {}) {
|
|
|
7
7
|
const profile = profileName ? config.getProfile(profileName) : null;
|
|
8
8
|
|
|
9
9
|
if (!profileName || !profile) {
|
|
10
|
-
console.log(
|
|
10
|
+
console.log(inactive(`No active session on profile "${profileName || 'default'}".`));
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -17,14 +17,14 @@ export async function logout(options: { profile?: string } = {}) {
|
|
|
17
17
|
const remaining = config.listProfiles();
|
|
18
18
|
if (remaining.length > 0) {
|
|
19
19
|
config.setActiveProfile(remaining[0]);
|
|
20
|
-
console.log(
|
|
20
|
+
console.log(green(`Logged out. Switched to profile: ${remaining[0]}`));
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
config.setActiveProfile('');
|
|
25
|
-
console.log(
|
|
25
|
+
console.log(green('Logged out.'));
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
console.log(
|
|
29
|
+
console.log(green(`Logged out profile: ${profileName}`));
|
|
30
30
|
}
|
package/src/auth/whoami.ts
CHANGED
|
@@ -1,37 +1,76 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import { config } from '../lib/config.js';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
failure,
|
|
4
|
+
getCliVersion,
|
|
5
|
+
header,
|
|
6
|
+
inactive,
|
|
7
|
+
muted,
|
|
8
|
+
orange,
|
|
9
|
+
renderTable,
|
|
10
|
+
white,
|
|
11
|
+
gold,
|
|
12
|
+
reset,
|
|
13
|
+
} from '../lib/banner.js';
|
|
14
|
+
|
|
15
|
+
const version = getCliVersion();
|
|
4
16
|
|
|
5
17
|
export async function whoami(options: { profile?: string } = {}) {
|
|
6
18
|
const profileName = options.profile ?? config.getActiveProfile() ?? 'default';
|
|
7
19
|
const profile = config.getProfile(profileName);
|
|
8
20
|
|
|
9
21
|
if (!profile) {
|
|
10
|
-
console.log(
|
|
22
|
+
console.log(
|
|
23
|
+
header(version) +
|
|
24
|
+
' ' +
|
|
25
|
+
failure('Not logged in.') +
|
|
26
|
+
reset +
|
|
27
|
+
' Run: globio login\n'
|
|
28
|
+
);
|
|
11
29
|
return;
|
|
12
30
|
}
|
|
13
31
|
|
|
14
32
|
const allProfiles = config.listProfiles();
|
|
15
|
-
const
|
|
33
|
+
const active = config.getActiveProfile();
|
|
34
|
+
const otherProfiles = allProfiles.filter((p) => p !== profileName).join(', ') || '—';
|
|
16
35
|
|
|
17
|
-
console.log('');
|
|
18
36
|
console.log(
|
|
19
|
-
|
|
37
|
+
header(
|
|
38
|
+
version,
|
|
39
|
+
'Logged in as ' +
|
|
40
|
+
orange(profile.account_name || profile.account_email) +
|
|
41
|
+
reset +
|
|
42
|
+
' · ' +
|
|
43
|
+
muted(profile.account_email)
|
|
44
|
+
)
|
|
20
45
|
);
|
|
21
|
-
|
|
22
|
-
console.log(muted('Name: ') + (profile.account_name || '—'));
|
|
46
|
+
|
|
23
47
|
console.log(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:
|
|
48
|
+
renderTable({
|
|
49
|
+
columns: [
|
|
50
|
+
{ header: 'Profile', width: 16 },
|
|
51
|
+
{ header: 'Value', width: 44 },
|
|
52
|
+
],
|
|
53
|
+
rows: [
|
|
54
|
+
[
|
|
55
|
+
'Profile',
|
|
56
|
+
profileName === active
|
|
57
|
+
? orange(profileName) + reset + ' ' + inactive('(active)')
|
|
58
|
+
: inactive(profileName),
|
|
59
|
+
],
|
|
60
|
+
['Other profiles', inactive(otherProfiles)],
|
|
61
|
+
['Account', white(profile.account_name || '—')],
|
|
62
|
+
['Organization', white(profile.org_name || '—')],
|
|
63
|
+
[
|
|
64
|
+
'Active project',
|
|
65
|
+
profile.active_project_id
|
|
66
|
+
? gold(profile.active_project_name || 'unnamed') +
|
|
67
|
+
reset +
|
|
68
|
+
' ' +
|
|
69
|
+
inactive(profile.active_project_id)
|
|
70
|
+
: inactive('none — run: globio projects use <id>'),
|
|
71
|
+
],
|
|
72
|
+
],
|
|
73
|
+
})
|
|
28
74
|
);
|
|
29
|
-
|
|
30
|
-
if (allProfiles.length > 1) {
|
|
31
|
-
console.log('');
|
|
32
|
-
console.log(
|
|
33
|
-
muted('Other profiles: ') + allProfiles.filter((name) => name !== profileName).join(', ')
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
75
|
console.log('');
|
|
37
76
|
}
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
1
|
import type { CodeFunction, CodeInvocation } from '@globio/sdk';
|
|
3
2
|
import ora from 'ora';
|
|
4
3
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
5
4
|
import { config } from '../lib/config.js';
|
|
6
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
failure,
|
|
7
|
+
getCliVersion,
|
|
8
|
+
green,
|
|
9
|
+
header,
|
|
10
|
+
inactive,
|
|
11
|
+
muted,
|
|
12
|
+
orange,
|
|
13
|
+
gold,
|
|
14
|
+
renderTable,
|
|
15
|
+
} from '../lib/banner.js';
|
|
7
16
|
import { getClient } from '../lib/sdk.js';
|
|
8
17
|
|
|
18
|
+
const version = getCliVersion();
|
|
19
|
+
|
|
9
20
|
function resolveProfileName(profile?: string) {
|
|
10
21
|
return profile ?? config.getActiveProfile() ?? 'default';
|
|
11
22
|
}
|
|
@@ -13,32 +24,39 @@ function resolveProfileName(profile?: string) {
|
|
|
13
24
|
export async function functionsList(options: { profile?: string } = {}) {
|
|
14
25
|
const profileName = resolveProfileName(options.profile);
|
|
15
26
|
const client = getClient(profileName);
|
|
16
|
-
const spinner = ora('Fetching functions...').start();
|
|
17
27
|
const result = await client.code.listFunctions();
|
|
18
|
-
spinner.stop();
|
|
19
28
|
|
|
20
29
|
if (!result.success || !result.data.length) {
|
|
21
|
-
console.log(
|
|
30
|
+
console.log(header(version) + ' ' + muted('No functions found.') + '\n');
|
|
22
31
|
return;
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const rows = result.data.map((fn: CodeFunction) => [
|
|
35
|
+
fn.type === 'hook' ? gold(fn.slug) : orange(fn.slug),
|
|
36
|
+
fn.type === 'hook' ? gold('hook') : orange('function'),
|
|
37
|
+
fn.type === 'hook' && fn.trigger_event ? gold(fn.trigger_event) : muted('http'),
|
|
38
|
+
fn.active ? green('active') : inactive('inactive'),
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
console.log(header(version));
|
|
42
|
+
console.log(
|
|
43
|
+
renderTable({
|
|
44
|
+
columns: [
|
|
45
|
+
{ header: 'Function', width: 24 },
|
|
46
|
+
{ header: 'Type', width: 10 },
|
|
47
|
+
{ header: 'Trigger', width: 20 },
|
|
48
|
+
{ header: 'Status', width: 10 },
|
|
49
|
+
],
|
|
50
|
+
rows,
|
|
51
|
+
})
|
|
52
|
+
);
|
|
35
53
|
console.log('');
|
|
36
54
|
}
|
|
37
55
|
|
|
38
56
|
export async function functionsCreate(slug: string, _options: { profile?: string } = {}) {
|
|
39
57
|
const filename = `${slug}.js`;
|
|
40
58
|
if (existsSync(filename)) {
|
|
41
|
-
console.log(
|
|
59
|
+
console.log(inactive(`${filename} already exists.`));
|
|
42
60
|
return;
|
|
43
61
|
}
|
|
44
62
|
|
|
@@ -58,10 +76,8 @@ async function handler(input, globio) {
|
|
|
58
76
|
}
|
|
59
77
|
`;
|
|
60
78
|
writeFileSync(filename, template);
|
|
61
|
-
console.log(
|
|
62
|
-
console.log(
|
|
63
|
-
chalk.gray(`Deploy with: npx @globio/cli functions deploy ${slug}`)
|
|
64
|
-
);
|
|
79
|
+
console.log(green(`Created ${filename}`));
|
|
80
|
+
console.log(muted(`Deploy with: npx @globio/cli functions deploy ${slug}`));
|
|
65
81
|
}
|
|
66
82
|
|
|
67
83
|
export async function functionsDeploy(
|
|
@@ -71,7 +87,7 @@ export async function functionsDeploy(
|
|
|
71
87
|
const filename = options.file ?? `${slug}.js`;
|
|
72
88
|
if (!existsSync(filename)) {
|
|
73
89
|
console.log(
|
|
74
|
-
|
|
90
|
+
failure(
|
|
75
91
|
`File not found: ${filename}. Create it with: npx @globio/cli functions create ${slug}`
|
|
76
92
|
)
|
|
77
93
|
);
|
|
@@ -117,7 +133,7 @@ export async function functionsInvoke(
|
|
|
117
133
|
try {
|
|
118
134
|
input = JSON.parse(options.input) as Record<string, unknown>;
|
|
119
135
|
} catch {
|
|
120
|
-
console.error(
|
|
136
|
+
console.error(failure('--input must be valid JSON'));
|
|
121
137
|
process.exit(1);
|
|
122
138
|
}
|
|
123
139
|
}
|
|
@@ -129,7 +145,7 @@ export async function functionsInvoke(
|
|
|
129
145
|
spinner.stop();
|
|
130
146
|
|
|
131
147
|
if (!result.success) {
|
|
132
|
-
console.log(
|
|
148
|
+
console.log(failure('Invocation failed'));
|
|
133
149
|
console.error(result.error.message);
|
|
134
150
|
return;
|
|
135
151
|
}
|
|
@@ -147,28 +163,38 @@ export async function functionsLogs(
|
|
|
147
163
|
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
148
164
|
const profileName = resolveProfileName(options.profile);
|
|
149
165
|
const client = getClient(profileName);
|
|
150
|
-
const spinner = ora('Fetching invocations...').start();
|
|
151
166
|
const result = await client.code.getInvocations(slug, limit);
|
|
152
|
-
spinner.stop();
|
|
153
167
|
|
|
154
168
|
if (!result.success || !result.data.length) {
|
|
155
|
-
console.log(
|
|
169
|
+
console.log(header(version) + ' ' + muted('No invocations yet.') + '\n');
|
|
156
170
|
return;
|
|
157
171
|
}
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
result.data.forEach((inv: CodeInvocation) => {
|
|
161
|
-
const status = inv.success
|
|
162
|
-
? '\x1b[38;2;244;140;6m✓\x1b[0m'
|
|
163
|
-
: '\x1b[31m✗\x1b[0m';
|
|
173
|
+
const rows = result.data.map((inv: CodeInvocation) => {
|
|
164
174
|
const date = new Date(inv.invoked_at * 1000)
|
|
165
175
|
.toISOString()
|
|
166
176
|
.replace('T', ' ')
|
|
167
177
|
.slice(0, 19);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
178
|
+
return [
|
|
179
|
+
muted(date),
|
|
180
|
+
muted(inv.trigger_type),
|
|
181
|
+
muted(inv.duration_ms + 'ms'),
|
|
182
|
+
inv.success ? green('success') : failure('failed'),
|
|
183
|
+
];
|
|
171
184
|
});
|
|
185
|
+
|
|
186
|
+
console.log(header(version));
|
|
187
|
+
console.log(
|
|
188
|
+
renderTable({
|
|
189
|
+
columns: [
|
|
190
|
+
{ header: 'Time', width: 21 },
|
|
191
|
+
{ header: 'Trigger', width: 9 },
|
|
192
|
+
{ header: 'Duration', width: 10 },
|
|
193
|
+
{ header: 'Status', width: 10 },
|
|
194
|
+
],
|
|
195
|
+
rows,
|
|
196
|
+
})
|
|
197
|
+
);
|
|
172
198
|
console.log('');
|
|
173
199
|
}
|
|
174
200
|
|
package/src/commands/init.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as p from '@clack/prompts';
|
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
3
3
|
import { config } from '../lib/config.js';
|
|
4
4
|
import {
|
|
5
|
+
failure,
|
|
5
6
|
getCliVersion,
|
|
6
7
|
muted,
|
|
7
8
|
orange,
|
|
@@ -21,7 +22,7 @@ export async function init(options: { profile?: string } = {}) {
|
|
|
21
22
|
const profileName = options.profile ?? config.getActiveProfile() ?? 'default';
|
|
22
23
|
const profile = config.getProfile(profileName);
|
|
23
24
|
if (!profile) {
|
|
24
|
-
console.log('Run: npx @globio/cli login --profile ' + profileName);
|
|
25
|
+
console.log(failure('Run: npx @globio/cli login --profile ' + profileName));
|
|
25
26
|
process.exit(1);
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -37,7 +38,7 @@ export async function init(options: { profile?: string } = {}) {
|
|
|
37
38
|
const { projectId: activeProjectId } = config.requireProject(profileName);
|
|
38
39
|
|
|
39
40
|
if (!activeProjectKey) {
|
|
40
|
-
console.log('No project API key cached. Run: npx @globio/cli projects use ' + activeProjectId);
|
|
41
|
+
console.log(failure('No project API key cached. Run: npx @globio/cli projects use ' + activeProjectId));
|
|
41
42
|
process.exit(1);
|
|
42
43
|
}
|
|
43
44
|
|
package/src/commands/migrate.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
2
|
import { basename } from 'path';
|
|
4
3
|
import {
|
|
4
|
+
failure,
|
|
5
5
|
getCliVersion,
|
|
6
6
|
gold,
|
|
7
|
+
green,
|
|
7
8
|
muted,
|
|
8
9
|
orange,
|
|
9
10
|
printBanner,
|
|
@@ -47,14 +48,14 @@ export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
|
47
48
|
const snapshot = await firestore.listCollections();
|
|
48
49
|
collections = snapshot.map((collection) => collection.id);
|
|
49
50
|
console.log(
|
|
50
|
-
|
|
51
|
+
green(
|
|
51
52
|
`Found ${collections.length} collections: ${collections.join(', ')}`
|
|
52
53
|
)
|
|
53
54
|
);
|
|
54
55
|
} else if (options.collection) {
|
|
55
56
|
collections = [options.collection];
|
|
56
57
|
} else {
|
|
57
|
-
console.log(
|
|
58
|
+
console.log(failure('Specify --collection <name> or --all'));
|
|
58
59
|
process.exit(1);
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -128,17 +129,17 @@ export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
|
128
129
|
bar.stop();
|
|
129
130
|
|
|
130
131
|
console.log(
|
|
131
|
-
|
|
132
|
+
green(` ✓ ${results[collectionId].success} documents migrated`)
|
|
132
133
|
);
|
|
133
134
|
if (indexFieldCount > 0) {
|
|
134
135
|
console.log(
|
|
135
|
-
|
|
136
|
+
muted(` Indexes created for ${indexFieldCount} fields`)
|
|
136
137
|
);
|
|
137
138
|
}
|
|
138
139
|
if (results[collectionId].failed > 0) {
|
|
139
|
-
console.log(
|
|
140
|
+
console.log(failure(` ✗ ${results[collectionId].failed} failed`) + '\x1b[0m');
|
|
140
141
|
console.log(
|
|
141
|
-
|
|
142
|
+
muted(
|
|
142
143
|
' Failed IDs: ' +
|
|
143
144
|
results[collectionId].failedIds.slice(0, 10).join(', ') +
|
|
144
145
|
(results[collectionId].failedIds.length > 10 ? '...' : '')
|
|
@@ -177,7 +178,7 @@ export async function migrateFirebaseStorage(options: MigrateStorageOptions) {
|
|
|
177
178
|
|
|
178
179
|
const [files] = await bucket.getFiles(prefix ? { prefix } : {});
|
|
179
180
|
|
|
180
|
-
console.log(
|
|
181
|
+
console.log(green(`Found ${files.length} files to migrate`));
|
|
181
182
|
|
|
182
183
|
const bar = createProgressBar('Storage');
|
|
183
184
|
bar.start(files.length, 0);
|
|
@@ -222,9 +223,9 @@ export async function migrateFirebaseStorage(options: MigrateStorageOptions) {
|
|
|
222
223
|
bar.stop();
|
|
223
224
|
|
|
224
225
|
console.log('');
|
|
225
|
-
console.log(
|
|
226
|
+
console.log(green(` ✓ ${success} files migrated`));
|
|
226
227
|
if (failed > 0) {
|
|
227
|
-
console.log(
|
|
228
|
+
console.log(failure(` ✗ ${failed} failed`) + '\x1b[0m');
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
p.outro(
|
package/src/commands/profiles.ts
CHANGED
|
@@ -1,26 +1,53 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
getCliVersion,
|
|
3
|
+
green,
|
|
4
|
+
header,
|
|
5
|
+
inactive,
|
|
6
|
+
muted,
|
|
7
|
+
orange,
|
|
8
|
+
renderTable,
|
|
9
|
+
reset,
|
|
10
|
+
white,
|
|
11
|
+
} from '../lib/banner.js';
|
|
3
12
|
import { config } from '../lib/config.js';
|
|
4
13
|
|
|
14
|
+
const version = getCliVersion();
|
|
15
|
+
|
|
5
16
|
export async function profilesList() {
|
|
6
17
|
const profiles = config.listProfiles();
|
|
7
18
|
const active = config.getActiveProfile();
|
|
8
19
|
|
|
9
20
|
if (!profiles.length) {
|
|
10
|
-
console.log(
|
|
21
|
+
console.log(
|
|
22
|
+
header(version) + ' ' + muted('No profiles. Run: globio login') + '\n'
|
|
23
|
+
);
|
|
11
24
|
return;
|
|
12
25
|
}
|
|
13
26
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const data = config.getProfile(name);
|
|
27
|
+
const rows = profiles.map((name) => {
|
|
28
|
+
const p = config.getProfile(name);
|
|
17
29
|
const isActive = name === active;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
return [
|
|
31
|
+
isActive ? orange(name) : inactive(name),
|
|
32
|
+
p?.account_email
|
|
33
|
+
? isActive
|
|
34
|
+
? white(p.account_email)
|
|
35
|
+
: muted(p.account_email)
|
|
36
|
+
: inactive('—'),
|
|
37
|
+
isActive ? green('active') : inactive('—'),
|
|
38
|
+
];
|
|
39
|
+
});
|
|
22
40
|
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
console.log(header(version));
|
|
42
|
+
console.log(
|
|
43
|
+
renderTable({
|
|
44
|
+
columns: [
|
|
45
|
+
{ header: 'Profile', width: 16 },
|
|
46
|
+
{ header: 'Account', width: 36 },
|
|
47
|
+
{ header: 'Status', width: 10 },
|
|
48
|
+
],
|
|
49
|
+
rows,
|
|
50
|
+
})
|
|
51
|
+
);
|
|
25
52
|
console.log('');
|
|
26
53
|
}
|
package/src/commands/projects.ts
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
2
|
import { config } from '../lib/config.js';
|
|
4
3
|
import {
|
|
5
4
|
manageRequest,
|
|
6
5
|
type ManageOrg,
|
|
7
6
|
type ManageProject,
|
|
8
7
|
type ManageProjectKey,
|
|
8
|
+
type ManageProjectServices,
|
|
9
9
|
} from '../lib/manage.js';
|
|
10
|
+
import {
|
|
11
|
+
footer,
|
|
12
|
+
getCliVersion,
|
|
13
|
+
gold,
|
|
14
|
+
green,
|
|
15
|
+
header,
|
|
16
|
+
inactive,
|
|
17
|
+
muted,
|
|
18
|
+
orange,
|
|
19
|
+
renderTable,
|
|
20
|
+
reset,
|
|
21
|
+
white,
|
|
22
|
+
failure,
|
|
23
|
+
} from '../lib/banner.js';
|
|
24
|
+
|
|
25
|
+
const version = getCliVersion();
|
|
10
26
|
|
|
11
27
|
function slugify(value: string) {
|
|
12
28
|
return value
|
|
@@ -44,30 +60,36 @@ export async function projectsList(options: { profile?: string } = {}) {
|
|
|
44
60
|
|
|
45
61
|
const projects = await manageRequest<ManageProject[]>('/projects', { profileName });
|
|
46
62
|
const activeProjectId = config.getProfile(profileName)?.active_project_id;
|
|
47
|
-
const grouped = new Map<string, ManageProject[]>();
|
|
48
|
-
|
|
49
|
-
for (const project of projects) {
|
|
50
|
-
const list = grouped.get(project.org_name) ?? [];
|
|
51
|
-
list.push(project);
|
|
52
|
-
grouped.set(project.org_name, list);
|
|
53
|
-
}
|
|
54
63
|
|
|
55
|
-
console.log('');
|
|
56
64
|
if (!projects.length) {
|
|
57
|
-
console.log(
|
|
58
|
-
console.log('');
|
|
65
|
+
console.log(header(version) + ' ' + muted('No projects found.') + '\n');
|
|
59
66
|
return;
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
const rows = projects.map((project) => [
|
|
70
|
+
activeProjectId === project.id
|
|
71
|
+
? gold(project.name) + reset + ' ' + orange('●') + reset
|
|
72
|
+
: white(project.name),
|
|
73
|
+
muted(project.id),
|
|
74
|
+
muted(project.org_name || project.org_id),
|
|
75
|
+
inactive(project.environment?.slice(0, 4) ?? 'dev'),
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
console.log(header(version));
|
|
79
|
+
console.log(
|
|
80
|
+
renderTable({
|
|
81
|
+
columns: [
|
|
82
|
+
{ header: 'Project', width: 24 },
|
|
83
|
+
{ header: 'ID', width: 26 },
|
|
84
|
+
{ header: 'Org', width: 16 },
|
|
85
|
+
{ header: 'Env', width: 6 },
|
|
86
|
+
],
|
|
87
|
+
rows,
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
console.log(
|
|
91
|
+
footer('● active project · run globio projects use <id> to switch')
|
|
92
|
+
);
|
|
71
93
|
}
|
|
72
94
|
|
|
73
95
|
export async function projectsUse(projectId: string, options: { profile?: string } = {}) {
|
|
@@ -77,7 +99,7 @@ export async function projectsUse(projectId: string, options: { profile?: string
|
|
|
77
99
|
const projects = await manageRequest<ManageProject[]>('/projects', { profileName });
|
|
78
100
|
const project = projects.find((item) => item.id === projectId);
|
|
79
101
|
if (!project) {
|
|
80
|
-
console.log(
|
|
102
|
+
console.log(failure(`Project not found: ${projectId}`));
|
|
81
103
|
process.exit(1);
|
|
82
104
|
}
|
|
83
105
|
|
|
@@ -87,13 +109,12 @@ export async function projectsUse(projectId: string, options: { profile?: string
|
|
|
87
109
|
config.setProfile(profileName, {
|
|
88
110
|
active_project_id: project.id,
|
|
89
111
|
active_project_name: project.name,
|
|
112
|
+
org_name: project.org_name,
|
|
90
113
|
project_api_key: apiKey,
|
|
91
114
|
});
|
|
92
115
|
config.setActiveProfile(profileName);
|
|
93
116
|
|
|
94
|
-
console.log(
|
|
95
|
-
chalk.green('Active project set to: ') + chalk.cyan(`${project.name} (${project.id})`)
|
|
96
|
-
);
|
|
117
|
+
console.log(green('Active project: ') + `${project.name} (${project.id})`);
|
|
97
118
|
}
|
|
98
119
|
|
|
99
120
|
export async function projectsCreate(options: { profile?: string } = {}) {
|
|
@@ -102,7 +123,7 @@ export async function projectsCreate(options: { profile?: string } = {}) {
|
|
|
102
123
|
|
|
103
124
|
const orgs = await manageRequest<ManageOrg[]>('/orgs', { profileName });
|
|
104
125
|
if (!orgs.length) {
|
|
105
|
-
console.log(
|
|
126
|
+
console.log(failure('No organizations found. Create one in the console first.'));
|
|
106
127
|
process.exit(1);
|
|
107
128
|
}
|
|
108
129
|
|
|
@@ -168,14 +189,15 @@ export async function projectsCreate(options: { profile?: string } = {}) {
|
|
|
168
189
|
config.setProfile(profileName, {
|
|
169
190
|
active_project_id: result.project.id,
|
|
170
191
|
active_project_name: result.project.name,
|
|
192
|
+
org_name: orgs.find((org) => org.id === orgId)?.name,
|
|
171
193
|
project_api_key: result.keys.server,
|
|
172
194
|
});
|
|
173
195
|
config.setActiveProfile(profileName);
|
|
174
196
|
|
|
175
197
|
console.log('');
|
|
176
|
-
console.log(
|
|
177
|
-
console.log(
|
|
178
|
-
console.log(
|
|
179
|
-
console.log(
|
|
198
|
+
console.log(green('Project created successfully.'));
|
|
199
|
+
console.log(orange('Project: ') + reset + `${result.project.name} (${result.project.id})`);
|
|
200
|
+
console.log(orange('Client key: ') + reset + result.keys.client);
|
|
201
|
+
console.log(orange('Server key: ') + reset + result.keys.server);
|
|
180
202
|
console.log('');
|
|
181
203
|
}
|