@geolonia/geonicdb-cli 0.8.0 → 0.9.0

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
@@ -186,6 +186,15 @@ function printInfo(message) {
186
186
  function printWarning(message) {
187
187
  console.error(chalk.yellow(message));
188
188
  }
189
+ function printApiKeyBox(key) {
190
+ const border = "\u2500".repeat(key.length + 4);
191
+ console.error("");
192
+ console.error(chalk.green(` \u250C${border}\u2510`));
193
+ console.error(chalk.green(` \u2502 ${chalk.bold(key)} \u2502`));
194
+ console.error(chalk.green(` \u2514${border}\u2518`));
195
+ console.error("");
196
+ console.error(chalk.yellow("\u26A0 \u3053\u306E API \u30AD\u30FC\u5024\u3092\u5B89\u5168\u306B\u4FDD\u5B58\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u4E8C\u5EA6\u3068\u8868\u793A\u3055\u308C\u307E\u305B\u3093\u3002"));
197
+ }
189
198
  function printCount(count) {
190
199
  console.log(chalk.dim(`Count: ${count}`));
191
200
  }
@@ -1477,6 +1486,45 @@ function addMeOAuthClientsSubcommand(me) {
1477
1486
  }
1478
1487
 
1479
1488
  // src/commands/me-api-keys.ts
1489
+ function cleanApiKeyData(data) {
1490
+ if (Array.isArray(data)) return data.map(cleanApiKeyData);
1491
+ if (typeof data !== "object" || data === null) return data;
1492
+ const obj = { ...data };
1493
+ if (obj.key === "******") delete obj.key;
1494
+ return obj;
1495
+ }
1496
+ function handleSaveKey(data, cmd) {
1497
+ const globalOpts = resolveOptions(cmd);
1498
+ const key = data.key;
1499
+ if (!key) {
1500
+ printError("Response missing key. API key was created, but it could not be saved.");
1501
+ process.exitCode = 1;
1502
+ return false;
1503
+ }
1504
+ try {
1505
+ const config = loadConfig(globalOpts.profile);
1506
+ config.apiKey = key;
1507
+ saveConfig(config, globalOpts.profile);
1508
+ console.error("API key saved to config. X-Api-Key header will be sent automatically.");
1509
+ return true;
1510
+ } catch (err) {
1511
+ printError(`Failed to save API key to config: ${err instanceof Error ? err.message : String(err)}`);
1512
+ printApiKeyBox(key);
1513
+ process.exitCode = 1;
1514
+ return false;
1515
+ }
1516
+ }
1517
+ function showKeyResult(data, save, cmd) {
1518
+ const key = data.key;
1519
+ if (!key) {
1520
+ printError("Response missing key. The new API key value was not returned.");
1521
+ process.exitCode = 1;
1522
+ return false;
1523
+ }
1524
+ if (save) return handleSaveKey(data, cmd);
1525
+ printApiKeyBox(key);
1526
+ return true;
1527
+ }
1480
1528
  function addMeApiKeysSubcommand(me) {
1481
1529
  const apiKeys = me.command("api-keys").description("Manage your API keys");
1482
1530
  const list = apiKeys.command("list").description("List your API keys").action(
@@ -1484,7 +1532,9 @@ function addMeApiKeysSubcommand(me) {
1484
1532
  const client = createClient(cmd);
1485
1533
  const format = getFormat(cmd);
1486
1534
  const response = await client.rawRequest("GET", "/me/api-keys");
1535
+ response.data = cleanApiKeyData(response.data);
1487
1536
  outputResponse(response, format);
1537
+ console.error("\u203B API \u30AD\u30FC\u5024\u306F\u4F5C\u6210\u6642 (create) \u307E\u305F\u306F\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u6642 (refresh) \u306B\u306E\u307F\u8868\u793A\u3055\u308C\u307E\u3059\u3002");
1488
1538
  })
1489
1539
  );
1490
1540
  addExamples(list, [
@@ -1540,24 +1590,9 @@ function addMeApiKeysSubcommand(me) {
1540
1590
  const format = getFormat(cmd);
1541
1591
  const response = await client.rawRequest("POST", "/me/api-keys", { body });
1542
1592
  const data = response.data;
1543
- if (opts.save) {
1544
- const globalOpts = resolveOptions(cmd);
1545
- const key = data.key;
1546
- if (!key) {
1547
- printError("Response missing key. API key was created, but it could not be saved.");
1548
- outputResponse(response, format);
1549
- process.exitCode = 1;
1550
- return;
1551
- }
1552
- const config = loadConfig(globalOpts.profile);
1553
- config.apiKey = key;
1554
- saveConfig(config, globalOpts.profile);
1555
- console.error("API key saved to config. X-Api-Key header will be sent automatically.");
1556
- } else {
1557
- printWarning("Save the API key now \u2014 it will not be shown again. Use --save to store it automatically.");
1558
- }
1593
+ const ok = showKeyResult(data, !!opts.save, cmd);
1559
1594
  outputResponse(response, format);
1560
- console.error("API key created.");
1595
+ if (ok) console.error("API key created.");
1561
1596
  })
1562
1597
  );
1563
1598
  addNotes(create, [
@@ -1586,6 +1621,35 @@ function addMeApiKeysSubcommand(me) {
1586
1621
  command: "geonic me api-keys create --name my-app --dpop-required"
1587
1622
  }
1588
1623
  ]);
1624
+ const refresh = apiKeys.command("refresh <keyId>").description("Refresh (rotate) an API key \u2014 generates a new key value").option("--save", "Save the new API key to config for automatic use").action(
1625
+ withErrorHandler(async (keyId, _opts, cmd) => {
1626
+ const opts = cmd.opts();
1627
+ const client = createClient(cmd);
1628
+ const format = getFormat(cmd);
1629
+ const response = await client.rawRequest(
1630
+ "POST",
1631
+ `/me/api-keys/${encodeURIComponent(String(keyId))}/refresh`
1632
+ );
1633
+ const data = response.data;
1634
+ const ok = showKeyResult(data, !!opts.save, cmd);
1635
+ outputResponse(response, format);
1636
+ if (ok) console.error("API key refreshed.");
1637
+ })
1638
+ );
1639
+ addNotes(refresh, [
1640
+ "Refreshing generates a new key value while keeping keyId, name, and policy settings.",
1641
+ "The previous key value is immediately invalidated."
1642
+ ]);
1643
+ addExamples(refresh, [
1644
+ {
1645
+ description: "Refresh an API key",
1646
+ command: "geonic me api-keys refresh <key-id>"
1647
+ },
1648
+ {
1649
+ description: "Refresh and save new key to config",
1650
+ command: "geonic me api-keys refresh <key-id> --save"
1651
+ }
1652
+ ]);
1589
1653
  const update = apiKeys.command("update <keyId> [json]").description("Update an API key").option("--name <name>", "Key name").option("--policy-id <policyId>", "Policy ID to attach (use 'null' to unbind)").option("--origins <origins>", "Allowed origins (comma-separated)").option("--rate-limit <n>", "Rate limit (requests per minute)").option("--dpop-required", "Require DPoP token binding").option("--no-dpop-required", "Disable DPoP requirement").option("--active", "Activate the API key").option("--inactive", "Deactivate the API key").action(
1590
1654
  withErrorHandler(async (keyId, json, _opts, cmd) => {
1591
1655
  const opts = cmd.opts();
@@ -1886,10 +1950,10 @@ function createLoginCommand() {
1886
1950
  process.exit(1);
1887
1951
  }
1888
1952
  const availableTenants = data.availableTenants;
1889
- const currentTenantId = data.tenantId;
1953
+ let finalTenantId = data.tenantId;
1890
1954
  if (availableTenants && availableTenants.length > 1 && !loginOpts.tenantId) {
1891
- const selectedTenantId = await promptTenantSelection(availableTenants, currentTenantId);
1892
- if (selectedTenantId && selectedTenantId !== currentTenantId) {
1955
+ const selectedTenantId = await promptTenantSelection(availableTenants, finalTenantId);
1956
+ if (selectedTenantId && selectedTenantId !== finalTenantId) {
1893
1957
  const reloginResponse = await client.rawRequest("POST", "/auth/login", {
1894
1958
  body: { email, password, tenantId: selectedTenantId },
1895
1959
  skipTenantHeader: true
@@ -1902,6 +1966,7 @@ function createLoginCommand() {
1902
1966
  }
1903
1967
  token = newToken;
1904
1968
  refreshToken = reloginData.refreshToken;
1969
+ finalTenantId = selectedTenantId;
1905
1970
  }
1906
1971
  }
1907
1972
  const config = loadConfig(globalOpts.profile);
@@ -1911,6 +1976,11 @@ function createLoginCommand() {
1911
1976
  } else {
1912
1977
  delete config.refreshToken;
1913
1978
  }
1979
+ if (finalTenantId) {
1980
+ config.service = finalTenantId;
1981
+ } else {
1982
+ delete config.service;
1983
+ }
1914
1984
  saveConfig(config, globalOpts.profile);
1915
1985
  printSuccess("Login successful. Token saved to config.");
1916
1986
  })
@@ -3941,6 +4011,13 @@ function registerCaddeCommand(parent) {
3941
4011
  }
3942
4012
 
3943
4013
  // src/commands/admin/api-keys.ts
4014
+ function cleanApiKeyData2(data) {
4015
+ if (Array.isArray(data)) return data.map(cleanApiKeyData2);
4016
+ if (typeof data !== "object" || data === null) return data;
4017
+ const obj = { ...data };
4018
+ if (obj.key === "******") delete obj.key;
4019
+ return obj;
4020
+ }
3944
4021
  function validateOrigins(body, opts) {
3945
4022
  if (opts.origins !== void 0) {
3946
4023
  const origins = String(opts.origins).split(",").map((s) => s.trim()).filter(Boolean);
@@ -3979,6 +4056,38 @@ function buildBodyFromFlags(opts) {
3979
4056
  if (opts.tenantId) payload.tenantId = opts.tenantId;
3980
4057
  return payload;
3981
4058
  }
4059
+ function handleSaveKey2(data, cmd) {
4060
+ const globalOpts = resolveOptions(cmd);
4061
+ const key = data.key;
4062
+ if (!key) {
4063
+ printError("Response missing key. API key was created, but it could not be saved.");
4064
+ process.exitCode = 1;
4065
+ return false;
4066
+ }
4067
+ try {
4068
+ const config = loadConfig(globalOpts.profile);
4069
+ config.apiKey = key;
4070
+ saveConfig(config, globalOpts.profile);
4071
+ console.error("API key saved to config. X-Api-Key header will be sent automatically.");
4072
+ return true;
4073
+ } catch (err) {
4074
+ printError(`Failed to save API key to config: ${err instanceof Error ? err.message : String(err)}`);
4075
+ printApiKeyBox(key);
4076
+ process.exitCode = 1;
4077
+ return false;
4078
+ }
4079
+ }
4080
+ function showKeyResult2(data, save, cmd) {
4081
+ const key = data.key;
4082
+ if (!key) {
4083
+ printError("Response missing key. The new API key value was not returned.");
4084
+ process.exitCode = 1;
4085
+ return false;
4086
+ }
4087
+ if (save) return handleSaveKey2(data, cmd);
4088
+ printApiKeyBox(key);
4089
+ return true;
4090
+ }
3982
4091
  function registerApiKeysCommand(parent) {
3983
4092
  const apiKeys = parent.command("api-keys").description("Manage API keys");
3984
4093
  const list = apiKeys.command("list").description("List all API keys").option("--tenant-id <id>", "Filter by tenant ID").action(
@@ -3991,7 +4100,9 @@ function registerApiKeysCommand(parent) {
3991
4100
  const response = await client.rawRequest("GET", "/admin/api-keys", {
3992
4101
  params
3993
4102
  });
4103
+ response.data = cleanApiKeyData2(response.data);
3994
4104
  outputResponse(response, format);
4105
+ console.error("\u203B API \u30AD\u30FC\u5024\u306F\u4F5C\u6210\u6642 (create) \u307E\u305F\u306F\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u6642 (refresh) \u306B\u306E\u307F\u8868\u793A\u3055\u308C\u307E\u3059\u3002");
3995
4106
  })
3996
4107
  );
3997
4108
  addExamples(list, [
@@ -4012,6 +4123,7 @@ function registerApiKeysCommand(parent) {
4012
4123
  "GET",
4013
4124
  `/admin/api-keys/${encodeURIComponent(String(keyId))}`
4014
4125
  );
4126
+ response.data = cleanApiKeyData2(response.data);
4015
4127
  outputResponse(response, format);
4016
4128
  })
4017
4129
  );
@@ -4040,24 +4152,9 @@ function registerApiKeysCommand(parent) {
4040
4152
  body
4041
4153
  });
4042
4154
  const data = response.data;
4043
- if (opts.save) {
4044
- const globalOpts = resolveOptions(cmd);
4045
- const key = data.key;
4046
- if (!key) {
4047
- printError("Response missing key. API key was created, but it could not be saved.");
4048
- outputResponse(response, format);
4049
- process.exitCode = 1;
4050
- return;
4051
- }
4052
- const config = loadConfig(globalOpts.profile);
4053
- config.apiKey = key;
4054
- saveConfig(config, globalOpts.profile);
4055
- console.error("API key saved to config. X-Api-Key header will be sent automatically.");
4056
- } else {
4057
- printWarning("Save the API key now \u2014 it will not be shown again. Use --save to store it automatically.");
4058
- }
4155
+ const ok = showKeyResult2(data, !!opts.save, cmd);
4059
4156
  outputResponse(response, format);
4060
- console.error("API key created.");
4157
+ if (ok) console.error("API key created.");
4061
4158
  })
4062
4159
  );
4063
4160
  addNotes(create, [
@@ -4078,6 +4175,35 @@ function registerApiKeysCommand(parent) {
4078
4175
  command: "geonic admin api-keys create @key.json --save"
4079
4176
  }
4080
4177
  ]);
4178
+ const refresh = apiKeys.command("refresh <keyId>").description("Refresh (rotate) an API key \u2014 generates a new key value").option("--save", "Save the new API key to profile config").action(
4179
+ withErrorHandler(async (keyId, _opts, cmd) => {
4180
+ const opts = cmd.opts();
4181
+ const client = createClient(cmd);
4182
+ const format = getFormat(cmd);
4183
+ const response = await client.rawRequest(
4184
+ "POST",
4185
+ `/admin/api-keys/${encodeURIComponent(String(keyId))}/refresh`
4186
+ );
4187
+ const data = response.data;
4188
+ const ok = showKeyResult2(data, !!opts.save, cmd);
4189
+ outputResponse(response, format);
4190
+ if (ok) console.error("API key refreshed.");
4191
+ })
4192
+ );
4193
+ addNotes(refresh, [
4194
+ "Refreshing generates a new key value while keeping keyId, name, and policy settings.",
4195
+ "The previous key value is immediately invalidated."
4196
+ ]);
4197
+ addExamples(refresh, [
4198
+ {
4199
+ description: "Refresh an API key",
4200
+ command: "geonic admin api-keys refresh <key-id>"
4201
+ },
4202
+ {
4203
+ description: "Refresh and save new key to config",
4204
+ command: "geonic admin api-keys refresh <key-id> --save"
4205
+ }
4206
+ ]);
4081
4207
  const update = apiKeys.command("update <keyId> [json]").description("Update an API key").option("--name <name>", "Key name").option("--policy <policyId>", "Policy ID to attach").option("--origins <origins>", "Comma-separated origins").option("--rate-limit <n>", "Rate limit per minute").option("--dpop-required", "Require DPoP token binding").option("--no-dpop-required", "Disable DPoP token binding").action(
4082
4208
  withErrorHandler(
4083
4209
  async (keyId, json, _opts, cmd) => {