@globio/cli 0.1.3 → 0.1.4
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 +398 -223
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/auth/login.ts +40 -16
- package/src/auth/logout.ts +26 -4
- package/src/auth/useProfile.ts +20 -0
- package/src/auth/whoami.ts +26 -8
- package/src/commands/functions.ts +28 -13
- package/src/commands/init.ts +21 -7
- package/src/commands/migrate.ts +9 -2
- package/src/commands/projects.ts +41 -14
- package/src/commands/services.ts +4 -1
- package/src/index.ts +44 -13
- package/src/lib/config.ts +119 -71
- package/src/lib/manage.ts +4 -3
- package/src/lib/sdk.ts +6 -2
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/auth/login.ts
CHANGED
|
@@ -23,15 +23,11 @@ function sleep(ms: number) {
|
|
|
23
23
|
|
|
24
24
|
async function savePat(token: string) {
|
|
25
25
|
const account = await manageRequest<ManageAccount>('/account', { token });
|
|
26
|
-
config.set({
|
|
27
|
-
pat: token,
|
|
28
|
-
accountEmail: account.email,
|
|
29
|
-
accountName: account.display_name ?? account.email,
|
|
30
|
-
});
|
|
31
26
|
return account;
|
|
32
27
|
}
|
|
33
28
|
|
|
34
|
-
async function runTokenLogin() {
|
|
29
|
+
async function runTokenLogin(profileName: string) {
|
|
30
|
+
const hadProfiles = config.listProfiles().length > 0;
|
|
35
31
|
const token = await p.text({
|
|
36
32
|
message: 'Paste your personal access token',
|
|
37
33
|
placeholder: 'glo_pat_...',
|
|
@@ -51,8 +47,17 @@ async function runTokenLogin() {
|
|
|
51
47
|
spinner.start('Validating personal access token...');
|
|
52
48
|
try {
|
|
53
49
|
const account = await savePat(token);
|
|
50
|
+
config.setProfile(profileName, {
|
|
51
|
+
pat: token,
|
|
52
|
+
account_email: account.email,
|
|
53
|
+
account_name: account.display_name ?? account.email,
|
|
54
|
+
created_at: Date.now(),
|
|
55
|
+
});
|
|
56
|
+
if (profileName === 'default' || !hadProfiles) {
|
|
57
|
+
config.setActiveProfile(profileName);
|
|
58
|
+
}
|
|
54
59
|
spinner.stop('Token validated.');
|
|
55
|
-
p.outro(`Logged in as ${account.email}`);
|
|
60
|
+
p.outro(`Logged in as ${account.email}\nProfile: ${profileName}`);
|
|
56
61
|
} catch (error) {
|
|
57
62
|
spinner.stop('Validation failed.');
|
|
58
63
|
p.outro(chalk.red(error instanceof Error ? error.message : 'Could not validate token'));
|
|
@@ -60,9 +65,10 @@ async function runTokenLogin() {
|
|
|
60
65
|
}
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
async function runBrowserLogin() {
|
|
68
|
+
async function runBrowserLogin(profileName: string) {
|
|
64
69
|
const state = crypto.randomUUID();
|
|
65
70
|
const spinner = p.spinner();
|
|
71
|
+
const hadProfiles = config.listProfiles().length > 0;
|
|
66
72
|
|
|
67
73
|
await manageRequest('/cli-auth/request', {
|
|
68
74
|
method: 'POST',
|
|
@@ -98,14 +104,18 @@ async function runBrowserLogin() {
|
|
|
98
104
|
body: { code: status.code },
|
|
99
105
|
});
|
|
100
106
|
|
|
101
|
-
config.
|
|
107
|
+
config.setProfile(profileName, {
|
|
102
108
|
pat: exchange.token,
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
account_email: exchange.account.email,
|
|
110
|
+
account_name: exchange.account.display_name ?? exchange.account.email,
|
|
111
|
+
created_at: Date.now(),
|
|
105
112
|
});
|
|
113
|
+
if (profileName === 'default' || !hadProfiles) {
|
|
114
|
+
config.setActiveProfile(profileName);
|
|
115
|
+
}
|
|
106
116
|
|
|
107
117
|
spinner.stop('Browser approval received.');
|
|
108
|
-
p.outro(`Logged in as ${exchange.account.email}`);
|
|
118
|
+
p.outro(`Logged in as ${exchange.account.email}\nProfile: ${profileName}`);
|
|
109
119
|
return;
|
|
110
120
|
}
|
|
111
121
|
} catch {
|
|
@@ -120,11 +130,25 @@ async function runBrowserLogin() {
|
|
|
120
130
|
process.exit(1);
|
|
121
131
|
}
|
|
122
132
|
|
|
123
|
-
export async function login(options: { token?: boolean } = {}) {
|
|
133
|
+
export async function login(options: { token?: boolean; profile?: string } = {}) {
|
|
124
134
|
printBanner(version);
|
|
135
|
+
const profileName = options.profile ?? 'default';
|
|
136
|
+
const existing = config.getProfile(profileName);
|
|
137
|
+
|
|
138
|
+
if (existing) {
|
|
139
|
+
const proceed = await p.confirm({
|
|
140
|
+
message: `Already logged in as ${existing.account_email} on profile "${profileName}". Replace?`,
|
|
141
|
+
initialValue: false,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
if (p.isCancel(proceed) || !proceed) {
|
|
145
|
+
p.outro('Login cancelled.');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
125
149
|
|
|
126
150
|
if (options.token) {
|
|
127
|
-
await runTokenLogin();
|
|
151
|
+
await runTokenLogin(profileName);
|
|
128
152
|
return;
|
|
129
153
|
}
|
|
130
154
|
|
|
@@ -142,12 +166,12 @@ export async function login(options: { token?: boolean } = {}) {
|
|
|
142
166
|
}
|
|
143
167
|
|
|
144
168
|
if (choice === 'token') {
|
|
145
|
-
await runTokenLogin();
|
|
169
|
+
await runTokenLogin(profileName);
|
|
146
170
|
return;
|
|
147
171
|
}
|
|
148
172
|
|
|
149
173
|
try {
|
|
150
|
-
await runBrowserLogin();
|
|
174
|
+
await runBrowserLogin(profileName);
|
|
151
175
|
} catch (error) {
|
|
152
176
|
p.outro(chalk.red(error instanceof Error ? error.message : 'Could not connect to Globio.'));
|
|
153
177
|
process.exit(1);
|
package/src/auth/logout.ts
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
|
-
import * as p from '@clack/prompts';
|
|
2
1
|
import chalk from 'chalk';
|
|
3
2
|
import { config } from '../lib/config.js';
|
|
4
3
|
|
|
5
|
-
export async function logout() {
|
|
6
|
-
config.
|
|
7
|
-
|
|
4
|
+
export async function logout(options: { profile?: string } = {}) {
|
|
5
|
+
const activeProfile = config.getActiveProfile();
|
|
6
|
+
const profileName = options.profile ?? activeProfile;
|
|
7
|
+
const profile = profileName ? config.getProfile(profileName) : null;
|
|
8
|
+
|
|
9
|
+
if (!profileName || !profile) {
|
|
10
|
+
console.log(chalk.yellow(`No active session on profile "${profileName || 'default'}".`));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
config.deleteProfile(profileName);
|
|
15
|
+
|
|
16
|
+
if (profileName === activeProfile) {
|
|
17
|
+
const remaining = config.listProfiles();
|
|
18
|
+
if (remaining.length > 0) {
|
|
19
|
+
config.setActiveProfile(remaining[0]);
|
|
20
|
+
console.log(chalk.green(`Logged out. Switched to profile: ${remaining[0]}`));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
config.setActiveProfile('');
|
|
25
|
+
console.log(chalk.green('Logged out.'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log(chalk.green(`Logged out profile: ${profileName}`));
|
|
8
30
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { orange } from '../lib/banner.js';
|
|
3
|
+
import { config } from '../lib/config.js';
|
|
4
|
+
|
|
5
|
+
export async function useProfile(profileName: string) {
|
|
6
|
+
const profile = config.getProfile(profileName);
|
|
7
|
+
if (!profile) {
|
|
8
|
+
console.log(
|
|
9
|
+
chalk.red(
|
|
10
|
+
`Profile "${profileName}" not found. Run: globio login --profile ${profileName}`
|
|
11
|
+
)
|
|
12
|
+
);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
config.setActiveProfile(profileName);
|
|
17
|
+
console.log(
|
|
18
|
+
chalk.green('Switched to profile: ') + orange(profileName) + ` (${profile.account_email})`
|
|
19
|
+
);
|
|
20
|
+
}
|
package/src/auth/whoami.ts
CHANGED
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { config } from '../lib/config.js';
|
|
3
|
+
import { muted, orange } from '../lib/banner.js';
|
|
3
4
|
|
|
4
|
-
export async function whoami() {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export async function whoami(options: { profile?: string } = {}) {
|
|
6
|
+
const profileName = options.profile ?? config.getActiveProfile() ?? 'default';
|
|
7
|
+
const profile = config.getProfile(profileName);
|
|
8
|
+
|
|
9
|
+
if (!profile) {
|
|
10
|
+
console.log(chalk.red('Not logged in. Run: globio login'));
|
|
8
11
|
return;
|
|
9
12
|
}
|
|
10
13
|
|
|
14
|
+
const allProfiles = config.listProfiles();
|
|
15
|
+
const activeProfile = config.getActiveProfile();
|
|
16
|
+
|
|
11
17
|
console.log('');
|
|
12
|
-
console.log(chalk.cyan('Account: ') + (cfg.accountEmail ?? 'unknown'));
|
|
13
|
-
console.log(chalk.cyan('Name: ') + (cfg.accountName ?? 'unknown'));
|
|
14
18
|
console.log(
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
muted('Profile: ') + orange(profileName) + (profileName === activeProfile ? muted(' (active)') : '')
|
|
20
|
+
);
|
|
21
|
+
console.log(muted('Account: ') + profile.account_email);
|
|
22
|
+
console.log(muted('Name: ') + (profile.account_name || '—'));
|
|
23
|
+
console.log(
|
|
24
|
+
muted('Project: ') +
|
|
25
|
+
(profile.active_project_id
|
|
26
|
+
? orange(profile.active_project_name || 'unnamed') + muted(` (${profile.active_project_id})`)
|
|
27
|
+
: chalk.gray('none — run: globio projects use <id>'))
|
|
17
28
|
);
|
|
29
|
+
|
|
30
|
+
if (allProfiles.length > 1) {
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(
|
|
33
|
+
muted('Other profiles: ') + allProfiles.filter((name) => name !== profileName).join(', ')
|
|
34
|
+
);
|
|
35
|
+
}
|
|
18
36
|
console.log('');
|
|
19
37
|
}
|
|
@@ -2,11 +2,17 @@ import chalk from 'chalk';
|
|
|
2
2
|
import type { CodeFunction, CodeInvocation } from '@globio/sdk';
|
|
3
3
|
import ora from 'ora';
|
|
4
4
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
5
|
+
import { config } from '../lib/config.js';
|
|
5
6
|
import { gold, muted, orange } from '../lib/banner.js';
|
|
6
7
|
import { getClient } from '../lib/sdk.js';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
function resolveProfileName(profile?: string) {
|
|
10
|
+
return profile ?? config.getActiveProfile() ?? 'default';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function functionsList(options: { profile?: string } = {}) {
|
|
14
|
+
const profileName = resolveProfileName(options.profile);
|
|
15
|
+
const client = getClient(profileName);
|
|
10
16
|
const spinner = ora('Fetching functions...').start();
|
|
11
17
|
const result = await client.code.listFunctions();
|
|
12
18
|
spinner.stop();
|
|
@@ -29,7 +35,7 @@ export async function functionsList() {
|
|
|
29
35
|
console.log('');
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
export async function functionsCreate(slug: string) {
|
|
38
|
+
export async function functionsCreate(slug: string, _options: { profile?: string } = {}) {
|
|
33
39
|
const filename = `${slug}.js`;
|
|
34
40
|
if (existsSync(filename)) {
|
|
35
41
|
console.log(chalk.yellow(`${filename} already exists.`));
|
|
@@ -60,7 +66,7 @@ async function handler(input, globio) {
|
|
|
60
66
|
|
|
61
67
|
export async function functionsDeploy(
|
|
62
68
|
slug: string,
|
|
63
|
-
options: { file?: string; name?: string }
|
|
69
|
+
options: { file?: string; name?: string; profile?: string }
|
|
64
70
|
) {
|
|
65
71
|
const filename = options.file ?? `${slug}.js`;
|
|
66
72
|
if (!existsSync(filename)) {
|
|
@@ -73,7 +79,8 @@ export async function functionsDeploy(
|
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
const code = readFileSync(filename, 'utf-8');
|
|
76
|
-
const
|
|
82
|
+
const profileName = resolveProfileName(options.profile);
|
|
83
|
+
const client = getClient(profileName);
|
|
77
84
|
const spinner = ora(`Deploying ${slug}...`).start();
|
|
78
85
|
const existing = await client.code.getFunction(slug);
|
|
79
86
|
|
|
@@ -103,7 +110,7 @@ export async function functionsDeploy(
|
|
|
103
110
|
|
|
104
111
|
export async function functionsInvoke(
|
|
105
112
|
slug: string,
|
|
106
|
-
options: { input?: string }
|
|
113
|
+
options: { input?: string; profile?: string }
|
|
107
114
|
) {
|
|
108
115
|
let input: Record<string, unknown> = {};
|
|
109
116
|
if (options.input) {
|
|
@@ -115,7 +122,8 @@ export async function functionsInvoke(
|
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
const
|
|
125
|
+
const profileName = resolveProfileName(options.profile);
|
|
126
|
+
const client = getClient(profileName);
|
|
119
127
|
const spinner = ora(`Invoking ${slug}...`).start();
|
|
120
128
|
const result = await client.code.invoke(slug, input);
|
|
121
129
|
spinner.stop();
|
|
@@ -134,10 +142,11 @@ export async function functionsInvoke(
|
|
|
134
142
|
|
|
135
143
|
export async function functionsLogs(
|
|
136
144
|
slug: string,
|
|
137
|
-
options: { limit?: string }
|
|
145
|
+
options: { limit?: string; profile?: string }
|
|
138
146
|
) {
|
|
139
147
|
const limit = options.limit ? parseInt(options.limit, 10) : 20;
|
|
140
|
-
const
|
|
148
|
+
const profileName = resolveProfileName(options.profile);
|
|
149
|
+
const client = getClient(profileName);
|
|
141
150
|
const spinner = ora('Fetching invocations...').start();
|
|
142
151
|
const result = await client.code.getInvocations(slug, limit);
|
|
143
152
|
spinner.stop();
|
|
@@ -163,8 +172,9 @@ export async function functionsLogs(
|
|
|
163
172
|
console.log('');
|
|
164
173
|
}
|
|
165
174
|
|
|
166
|
-
export async function functionsDelete(slug: string) {
|
|
167
|
-
const
|
|
175
|
+
export async function functionsDelete(slug: string, options: { profile?: string } = {}) {
|
|
176
|
+
const profileName = resolveProfileName(options.profile);
|
|
177
|
+
const client = getClient(profileName);
|
|
168
178
|
const spinner = ora(`Deleting ${slug}...`).start();
|
|
169
179
|
const result = await client.code.deleteFunction(slug);
|
|
170
180
|
if (!result.success) {
|
|
@@ -175,8 +185,13 @@ export async function functionsDelete(slug: string) {
|
|
|
175
185
|
spinner.succeed(`Deleted ${slug}`);
|
|
176
186
|
}
|
|
177
187
|
|
|
178
|
-
export async function functionsToggle(
|
|
179
|
-
|
|
188
|
+
export async function functionsToggle(
|
|
189
|
+
slug: string,
|
|
190
|
+
active: boolean,
|
|
191
|
+
options: { profile?: string } = {}
|
|
192
|
+
) {
|
|
193
|
+
const profileName = resolveProfileName(options.profile);
|
|
194
|
+
const client = getClient(profileName);
|
|
180
195
|
const spinner = ora(
|
|
181
196
|
`${active ? 'Enabling' : 'Disabling'} ${slug}...`
|
|
182
197
|
).start();
|
package/src/commands/init.ts
CHANGED
|
@@ -14,20 +14,32 @@ import { projectsCreate, projectsUse } from './projects.js';
|
|
|
14
14
|
|
|
15
15
|
const version = getCliVersion();
|
|
16
16
|
|
|
17
|
-
export async function init() {
|
|
17
|
+
export async function init(options: { profile?: string } = {}) {
|
|
18
18
|
printBanner(version);
|
|
19
19
|
p.intro(orange('⇒⇒') + ' Initialize your Globio project');
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const profileName = options.profile ?? config.getActiveProfile() ?? 'default';
|
|
22
|
+
const profile = config.getProfile(profileName);
|
|
23
|
+
if (!profile) {
|
|
24
|
+
console.log('Run: npx @globio/cli login --profile ' + profileName);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!profile.active_project_id) {
|
|
29
|
+
await projectsCreate({ profile: profileName });
|
|
24
30
|
} else {
|
|
25
|
-
await projectsUse(
|
|
31
|
+
await projectsUse(profile.active_project_id, { profile: profileName });
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
const values = await promptInit();
|
|
29
|
-
const
|
|
30
|
-
const
|
|
35
|
+
const activeProfile = config.getProfile(profileName);
|
|
36
|
+
const activeProjectKey = activeProfile?.project_api_key;
|
|
37
|
+
const { projectId: activeProjectId } = config.requireProject(profileName);
|
|
38
|
+
|
|
39
|
+
if (!activeProjectKey) {
|
|
40
|
+
console.log('No project API key cached. Run: npx @globio/cli projects use ' + activeProjectId);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
31
43
|
|
|
32
44
|
if (!existsSync('globio.config.ts')) {
|
|
33
45
|
writeFileSync(
|
|
@@ -54,6 +66,7 @@ export const globio = new Globio({
|
|
|
54
66
|
await migrateFirestore({
|
|
55
67
|
from: values.serviceAccountPath as string,
|
|
56
68
|
all: true,
|
|
69
|
+
profile: profileName,
|
|
57
70
|
});
|
|
58
71
|
|
|
59
72
|
const serviceAccount = JSON.parse(
|
|
@@ -64,6 +77,7 @@ export const globio = new Globio({
|
|
|
64
77
|
from: values.serviceAccountPath as string,
|
|
65
78
|
bucket: `${serviceAccount.project_id}.appspot.com`,
|
|
66
79
|
all: true,
|
|
80
|
+
profile: profileName,
|
|
67
81
|
});
|
|
68
82
|
}
|
|
69
83
|
|
package/src/commands/migrate.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { initFirebase } from '../lib/firebase.js';
|
|
12
12
|
import { createProgressBar } from '../lib/progress.js';
|
|
13
13
|
import { getClient } from '../lib/sdk.js';
|
|
14
|
+
import { config } from '../lib/config.js';
|
|
14
15
|
|
|
15
16
|
const version = getCliVersion();
|
|
16
17
|
|
|
@@ -18,6 +19,7 @@ interface MigrateFirestoreOptions {
|
|
|
18
19
|
from: string;
|
|
19
20
|
collection?: string;
|
|
20
21
|
all?: boolean;
|
|
22
|
+
profile?: string;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
interface MigrateStorageOptions {
|
|
@@ -25,6 +27,11 @@ interface MigrateStorageOptions {
|
|
|
25
27
|
bucket: string;
|
|
26
28
|
folder?: string;
|
|
27
29
|
all?: boolean;
|
|
30
|
+
profile?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function resolveProfileName(profile?: string) {
|
|
34
|
+
return profile ?? config.getActiveProfile() ?? 'default';
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
@@ -32,7 +39,7 @@ export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
|
32
39
|
p.intro(gold('⇒⇒') + ' Firebase → Globio Migration');
|
|
33
40
|
|
|
34
41
|
const { firestore } = await initFirebase(options.from);
|
|
35
|
-
const client = getClient();
|
|
42
|
+
const client = getClient(resolveProfileName(options.profile));
|
|
36
43
|
|
|
37
44
|
let collections: string[] = [];
|
|
38
45
|
|
|
@@ -139,7 +146,7 @@ export async function migrateFirebaseStorage(options: MigrateStorageOptions) {
|
|
|
139
146
|
p.intro(gold('⇒⇒') + ' Firebase → Globio Migration');
|
|
140
147
|
|
|
141
148
|
const { storage } = await initFirebase(options.from);
|
|
142
|
-
const client = getClient();
|
|
149
|
+
const client = getClient(resolveProfileName(options.profile));
|
|
143
150
|
|
|
144
151
|
const bucketName = options.bucket.replace(/^gs:\/\//, '');
|
|
145
152
|
const bucket = storage.bucket(bucketName);
|
package/src/commands/projects.ts
CHANGED
|
@@ -17,16 +17,18 @@ function slugify(value: string) {
|
|
|
17
17
|
.replace(/-+/g, '-');
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
function resolveProfileName(profileName?: string) {
|
|
21
|
+
return profileName ?? config.getActiveProfile() ?? 'default';
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
+
async function createServerKey(projectId: string, profileName: string) {
|
|
24
25
|
const created = await manageRequest<ManageProjectKey>(`/projects/${projectId}/keys`, {
|
|
25
26
|
method: 'POST',
|
|
26
27
|
body: {
|
|
27
28
|
name: 'CLI server key',
|
|
28
29
|
scope: 'server',
|
|
29
30
|
},
|
|
31
|
+
profileName,
|
|
30
32
|
});
|
|
31
33
|
|
|
32
34
|
if (!created.token) {
|
|
@@ -36,9 +38,12 @@ async function ensureProjectKey(projectId: string) {
|
|
|
36
38
|
return created.token;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
export async function projectsList() {
|
|
40
|
-
const
|
|
41
|
-
|
|
41
|
+
export async function projectsList(options: { profile?: string } = {}) {
|
|
42
|
+
const profileName = resolveProfileName(options.profile);
|
|
43
|
+
config.requireAuth(profileName);
|
|
44
|
+
|
|
45
|
+
const projects = await manageRequest<ManageProject[]>('/projects', { profileName });
|
|
46
|
+
const activeProjectId = config.getProfile(profileName)?.active_project_id;
|
|
42
47
|
const grouped = new Map<string, ManageProject[]>();
|
|
43
48
|
|
|
44
49
|
for (const project of projects) {
|
|
@@ -65,21 +70,37 @@ export async function projectsList() {
|
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
|
|
68
|
-
export async function projectsUse(projectId: string) {
|
|
69
|
-
const
|
|
73
|
+
export async function projectsUse(projectId: string, options: { profile?: string } = {}) {
|
|
74
|
+
const profileName = resolveProfileName(options.profile);
|
|
75
|
+
config.requireAuth(profileName);
|
|
76
|
+
|
|
77
|
+
const projects = await manageRequest<ManageProject[]>('/projects', { profileName });
|
|
70
78
|
const project = projects.find((item) => item.id === projectId);
|
|
71
79
|
if (!project) {
|
|
72
80
|
console.log(chalk.red(`Project not found: ${projectId}`));
|
|
73
81
|
process.exit(1);
|
|
74
82
|
}
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
await manageRequest<ManageProjectKey[]>(`/projects/${projectId}/keys`, { profileName });
|
|
85
|
+
const apiKey = await createServerKey(projectId, profileName);
|
|
86
|
+
|
|
87
|
+
config.setProfile(profileName, {
|
|
88
|
+
active_project_id: project.id,
|
|
89
|
+
active_project_name: project.name,
|
|
90
|
+
project_api_key: apiKey,
|
|
91
|
+
});
|
|
92
|
+
config.setActiveProfile(profileName);
|
|
93
|
+
|
|
94
|
+
console.log(
|
|
95
|
+
chalk.green('Active project set to: ') + chalk.cyan(`${project.name} (${project.id})`)
|
|
96
|
+
);
|
|
79
97
|
}
|
|
80
98
|
|
|
81
|
-
export async function projectsCreate() {
|
|
82
|
-
const
|
|
99
|
+
export async function projectsCreate(options: { profile?: string } = {}) {
|
|
100
|
+
const profileName = resolveProfileName(options.profile);
|
|
101
|
+
config.requireAuth(profileName);
|
|
102
|
+
|
|
103
|
+
const orgs = await manageRequest<ManageOrg[]>('/orgs', { profileName });
|
|
83
104
|
if (!orgs.length) {
|
|
84
105
|
console.log(chalk.red('No organizations found. Create one in the console first.'));
|
|
85
106
|
process.exit(1);
|
|
@@ -141,9 +162,15 @@ export async function projectsCreate() {
|
|
|
141
162
|
slug: values.slug,
|
|
142
163
|
environment: values.environment,
|
|
143
164
|
},
|
|
165
|
+
profileName,
|
|
144
166
|
});
|
|
145
167
|
|
|
146
|
-
config.
|
|
168
|
+
config.setProfile(profileName, {
|
|
169
|
+
active_project_id: result.project.id,
|
|
170
|
+
active_project_name: result.project.name,
|
|
171
|
+
project_api_key: result.keys.server,
|
|
172
|
+
});
|
|
173
|
+
config.setActiveProfile(profileName);
|
|
147
174
|
|
|
148
175
|
console.log('');
|
|
149
176
|
console.log(chalk.green('Project created successfully.'));
|
package/src/commands/services.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { config } from '../lib/config.js';
|
|
2
3
|
|
|
3
4
|
const ALL_SERVICES = [
|
|
4
5
|
'id',
|
|
@@ -13,7 +14,9 @@ const ALL_SERVICES = [
|
|
|
13
14
|
'code',
|
|
14
15
|
];
|
|
15
16
|
|
|
16
|
-
export async function servicesList() {
|
|
17
|
+
export async function servicesList(options: { profile?: string } = {}) {
|
|
18
|
+
void options.profile;
|
|
19
|
+
void config;
|
|
17
20
|
console.log('');
|
|
18
21
|
console.log(chalk.cyan('Available Globio services:'));
|
|
19
22
|
ALL_SERVICES.forEach((service) => {
|