@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 +163 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
1953
|
+
let finalTenantId = data.tenantId;
|
|
1890
1954
|
if (availableTenants && availableTenants.length > 1 && !loginOpts.tenantId) {
|
|
1891
|
-
const selectedTenantId = await promptTenantSelection(availableTenants,
|
|
1892
|
-
if (selectedTenantId && selectedTenantId !==
|
|
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
|
-
|
|
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) => {
|