@globio/cli 0.1.4 → 0.1.5
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 +53 -14
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/auth/login.ts +22 -0
- package/src/commands/profiles.ts +26 -0
- package/src/index.ts +11 -0
package/dist/index.js
CHANGED
|
@@ -198,6 +198,19 @@ async function savePat(token) {
|
|
|
198
198
|
const account = await manageRequest("/account", { token });
|
|
199
199
|
return account;
|
|
200
200
|
}
|
|
201
|
+
function warnOnDuplicateAccount(accountEmail, targetProfileName) {
|
|
202
|
+
const allProfiles = config.listProfiles();
|
|
203
|
+
const duplicate = allProfiles.find((name) => {
|
|
204
|
+
const profile = config.getProfile(name);
|
|
205
|
+
return profile?.account_email === accountEmail && name !== targetProfileName;
|
|
206
|
+
});
|
|
207
|
+
if (!duplicate) return;
|
|
208
|
+
console.log("");
|
|
209
|
+
console.log(
|
|
210
|
+
chalk2.yellow(" \u26A0 ") + chalk2.white(accountEmail) + chalk2.gray(" is already logged in under profile ") + orange(`"${duplicate}"`) + chalk2.gray(".")
|
|
211
|
+
);
|
|
212
|
+
console.log("");
|
|
213
|
+
}
|
|
201
214
|
async function runTokenLogin(profileName) {
|
|
202
215
|
const hadProfiles = config.listProfiles().length > 0;
|
|
203
216
|
const token = await p.text({
|
|
@@ -217,6 +230,7 @@ async function runTokenLogin(profileName) {
|
|
|
217
230
|
spinner2.start("Validating personal access token...");
|
|
218
231
|
try {
|
|
219
232
|
const account = await savePat(token);
|
|
233
|
+
warnOnDuplicateAccount(account.email, profileName);
|
|
220
234
|
config.setProfile(profileName, {
|
|
221
235
|
pat: token,
|
|
222
236
|
account_email: account.email,
|
|
@@ -264,6 +278,7 @@ async function runBrowserLogin(profileName) {
|
|
|
264
278
|
method: "POST",
|
|
265
279
|
body: { code: status.code }
|
|
266
280
|
});
|
|
281
|
+
warnOnDuplicateAccount(exchange.account.email, profileName);
|
|
267
282
|
config.setProfile(profileName, {
|
|
268
283
|
pat: exchange.token,
|
|
269
284
|
account_email: exchange.account.email,
|
|
@@ -816,8 +831,30 @@ export const globio = new Globio({
|
|
|
816
831
|
);
|
|
817
832
|
}
|
|
818
833
|
|
|
819
|
-
// src/commands/
|
|
834
|
+
// src/commands/profiles.ts
|
|
820
835
|
import chalk9 from "chalk";
|
|
836
|
+
async function profilesList() {
|
|
837
|
+
const profiles2 = config.listProfiles();
|
|
838
|
+
const active = config.getActiveProfile();
|
|
839
|
+
if (!profiles2.length) {
|
|
840
|
+
console.log(chalk9.gray("No profiles found. Run: globio login"));
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
console.log("");
|
|
844
|
+
for (const name of profiles2) {
|
|
845
|
+
const data = config.getProfile(name);
|
|
846
|
+
const isActive = name === active;
|
|
847
|
+
const bullet = isActive ? orange("\u25CF") : chalk9.gray("\u25CB");
|
|
848
|
+
const label = isActive ? orange(name) : chalk9.white(name);
|
|
849
|
+
const email = data?.account_email ? muted(data.account_email) : chalk9.gray("unknown");
|
|
850
|
+
const tag = isActive ? muted(" (active)") : "";
|
|
851
|
+
console.log(` ${bullet} ${label} ${email}${tag}`);
|
|
852
|
+
}
|
|
853
|
+
console.log("");
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// src/commands/services.ts
|
|
857
|
+
import chalk10 from "chalk";
|
|
821
858
|
var ALL_SERVICES = [
|
|
822
859
|
"id",
|
|
823
860
|
"doc",
|
|
@@ -834,19 +871,19 @@ async function servicesList(options = {}) {
|
|
|
834
871
|
void options.profile;
|
|
835
872
|
void config;
|
|
836
873
|
console.log("");
|
|
837
|
-
console.log(
|
|
874
|
+
console.log(chalk10.cyan("Available Globio services:"));
|
|
838
875
|
ALL_SERVICES.forEach((service) => {
|
|
839
|
-
console.log(" " +
|
|
876
|
+
console.log(" " + chalk10.white(service));
|
|
840
877
|
});
|
|
841
878
|
console.log("");
|
|
842
879
|
console.log(
|
|
843
|
-
|
|
880
|
+
chalk10.gray("Manage service access via console.globio.stanlink.online")
|
|
844
881
|
);
|
|
845
882
|
console.log("");
|
|
846
883
|
}
|
|
847
884
|
|
|
848
885
|
// src/commands/functions.ts
|
|
849
|
-
import
|
|
886
|
+
import chalk11 from "chalk";
|
|
850
887
|
import ora from "ora";
|
|
851
888
|
import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
852
889
|
function resolveProfileName3(profile) {
|
|
@@ -859,7 +896,7 @@ async function functionsList(options = {}) {
|
|
|
859
896
|
const result = await client.code.listFunctions();
|
|
860
897
|
spinner2.stop();
|
|
861
898
|
if (!result.success || !result.data.length) {
|
|
862
|
-
console.log(
|
|
899
|
+
console.log(chalk11.gray("No functions found."));
|
|
863
900
|
return;
|
|
864
901
|
}
|
|
865
902
|
console.log("");
|
|
@@ -876,7 +913,7 @@ async function functionsList(options = {}) {
|
|
|
876
913
|
async function functionsCreate(slug, _options = {}) {
|
|
877
914
|
const filename = `${slug}.js`;
|
|
878
915
|
if (existsSync3(filename)) {
|
|
879
|
-
console.log(
|
|
916
|
+
console.log(chalk11.yellow(`${filename} already exists.`));
|
|
880
917
|
return;
|
|
881
918
|
}
|
|
882
919
|
const template = `/**
|
|
@@ -895,16 +932,16 @@ async function handler(input, globio) {
|
|
|
895
932
|
}
|
|
896
933
|
`;
|
|
897
934
|
writeFileSync3(filename, template);
|
|
898
|
-
console.log(
|
|
935
|
+
console.log(chalk11.green(`Created ${filename}`));
|
|
899
936
|
console.log(
|
|
900
|
-
|
|
937
|
+
chalk11.gray(`Deploy with: npx @globio/cli functions deploy ${slug}`)
|
|
901
938
|
);
|
|
902
939
|
}
|
|
903
940
|
async function functionsDeploy(slug, options) {
|
|
904
941
|
const filename = options.file ?? `${slug}.js`;
|
|
905
942
|
if (!existsSync3(filename)) {
|
|
906
943
|
console.log(
|
|
907
|
-
|
|
944
|
+
chalk11.red(
|
|
908
945
|
`File not found: ${filename}. Create it with: npx @globio/cli functions create ${slug}`
|
|
909
946
|
)
|
|
910
947
|
);
|
|
@@ -942,7 +979,7 @@ async function functionsInvoke(slug, options) {
|
|
|
942
979
|
try {
|
|
943
980
|
input = JSON.parse(options.input);
|
|
944
981
|
} catch {
|
|
945
|
-
console.error(
|
|
982
|
+
console.error(chalk11.red("--input must be valid JSON"));
|
|
946
983
|
process.exit(1);
|
|
947
984
|
}
|
|
948
985
|
}
|
|
@@ -952,7 +989,7 @@ async function functionsInvoke(slug, options) {
|
|
|
952
989
|
const result = await client.code.invoke(slug, input);
|
|
953
990
|
spinner2.stop();
|
|
954
991
|
if (!result.success) {
|
|
955
|
-
console.log(
|
|
992
|
+
console.log(chalk11.red("Invocation failed"));
|
|
956
993
|
console.error(result.error.message);
|
|
957
994
|
return;
|
|
958
995
|
}
|
|
@@ -970,7 +1007,7 @@ async function functionsLogs(slug, options) {
|
|
|
970
1007
|
const result = await client.code.getInvocations(slug, limit);
|
|
971
1008
|
spinner2.stop();
|
|
972
1009
|
if (!result.success || !result.data.length) {
|
|
973
|
-
console.log(
|
|
1010
|
+
console.log(chalk11.gray("No invocations yet."));
|
|
974
1011
|
return;
|
|
975
1012
|
}
|
|
976
1013
|
console.log("");
|
|
@@ -978,7 +1015,7 @@ async function functionsLogs(slug, options) {
|
|
|
978
1015
|
const status = inv.success ? "\x1B[38;2;244;140;6m\u2713\x1B[0m" : "\x1B[31m\u2717\x1B[0m";
|
|
979
1016
|
const date = new Date(inv.invoked_at * 1e3).toISOString().replace("T", " ").slice(0, 19);
|
|
980
1017
|
console.log(
|
|
981
|
-
` ${status} ${
|
|
1018
|
+
` ${status} ${chalk11.gray(date)} ${inv.duration_ms}ms ${chalk11.gray(`[${inv.trigger_type}]`)}`
|
|
982
1019
|
);
|
|
983
1020
|
});
|
|
984
1021
|
console.log("");
|
|
@@ -1036,6 +1073,8 @@ program.command("logout").description("Log out").option("--profile <name>", "Use
|
|
|
1036
1073
|
program.command("whoami").description("Show current account and project").option("--profile <name>", "Use a specific profile").action(whoami);
|
|
1037
1074
|
program.command("use <profile>").description("Switch active profile").action(useProfile);
|
|
1038
1075
|
program.command("init").description("Initialize a Globio project").option("--profile <name>", "Use a specific profile").action(init);
|
|
1076
|
+
var profiles = program.command("profiles").description("Manage login profiles").action(profilesList);
|
|
1077
|
+
profiles.command("list").description("List all profiles").action(profilesList);
|
|
1039
1078
|
var projects = program.command("projects").description("Manage projects");
|
|
1040
1079
|
projects.command("list").description("List projects").option("--profile <name>", "Use a specific profile").action(projectsList);
|
|
1041
1080
|
projects.command("create").description("Create a project").option("--profile <name>", "Use a specific profile").action(projectsCreate);
|
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/auth/login.ts
CHANGED
|
@@ -26,6 +26,26 @@ async function savePat(token: string) {
|
|
|
26
26
|
return account;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function warnOnDuplicateAccount(accountEmail: string, targetProfileName: string) {
|
|
30
|
+
const allProfiles = config.listProfiles();
|
|
31
|
+
const duplicate = allProfiles.find((name) => {
|
|
32
|
+
const profile = config.getProfile(name);
|
|
33
|
+
return profile?.account_email === accountEmail && name !== targetProfileName;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (!duplicate) return;
|
|
37
|
+
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(
|
|
40
|
+
chalk.yellow(' ⚠ ') +
|
|
41
|
+
chalk.white(accountEmail) +
|
|
42
|
+
chalk.gray(' is already logged in under profile ') +
|
|
43
|
+
orange(`"${duplicate}"`) +
|
|
44
|
+
chalk.gray('.')
|
|
45
|
+
);
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
async function runTokenLogin(profileName: string) {
|
|
30
50
|
const hadProfiles = config.listProfiles().length > 0;
|
|
31
51
|
const token = await p.text({
|
|
@@ -47,6 +67,7 @@ async function runTokenLogin(profileName: string) {
|
|
|
47
67
|
spinner.start('Validating personal access token...');
|
|
48
68
|
try {
|
|
49
69
|
const account = await savePat(token);
|
|
70
|
+
warnOnDuplicateAccount(account.email, profileName);
|
|
50
71
|
config.setProfile(profileName, {
|
|
51
72
|
pat: token,
|
|
52
73
|
account_email: account.email,
|
|
@@ -104,6 +125,7 @@ async function runBrowserLogin(profileName: string) {
|
|
|
104
125
|
body: { code: status.code },
|
|
105
126
|
});
|
|
106
127
|
|
|
128
|
+
warnOnDuplicateAccount(exchange.account.email, profileName);
|
|
107
129
|
config.setProfile(profileName, {
|
|
108
130
|
pat: exchange.token,
|
|
109
131
|
account_email: exchange.account.email,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { orange, muted } from '../lib/banner.js';
|
|
3
|
+
import { config } from '../lib/config.js';
|
|
4
|
+
|
|
5
|
+
export async function profilesList() {
|
|
6
|
+
const profiles = config.listProfiles();
|
|
7
|
+
const active = config.getActiveProfile();
|
|
8
|
+
|
|
9
|
+
if (!profiles.length) {
|
|
10
|
+
console.log(chalk.gray('No profiles found. Run: globio login'));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
console.log('');
|
|
15
|
+
for (const name of profiles) {
|
|
16
|
+
const data = config.getProfile(name);
|
|
17
|
+
const isActive = name === active;
|
|
18
|
+
const bullet = isActive ? orange('●') : chalk.gray('○');
|
|
19
|
+
const label = isActive ? orange(name) : chalk.white(name);
|
|
20
|
+
const email = data?.account_email ? muted(data.account_email) : chalk.gray('unknown');
|
|
21
|
+
const tag = isActive ? muted(' (active)') : '';
|
|
22
|
+
|
|
23
|
+
console.log(` ${bullet} ${label} ${email}${tag}`);
|
|
24
|
+
}
|
|
25
|
+
console.log('');
|
|
26
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { useProfile } from './auth/useProfile.js';
|
|
|
6
6
|
import { whoami } from './auth/whoami.js';
|
|
7
7
|
import { init } from './commands/init.js';
|
|
8
8
|
import { projectsCreate, projectsList, projectsUse } from './commands/projects.js';
|
|
9
|
+
import { profilesList } from './commands/profiles.js';
|
|
9
10
|
import { servicesList } from './commands/services.js';
|
|
10
11
|
import {
|
|
11
12
|
functionsList,
|
|
@@ -62,6 +63,16 @@ program.command('use <profile>').description('Switch active profile').action(use
|
|
|
62
63
|
|
|
63
64
|
program.command('init').description('Initialize a Globio project').option('--profile <name>', 'Use a specific profile').action(init);
|
|
64
65
|
|
|
66
|
+
const profiles = program
|
|
67
|
+
.command('profiles')
|
|
68
|
+
.description('Manage login profiles')
|
|
69
|
+
.action(profilesList);
|
|
70
|
+
|
|
71
|
+
profiles
|
|
72
|
+
.command('list')
|
|
73
|
+
.description('List all profiles')
|
|
74
|
+
.action(profilesList);
|
|
75
|
+
|
|
65
76
|
const projects = program.command('projects').description('Manage projects');
|
|
66
77
|
projects.command('list').description('List projects').option('--profile <name>', 'Use a specific profile').action(projectsList);
|
|
67
78
|
projects.command('create').description('Create a project').option('--profile <name>', 'Use a specific profile').action(projectsCreate);
|