@tokenbuddy/tb-admin 1.0.37 → 1.0.39
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/src/cli.js +8 -8
- package/dist/src/config.d.ts +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/ui-static.js +2 -2
- package/dist/src/workdir.js +1 -1
- package/package.json +3 -3
package/dist/src/cli.js
CHANGED
|
@@ -203,7 +203,7 @@ export function buildAdminCli(configManager) {
|
|
|
203
203
|
.option("--token <token>", "Operator Bearer token")
|
|
204
204
|
.option("--profile <profile>", "Use custom profile instead of default")
|
|
205
205
|
.option("--config <path>", "Use custom config file path")
|
|
206
|
-
.option("--workdir <path>", "Admin workdir path (default: $TB_ADMIN_WORKDIR or ~/.config/
|
|
206
|
+
.option("--workdir <path>", "Admin workdir path (default: $TB_ADMIN_WORKDIR or ~/.config/tb-admin)");
|
|
207
207
|
bindAdminUiCommand(program, configManager);
|
|
208
208
|
function getRootConfigManager() {
|
|
209
209
|
const opts = program.opts();
|
|
@@ -216,7 +216,7 @@ export function buildAdminCli(configManager) {
|
|
|
216
216
|
.command("init")
|
|
217
217
|
.description("Initialize an admin workdir for provider-specific deployment assets")
|
|
218
218
|
.option("--provider <provider>", "Deployment provider (default: fly.io)", "fly.io")
|
|
219
|
-
.option("--workdir <path>", "Admin workdir path (default: root --workdir, $TB_ADMIN_WORKDIR, or ~/.config/
|
|
219
|
+
.option("--workdir <path>", "Admin workdir path (default: root --workdir, $TB_ADMIN_WORKDIR, or ~/.config/tb-admin)")
|
|
220
220
|
.option("--check-only", "Only check provider requirements; do not write files")
|
|
221
221
|
.option("--force", "Refresh regenerable templates without overwriting runtime secret files")
|
|
222
222
|
.option("--install-tools", "Install missing provider CLI tools when supported")
|
|
@@ -1158,13 +1158,13 @@ export function buildAdminCli(configManager) {
|
|
|
1158
1158
|
}
|
|
1159
1159
|
});
|
|
1160
1160
|
// Step 14 (v1.1): 多 vendor 实例隔离.
|
|
1161
|
-
// 默认 config dir 改成 ~/.config/
|
|
1161
|
+
// 默认 config dir 改成 ~/.config/tb-admin/profiles/*.toml, 每个 vendor 一份 config.
|
|
1162
1162
|
// 启动时 tb-admin (没传 --config) 会扫描 profiles/ 合并成一个虚拟配置 (default_profile 仍来自
|
|
1163
|
-
// ~/.config/
|
|
1163
|
+
// ~/.config/tb-admin/admin.toml). `tb-admin config ls` 列出当前 active file,
|
|
1164
1164
|
// `tb-admin config profiles` 扫描 profiles/ 列出所有 vendor file.
|
|
1165
1165
|
configCmd
|
|
1166
1166
|
.command("profiles")
|
|
1167
|
-
.description("Scan the vendor profiles directory (~/.config/
|
|
1167
|
+
.description("Scan the vendor profiles directory (~/.config/tb-admin/profiles/) and list every vendor config")
|
|
1168
1168
|
.action(() => {
|
|
1169
1169
|
const profileDir = defaultProfileDir();
|
|
1170
1170
|
const files = listProfileFiles(profileDir);
|
|
@@ -1530,8 +1530,8 @@ function collectIds(value, previous) {
|
|
|
1530
1530
|
return previous.concat([value]);
|
|
1531
1531
|
}
|
|
1532
1532
|
// Step 14 (v1.1): 多 vendor 实例 config 隔离.
|
|
1533
|
-
// 默认 profiles 目录是 ~/.config/
|
|
1534
|
-
// 默认主 config 仍走 ~/.config/
|
|
1533
|
+
// 默认 profiles 目录是 ~/.config/tb-admin/profiles/, 每个 vendor 一份独立 toml.
|
|
1534
|
+
// 默认主 config 仍走 ~/.config/tb-admin/admin.toml (default_profile 在此设).
|
|
1535
1535
|
// 用户可以:
|
|
1536
1536
|
// - tb-admin --config /path/to/vendor-A.toml config ls (单 vendor 显式)
|
|
1537
1537
|
// - tb-admin config profiles (扫 profiles/ 看所有 vendor)
|
|
@@ -1541,7 +1541,7 @@ function defaultProfileDir() {
|
|
|
1541
1541
|
if (override) {
|
|
1542
1542
|
return path.join(override, "profiles");
|
|
1543
1543
|
}
|
|
1544
|
-
return path.join(process.env.HOME || "", ".config", "
|
|
1544
|
+
return path.join(process.env.HOME || "", ".config", "tb-admin", "profiles");
|
|
1545
1545
|
}
|
|
1546
1546
|
function listProfileFiles(dir) {
|
|
1547
1547
|
if (!fs.existsSync(dir)) {
|
package/dist/src/config.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface AdminConfig {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* 解析 admin CLI 的默认配置路径:`~/.config/
|
|
53
|
+
* 解析 admin CLI 的默认配置路径:`~/.config/tb-admin/admin.toml`。
|
|
54
54
|
* 兼容旧版 `~/.tokenbuddy/admin.json`(legacy JSON),由 `ConfigManager` 自动识别。
|
|
55
55
|
*
|
|
56
56
|
* @returns 配置文件绝对路径
|
package/dist/src/config.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as os from "os";
|
|
|
4
4
|
import TOML from "@iarna/toml";
|
|
5
5
|
import { defaultAdminConfigPath, defaultAdminWorkdir, resolveAdminConfigPath, resolveAdminWorkdir } from "./workdir.js";
|
|
6
6
|
/**
|
|
7
|
-
* 解析 admin CLI 的默认配置路径:`~/.config/
|
|
7
|
+
* 解析 admin CLI 的默认配置路径:`~/.config/tb-admin/admin.toml`。
|
|
8
8
|
* 兼容旧版 `~/.tokenbuddy/admin.json`(legacy JSON),由 `ConfigManager` 自动识别。
|
|
9
9
|
*
|
|
10
10
|
* @returns 配置文件绝对路径
|
package/dist/src/ui-static.js
CHANGED
|
@@ -623,7 +623,7 @@ function renderDetail(){
|
|
|
623
623
|
const d = currentDetail;
|
|
624
624
|
document.getElementById("detailTitle").textContent = d.row.name + " detail";
|
|
625
625
|
document.getElementById("editDetail").textContent = editing ? "Save changes" : "Edit config";
|
|
626
|
-
document.getElementById("deleteSeller").title =
|
|
626
|
+
document.getElementById("deleteSeller").title = "Delete deployment";
|
|
627
627
|
showDetailStatus(d.row.error || "", false);
|
|
628
628
|
document.getElementById("detailGrid").classList.remove("hidden");
|
|
629
629
|
const c = d.configuration;
|
|
@@ -647,7 +647,7 @@ function setStatusActionBusy(busy){ document.querySelectorAll("[data-status-acti
|
|
|
647
647
|
function setDetailSavingBusy(busy){ const edit = document.getElementById("editDetail"); edit.disabled = Boolean(busy); edit.textContent = busy ? "Saving" : (editing ? "Save changes" : "Edit config"); document.querySelectorAll("#detailGrid [data-field], #detailGrid [data-model], #detailGrid [data-model-enabled], [data-status-action], #deleteSeller").forEach(input => { input.disabled = Boolean(busy); }); }
|
|
648
648
|
document.getElementById("editDetail").onclick = async () => { if (!editing){ editing = true; renderDetail(); return; } const patch = {}; document.querySelectorAll("[data-field]").forEach(input => { const value = input.value; if (value === "" || value === input.dataset.original) return; patch[input.dataset.field] = numeric(value); }); const aliases = {}; document.querySelectorAll("[data-model]").forEach(input => aliases[input.dataset.model] = input.value); patch.modelAliases = aliases; patch.models = modelConfigPatchFromDetail(); try { setDetailSavingBusy(true); showDetailStatus("Saving seller config", true); const result = await api("/api/sellers/"+encodeURIComponent(currentDetail.row.id)+"/config", { method:"PUT", body: JSON.stringify(patch) }); if (!result.ok) throw new Error(result.stderr || "Save failed"); currentDetail = await api("/api/sellers/"+encodeURIComponent(currentDetail.row.id)); editing = false; renderDetail(); loadSellers(); } catch (err) { showDetailStatus(err.message || "Save failed", false); } finally { setDetailSavingBusy(false); } };
|
|
649
649
|
function modelConfigPatchFromDetail(){ const enabledByModel = {}; document.querySelectorAll("[data-model-enabled]").forEach(input => enabledByModel[input.dataset.modelEnabled] = Boolean(input.checked)); return (currentDetail?.models || []).map(model => ({ ...(model.configModel || { id:model.upstreamModel }), id:model.upstreamModel, enabled: enabledByModel[model.upstreamModel] !== false })); }
|
|
650
|
-
document.getElementById("deleteSeller").onclick = async () => { if (!currentDetail) return; if (
|
|
650
|
+
document.getElementById("deleteSeller").onclick = async () => { if (!currentDetail) return; if (!confirm("Destroy deployment for "+currentDetail.row.name+"?")) return; try { setDetailSavingBusy(true); showDetailStatus("Destroying deployment", true); const result = await api("/api/sellers/"+encodeURIComponent(currentDetail.row.id)+"/deployment", { method:"DELETE", body: JSON.stringify({ confirm: true }) }); if (!result.ok) throw new Error(result.stderr || "Deployment destroy failed."); showDetailStatus(result.stdout || "Deployment destroy requested.", false); deleteReady = false; document.getElementById("deleteSeller").title = "Delete deployment"; loadSellers(); } catch (err) { showDetailStatus(err.message || "Deployment destroy failed.", false); } finally { setDetailSavingBusy(false); } };
|
|
651
651
|
document.getElementById("closeDetail").onclick = () => { deleteReady = false; document.getElementById("detailModal").classList.remove("open"); };
|
|
652
652
|
document.getElementById("hideNoInstanceApps").onchange = event => { hideNoInstanceApps = Boolean(event.target.checked); renderSellerRows(sellerRowsCache); };
|
|
653
653
|
document.querySelectorAll("[data-status-action]").forEach(btn => btn.onclick = async () => { if (!currentDetail) return; const action = btn.dataset.statusAction; const id = currentDetail.row.id; const status = registryStatusForAction(action); try { setStatusActionBusy(true); showDetailStatus("Updating registry status", true); const result = await api("/api/sellers/"+encodeURIComponent(id)+"/"+action, { method:"POST" }); if (!result.ok) throw new Error(result.stderr || "Status update failed."); patchSellerRegistryStatus(id, status); deleteReady = false; currentDetail = null; document.getElementById("detailModal").classList.remove("open"); } catch (err) { showDetailStatus(err.message || "Status update failed.", false); } finally { setStatusActionBusy(false); } });
|
package/dist/src/workdir.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as os from "os";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
export const TB_ADMIN_WORKDIR_ENV = "TB_ADMIN_WORKDIR";
|
|
4
4
|
export const TOKENBUDDY_ADMIN_CONFIG_ENV = "TOKENBUDDY_ADMIN_CONFIG";
|
|
5
|
-
export const DEFAULT_ADMIN_WORKDIR_RELATIVE = path.join(".config", "
|
|
5
|
+
export const DEFAULT_ADMIN_WORKDIR_RELATIVE = path.join(".config", "tb-admin");
|
|
6
6
|
function expandHome(input, homeDir) {
|
|
7
7
|
if (input === "~") {
|
|
8
8
|
return homeDir;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenbuddy/tb-admin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39",
|
|
4
4
|
"description": "Remote admin CLI for TokenBuddy seller apps",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|
|
9
|
-
"tb-admin": "
|
|
9
|
+
"tb-admin": "bin/tb-admin.js"
|
|
10
10
|
},
|
|
11
11
|
"private": false,
|
|
12
12
|
"files": [
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@iarna/toml": "^2.2.5",
|
|
23
|
-
"@tokenbuddy/contracts": "^1.0.
|
|
23
|
+
"@tokenbuddy/contracts": "^1.0.39",
|
|
24
24
|
"@types/js-yaml": "^4.0.9",
|
|
25
25
|
"cli-table3": "^0.6.4",
|
|
26
26
|
"commander": "^12.0.0",
|