@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 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/services.ts
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(chalk9.cyan("Available Globio services:"));
874
+ console.log(chalk10.cyan("Available Globio services:"));
838
875
  ALL_SERVICES.forEach((service) => {
839
- console.log(" " + chalk9.white(service));
876
+ console.log(" " + chalk10.white(service));
840
877
  });
841
878
  console.log("");
842
879
  console.log(
843
- chalk9.gray("Manage service access via console.globio.stanlink.online")
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 chalk10 from "chalk";
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(chalk10.gray("No functions found."));
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(chalk10.yellow(`${filename} already exists.`));
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(chalk10.green(`Created ${filename}`));
935
+ console.log(chalk11.green(`Created ${filename}`));
899
936
  console.log(
900
- chalk10.gray(`Deploy with: npx @globio/cli functions deploy ${slug}`)
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
- chalk10.red(
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(chalk10.red("--input must be valid JSON"));
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(chalk10.red("Invocation failed"));
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(chalk10.gray("No invocations yet."));
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} ${chalk10.gray(date)} ${inv.duration_ms}ms ${chalk10.gray(`[${inv.trigger_type}]`)}`
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globio/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "license": "MIT",
5
5
  "exports": "./src/index.ts"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globio/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "The official CLI for Globio — game backend as a service",
5
5
  "type": "module",
6
6
  "license": "MIT",
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);