@tokenbuddy/tb-admin 1.0.30 → 1.0.32
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.d.ts.map +1 -1
- package/dist/src/cli.js +280 -19
- package/dist/src/cli.js.map +1 -1
- package/dist/src/client.d.ts +82 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +93 -0
- package/dist/src/client.js.map +1 -1
- package/dist/src/provider.d.ts +120 -0
- package/dist/src/provider.d.ts.map +1 -0
- package/dist/src/provider.js +73 -0
- package/dist/src/provider.js.map +1 -0
- package/dist/src/seller.d.ts +104 -0
- package/dist/src/seller.d.ts.map +1 -0
- package/dist/src/seller.js +283 -0
- package/dist/src/seller.js.map +1 -0
- package/dist/src/ui-actions.d.ts +25 -0
- package/dist/src/ui-actions.d.ts.map +1 -1
- package/dist/src/ui-actions.js +81 -11
- package/dist/src/ui-actions.js.map +1 -1
- package/dist/src/ui-server.js +9 -0
- package/dist/src/ui-server.js.map +1 -1
- package/dist/src/ui-state.d.ts +77 -2
- package/dist/src/ui-state.d.ts.map +1 -1
- package/dist/src/ui-state.js +242 -14
- package/dist/src/ui-state.js.map +1 -1
- package/dist/src/ui-static.d.ts.map +1 -1
- package/dist/src/ui-static.js +95 -17
- package/dist/src/ui-static.js.map +1 -1
- package/dist/src/vendor-client.d.ts +23 -0
- package/dist/src/vendor-client.d.ts.map +1 -0
- package/dist/src/vendor-client.js +2 -0
- package/dist/src/vendor-client.js.map +1 -0
- package/dist/src/vendor-commands.d.ts +35 -0
- package/dist/src/vendor-commands.d.ts.map +1 -0
- package/dist/src/vendor-commands.js +33 -0
- package/dist/src/vendor-commands.js.map +1 -0
- package/package.json +1 -1
- package/src/cli.ts +305 -31
- package/src/client.ts +119 -2
- package/src/provider.ts +150 -0
- package/src/seller.ts +362 -0
- package/src/ui-actions.ts +89 -11
- package/src/ui-server.ts +9 -0
- package/src/ui-state.ts +293 -15
- package/src/ui-static.ts +95 -17
- package/src/vendor-client.ts +23 -0
- package/src/vendor-commands.ts +65 -0
- package/tests/admin.test.ts +20 -1
- package/tests/seller.test.ts +307 -0
- package/tests/ui-state-fleet.test.ts +257 -0
- package/tests/ui-static-row.test.ts +202 -0
- package/tests/vendor-cli.test.ts +197 -0
package/dist/src/ui-static.js
CHANGED
|
@@ -77,6 +77,25 @@ export function adminUiHtml() {
|
|
|
77
77
|
.app-table-head{min-height:34px;color:var(--muted);font-size:var(--label-fs);font-weight:var(--label-weight);text-transform:uppercase;letter-spacing:var(--label-spacing)}
|
|
78
78
|
.app-row{border:1px solid var(--hairline);border-radius:8px;background:#fff;min-height:76px;text-align:left}
|
|
79
79
|
.app-row:hover{border-color:var(--hairline-strong);background:#fff}
|
|
80
|
+
/* Step 13 v1.1: 双源 (fly + registry) 4 类行视觉. dataSource 决定
|
|
81
|
+
dataSource="fly" → 灰/中性边, "未发布" 提示
|
|
82
|
+
dataSource="registry" → 整行红边 + 软红底, "立即下线 (registry-only)" 按钮
|
|
83
|
+
dataSource="both" → 正常边, 跟 1.0.31 老样式一致
|
|
84
|
+
*/
|
|
85
|
+
.app-row.app-row-fly-only{border-color:#cdd2db;background:#f8f9fc}
|
|
86
|
+
.app-row.app-row-fly-only:hover{background:#f1f3f8}
|
|
87
|
+
.app-row.app-row-registry-only{border:2px solid var(--danger);background:var(--danger-soft);box-shadow:0 0 0 3px rgba(239,91,120,.08)}
|
|
88
|
+
.app-row.app-row-registry-only:hover{background:#ffe3ea}
|
|
89
|
+
.datasource-chip{display:inline-block;padding:1px 8px;border-radius:999px;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;line-height:16px;margin-left:6px;vertical-align:middle}
|
|
90
|
+
.datasource-chip.both{background:#e7f6ee;color:#0a8754}
|
|
91
|
+
.datasource-chip.fly{background:#e3e6ee;color:#4a5170}
|
|
92
|
+
.datasource-chip.registry{background:var(--danger-soft);color:var(--danger);border:1px solid var(--danger)}
|
|
93
|
+
.alert-reason{color:var(--danger);font-size:11px;line-height:1.4;font-weight:700;margin-top:4px;display:block}
|
|
94
|
+
.remove-hint-btn{margin-top:6px;background:var(--danger);color:#fff;border:0;border-radius:6px;padding:4px 10px;font-size:11px;font-weight:800;cursor:pointer;display:inline-block}
|
|
95
|
+
.remove-hint-btn:hover{background:#d63d5a}
|
|
96
|
+
.remove-hint-btn::before{content:"⚠ ";margin-right:2px}
|
|
97
|
+
.publish-hint-btn{margin-top:6px;background:#fff;color:var(--primary);border:1px solid var(--hairline-strong);border-radius:6px;padding:4px 10px;font-size:11px;font-weight:800;cursor:pointer;display:inline-block}
|
|
98
|
+
.publish-hint-btn:hover{background:#f5f3ff}
|
|
80
99
|
/* Status dot — five spec tones (green/amber/red/blue/gray) */
|
|
81
100
|
.app-dot{width:10px;height:10px;border-radius:999px;background:#c8ced8;box-shadow:0 0 0 4px #edf1f8}
|
|
82
101
|
.app-dot.tone-green{background:var(--success);box-shadow:0 0 0 4px rgba(16,185,129,.18)}
|
|
@@ -193,7 +212,7 @@ export function adminUiHtml() {
|
|
|
193
212
|
</style>
|
|
194
213
|
</head>
|
|
195
214
|
<body>
|
|
196
|
-
<nav class="topnav"><div class="logo">TOKENBUDDY ADMIN</div><div class="top-links"><button class="top-link active" data-page="sellers">Sellers</button><button class="top-link" data-page="
|
|
215
|
+
<nav class="topnav"><div class="logo">TOKENBUDDY ADMIN</div><div class="top-links"><button class="top-link active" data-page="sellers">Sellers</button><button class="top-link" data-page="releases">Release Requests</button></div></nav>
|
|
197
216
|
<main class="content">
|
|
198
217
|
<section id="page-sellers" class="page active">
|
|
199
218
|
<div class="panel">
|
|
@@ -221,13 +240,17 @@ export function adminUiHtml() {
|
|
|
221
240
|
<section id="page-bootstrap" class="page">
|
|
222
241
|
<div class="bootstrap-card">
|
|
223
242
|
<div class="panel-head">
|
|
224
|
-
<h1 class="title">
|
|
243
|
+
<h1 class="title">Release Requests</h1>
|
|
225
244
|
<div class="modal-actions">
|
|
226
|
-
<button id="
|
|
227
|
-
<button id="refreshBootstrap" class="btn">Refresh</button>
|
|
245
|
+
<button id="refreshReleases" class="btn">Refresh</button>
|
|
228
246
|
</div>
|
|
229
247
|
</div>
|
|
230
|
-
<
|
|
248
|
+
<p class="hint" style="color:var(--muted);font-size:12px;margin:0 0 12px;">
|
|
249
|
+
Pending and historical release requests you have submitted to the wallet-bootstrap
|
|
250
|
+
registry. Force-publish is available to the platform super-admin via the registry
|
|
251
|
+
admin web; vendors do not publish their own releases.
|
|
252
|
+
</p>
|
|
253
|
+
<div id="releasesGrid" class="bootstrap-grid"></div>
|
|
231
254
|
</div>
|
|
232
255
|
</section>
|
|
233
256
|
</main>
|
|
@@ -338,6 +361,17 @@ function scheduleSellerRefresh(){ clearTimeout(sellerRefreshTimer); sellerNextRe
|
|
|
338
361
|
function updateSellerRefreshMeta(refreshing){ const state = document.getElementById("sellerRefreshState"); if (!state) return; const nextSeconds = sellerNextRefreshAt ? Math.max(0, Math.ceil((sellerNextRefreshAt.getTime() - Date.now()) / 1000)) : 0; state.classList.toggle("refreshing", Boolean(refreshing)); state.classList.toggle("error", Boolean(sellerRefreshError)); state.innerHTML = refreshing ? '<span class="spinner" aria-hidden="true"></span><span>Refreshing</span>' : esc(sellerRefreshError || (sellerRefreshLoaded ? "Next refresh: " + nextSeconds + "s" : "Starting")); }
|
|
339
362
|
function sellerRow(row){
|
|
340
363
|
const fmt = window.__tbFmt;
|
|
364
|
+
// Step 13 v1.1: dataSource 决定行 class + 标红/灰 + 按钮 + chip.
|
|
365
|
+
// row.dataSource ∈ "fly" | "registry" | "both". 老 1.0.31 没这个字段,
|
|
366
|
+
// 兜底当 "both" (老 UI 看到的所有行, 默认都按已发布处理).
|
|
367
|
+
const ds = row.dataSource || "both";
|
|
368
|
+
const rowClass = ds === "registry" ? "app-row app-row-registry-only"
|
|
369
|
+
: ds === "fly" ? "app-row app-row-fly-only"
|
|
370
|
+
: "app-row";
|
|
371
|
+
const dsChipLabel = ds === "registry" ? "Registry-only"
|
|
372
|
+
: ds === "fly" ? "未发布"
|
|
373
|
+
: "Both";
|
|
374
|
+
const dsChip = '<span class="datasource-chip '+esc(ds)+'" title="'+esc('Data source: ' + ds + '. 详见 docs/processes/seller-fleet-data-sources.md')+'">'+esc(dsChipLabel)+'</span>';
|
|
341
375
|
const tip = [row.description, row.region, row.app, row.specs?.memoryGb ? row.specs.memoryGb + "GB" : "", row.specs?.machines ? row.specs.machines + " machines" : "", row.modelsCount ? row.modelsCount + " models" : ""].filter(Boolean).join(" · ") || "No specs";
|
|
342
376
|
const ttftText = fmt.formatDuration(row.ttftMs);
|
|
343
377
|
const ttft = "TTFT: " + (ttftText === fmt.UNKNOWN_VALUE ? "—" : ttftText);
|
|
@@ -348,9 +382,11 @@ function sellerRow(row){
|
|
|
348
382
|
const balanceRaw = row.upstreamBalanceUsdMicros;
|
|
349
383
|
const balanceText = (balanceRaw === undefined || balanceRaw === null) ? dash() : '<strong>'+esc(fmt.formatBalanceAmount(balanceRaw, row.upstreamBalanceCurrency || "USD"))+'</strong>';
|
|
350
384
|
const switchText = row.lastSwitchAt ? "Switch " + esc(fmt.formatTimeCompact(row.lastSwitchAt)) : "";
|
|
385
|
+
// Step 13 v1.1: 绿点 (status + tone) 仍按 nodeStatus 决定 (probeManifest
|
|
386
|
+
// 200 → active 绿点; 失败 → unknown 灰). registryStatus 单独 tooltip.
|
|
351
387
|
const status = fmt.formatSellerStatus(row.nodeStatus);
|
|
352
388
|
const tone = fmt.sellerStatusTone(row.nodeStatus);
|
|
353
|
-
const statusTip = "registry: " + esc(fmt.formatSellerStatus(row.registryStatus)) + " · upstream: " + esc(fmt.normalizeStatusLabel(row.upstreamStatus));
|
|
389
|
+
const statusTip = "registry: " + esc(fmt.formatSellerStatus(row.registryStatus)) + " · upstream: " + esc(fmt.normalizeStatusLabel(row.upstreamStatus)) + " · source: " + esc(ds);
|
|
354
390
|
const sellerLine = [
|
|
355
391
|
disc !== fmt.UNKNOWN_VALUE ? "Disc " + esc(disc) : null,
|
|
356
392
|
capacity !== fmt.UNKNOWN_VALUE ? capacity : null,
|
|
@@ -358,19 +394,55 @@ function sellerRow(row){
|
|
|
358
394
|
balanceText.includes("<strong>") ? "Balance " + esc(balanceText.replace(/<[^>]+>/g, "")) : null,
|
|
359
395
|
switchText || null
|
|
360
396
|
].filter(Boolean).join(" · ");
|
|
361
|
-
|
|
397
|
+
// Step 13 v1.1: 4 类行的 status cell 文案不同.
|
|
398
|
+
// both → 正常 active / draining / offline
|
|
399
|
+
// fly-only → "未发布" (publishHint 提示走 vendor-bootstrap stage)
|
|
400
|
+
// registry → "**严重事故**" + alertReason 红字
|
|
401
|
+
let statusCell;
|
|
402
|
+
if (ds === "registry") {
|
|
403
|
+
statusCell = '<span class="field-cell"><strong class="registry-incident" title="'+esc(statusTip)+'">严重事故</strong>' +
|
|
404
|
+
(row.alertReason ? '<span class="alert-reason">'+esc(row.alertReason)+'</span>' : '') +
|
|
405
|
+
(row.removeHint ? '<button class="remove-hint-btn" type="button" data-action="remove" data-seller-id="'+esc(row.id)+'" title="'+esc(row.removeHint)+'">'+esc(row.removeHint)+'</button>' : '') +
|
|
406
|
+
'</span>';
|
|
407
|
+
} else if (ds === "fly") {
|
|
408
|
+
statusCell = '<span class="field-cell"><strong title="'+esc(statusTip)+'">未发布</strong>' +
|
|
409
|
+
(row.publishHint ? '<button class="publish-hint-btn" type="button" data-action="publish" data-seller-id="'+esc(row.id)+'" title="'+esc(row.publishHint)+'">'+esc(row.publishHint)+'</button>' : '') +
|
|
410
|
+
'</span>';
|
|
411
|
+
} else {
|
|
412
|
+
statusCell = '<span class="field-cell"><strong title="'+esc(statusTip)+'">'+esc(status)+'</strong></span>';
|
|
413
|
+
}
|
|
414
|
+
return '<button class="'+esc(rowClass)+'" type="button" data-detail="'+esc(row.id)+'"><span class="app-dot tone-'+esc(tone)+'" aria-label="'+esc(status)+'"></span><span class="app-name"><span class="seller-title"><strong>'+esc(row.name)+'</strong>'+dsChip+'<span class="spec-tip" title="'+esc(tip)+'" aria-label="Seller specs">'+infoIcon+'</span></span><span class="muted-value" style="font-size:12px;font-family:var(--font-mono)">'+esc(sellerLine || row.app || row.id)+'</span></span><span class="field-cell"><strong>'+esc(row.upstreamDomain)+'</strong></span><span class="field-cell"><strong>'+esc(disc === fmt.UNKNOWN_VALUE ? "—" : disc)+'</strong></span><span class="field-cell"><strong>'+esc(capacity)+'</strong></span><span class="speed-cell"><strong>'+esc(ttftText === fmt.UNKNOWN_VALUE ? "—" : ttftText)+'</strong><span>'+avgSpeed+'</span></span><span class="field-cell"><span class="balance-line">'+balanceText+(row.upstreamRechargeUrl ? '<a class="recharge-btn" href="'+esc(row.upstreamRechargeUrl)+'" target="_blank" rel="noreferrer">↗</a>' : '')+'</span></span>'+statusCell+'<span class="row-actions"><span class="detail-btn">›</span></span></button>';
|
|
362
415
|
}
|
|
363
416
|
async function loadBootstrap(){
|
|
417
|
+
// Step 6 of the registry redesign: the legacy Bootstrap tab now
|
|
418
|
+
// surfaces vendor release requests. We keep the function name
|
|
419
|
+
// (loadBootstrap) so the existing click wiring continues to work,
|
|
420
|
+
// but the rendered content comes from the new
|
|
421
|
+
// /api/vendor/release-requests endpoint (added in ui-server.ts).
|
|
364
422
|
const fmt = window.__tbFmt;
|
|
365
423
|
try {
|
|
366
|
-
const data = await api("/api/
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
424
|
+
const data = await api("/api/vendor/release-requests");
|
|
425
|
+
const rows = (data.releaseRequests || []);
|
|
426
|
+
if (rows.length === 0) {
|
|
427
|
+
document.getElementById("bootstrapGrid").innerHTML = '<div class="status-line">No release requests yet. Submit one with <code>tb-admin vendor-bootstrap stage</code> + <code>release submit</code>.</div>';
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const table = '<table style="width:100%;border-collapse:collapse;font-size:13px;">' +
|
|
431
|
+
'<thead><tr><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">ID</th><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">Status</th><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">Sellers</th><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">Submitted</th><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">Version</th><th style="text-align:left;padding:6px 8px;color:var(--muted);text-transform:uppercase;font-size:11px;letter-spacing:0.04em;">Error</th></tr></thead>' +
|
|
432
|
+
'<tbody>' + rows.map((r) => {
|
|
433
|
+
const summary = r.payloadSummary || { count: 0, sellerIds: [] };
|
|
434
|
+
const sellerList = (summary.sellerIds || []).join(", ") || "—";
|
|
435
|
+
const version = r.publishedVersion !== null && r.publishedVersion !== undefined ? "v" + esc(String(r.publishedVersion)) : "—";
|
|
436
|
+
return '<tr>' +
|
|
437
|
+
'<td style="padding:6px 8px;font-family:ui-monospace,monospace;">#' + esc(String(r.id)) + '</td>' +
|
|
438
|
+
'<td style="padding:6px 8px;">' + esc(r.status) + '</td>' +
|
|
439
|
+
'<td style="padding:6px 8px;">' + esc(String(summary.count)) + ' <span style="color:var(--muted);font-size:11px;">(' + esc(sellerList) + ')</span></td>' +
|
|
440
|
+
'<td style="padding:6px 8px;font-family:ui-monospace,monospace;">' + esc(fmt.formatTimeCompact(r.submittedAt)) + '</td>' +
|
|
441
|
+
'<td style="padding:6px 8px;">' + version + '</td>' +
|
|
442
|
+
'<td style="padding:6px 8px;color:var(--danger);">' + (r.errorMessage ? esc(r.errorMessage) : "—") + '</td>' +
|
|
443
|
+
'</tr>';
|
|
444
|
+
}).join("") + '</tbody></table>';
|
|
445
|
+
document.getElementById("bootstrapGrid").innerHTML = table;
|
|
374
446
|
} catch (err) {
|
|
375
447
|
document.getElementById("bootstrapGrid").innerHTML = '<div class="status-line">'+esc(uiErrorMessage(err))+'</div>';
|
|
376
448
|
}
|
|
@@ -458,8 +530,14 @@ function renderCreateJob(job){ if (!job) return; currentCreateJob = job; const d
|
|
|
458
530
|
function progressStep(event){ const result = event.result || {}; const log = [result.command ? "$ " + result.command.join(" ") : "", result.stdout || "", result.stderr || ""].filter(Boolean).join("\\n").slice(0, 1600); const expanded = expandedProgressSteps.has(event.stepId); const spinner = event.status === "running" ? '<span class="spinner" aria-hidden="true"></span>' : ""; return '<button type="button" class="progress-step '+esc(event.status)+'" data-progress-step="'+esc(event.stepId)+'" aria-expanded="'+String(expanded)+'"><div class="progress-title">'+spinner+'<strong>'+esc(event.title)+'</strong></div><div class="progress-meta"><span>'+esc(event.message || event.status)+'</span>'+(log ? '<span class="progress-toggle">'+(expanded ? "Hide details" : "Show details")+'</span>' : '')+'</div>'+(log && expanded ? '<pre class="progress-log">'+esc(log)+'</pre>' : '')+'</button>'; }
|
|
459
531
|
function setCreateFormDisabled(disabled){ document.querySelectorAll("#createFields [data-field], #createFields [data-payment-tab], #createFields [data-payment-toggle]").forEach(input => { input.disabled = Boolean(disabled); }); if (!disabled) updatePaymentPanels(); }
|
|
460
532
|
document.getElementById("createProgress").onclick = event => { const step = event.target.closest("[data-progress-step]"); if (!step) return; const id = step.dataset.progressStep; if (expandedProgressSteps.has(id)) expandedProgressSteps.delete(id); else expandedProgressSteps.add(id); if (currentCreateJob) renderCreateJob(currentCreateJob); };
|
|
461
|
-
document.getElementById("refreshBootstrap")
|
|
462
|
-
|
|
533
|
+
const refreshBootstrapEl = document.getElementById("refreshBootstrap");
|
|
534
|
+
if (refreshBootstrapEl) {
|
|
535
|
+
refreshBootstrapEl.onclick = loadBootstrap;
|
|
536
|
+
}
|
|
537
|
+
const refreshReleasesEl = document.getElementById("refreshReleases");
|
|
538
|
+
if (refreshReleasesEl) {
|
|
539
|
+
refreshReleasesEl.onclick = loadBootstrap;
|
|
540
|
+
}
|
|
463
541
|
document.getElementById("closeBootstrapConfig").onclick = () => document.getElementById("bootstrapModal").classList.remove("open");
|
|
464
542
|
function fieldValue(input){ return numeric(input.value); }
|
|
465
543
|
function numeric(value){ const n = Number(value); return value !== "" && Number.isFinite(n) ? n : value; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-static.js","sourceRoot":"","sources":["../../src/ui-static.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,0DAA0D;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,OAAO
|
|
1
|
+
{"version":3,"file":"ui-static.js","sourceRoot":"","sources":["../../src/ui-static.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,0DAA0D;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAqTG,aAAa,EAAE;;QAEnB,CAAC;AACT,CAAC;AAED,SAAS,aAAa;IACpB,gFAAgF;IAChF,OAAO;EACP,mBAAmB,EAAE;EACrB,mBAAmB,EAAE;CACtB,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwNR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type alias for the seller entry shape vendor commands work with.
|
|
3
|
+
* Mirrors the server-side `SellerRegistryEntry` but stays decoupled
|
|
4
|
+
* from `wallet-bootstrap`'s internal types so this package does not
|
|
5
|
+
* become a build-time dependency of the registry service.
|
|
6
|
+
*/
|
|
7
|
+
export interface SellerRegistryEntry {
|
|
8
|
+
id: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
profile?: string;
|
|
11
|
+
app?: string;
|
|
12
|
+
url: string;
|
|
13
|
+
status?: string;
|
|
14
|
+
region?: string;
|
|
15
|
+
modelsCount?: number;
|
|
16
|
+
sampleModels?: string[];
|
|
17
|
+
models?: string[];
|
|
18
|
+
supportedProtocols: string[];
|
|
19
|
+
paymentMethods: string[];
|
|
20
|
+
recommendedFor?: string[];
|
|
21
|
+
}
|
|
22
|
+
export { RegistryVendorClient, RegistryAdminClient } from "./client.js";
|
|
23
|
+
//# sourceMappingURL=vendor-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-client.d.ts","sourceRoot":"","sources":["../../src/vendor-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-client.js","sourceRoot":"","sources":["../../src/vendor-client.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RegistryVendorClient } from "./vendor-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* vendor CLI helpers for the `bootstrap sellers` and
|
|
4
|
+
* `bootstrap release` subcommands. Step 5 of the registry redesign.
|
|
5
|
+
*
|
|
6
|
+
* - `bootstrap sellers add --file <path>`: stage a single seller
|
|
7
|
+
* for inclusion in the next release request submitted by this
|
|
8
|
+
* vendor. The server validates the payload shape, persists it to
|
|
9
|
+
* `seller_pending`, and returns a `pendingSeller` row.
|
|
10
|
+
* - `bootstrap release submit --note <text> --staged <id>`: submit
|
|
11
|
+
* a release request that includes one or more staged sellers.
|
|
12
|
+
* - `bootstrap release list`: list the vendor's release requests.
|
|
13
|
+
* - `bootstrap release show <id>`: show one release request.
|
|
14
|
+
* - `bootstrap release force-publish <id>`: super-admin path; the
|
|
15
|
+
* vendor token cannot force-publish itself (the platform owns
|
|
16
|
+
* the scheduler loop in Step 7), but we keep the command here
|
|
17
|
+
* so CI scripts have a single entry point.
|
|
18
|
+
*/
|
|
19
|
+
export interface StageSellerInput {
|
|
20
|
+
client: RegistryVendorClient;
|
|
21
|
+
file: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function stageSellerFromFile({ client, file }: StageSellerInput): Promise<{
|
|
24
|
+
pendingSeller: unknown;
|
|
25
|
+
}>;
|
|
26
|
+
export interface SubmitReleaseInput {
|
|
27
|
+
client: RegistryVendorClient;
|
|
28
|
+
stagedSellerIds: string[];
|
|
29
|
+
note?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function submitRelease({ client, stagedSellerIds, note }: SubmitReleaseInput): Promise<{
|
|
32
|
+
releaseRequest: unknown;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function printReleaseRequestSummary(record: any): string;
|
|
35
|
+
//# sourceMappingURL=vendor-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-commands.d.ts","sourceRoot":"","sources":["../../src/vendor-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAuB,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC;IAAE,aAAa,EAAE,OAAO,CAAA;CAAE,CAAC,CAOjH;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAAE,cAAc,EAAE,OAAO,CAAA;CAAE,CAAC,CAK/H;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAgB9D"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
export async function stageSellerFromFile({ client, file }) {
|
|
3
|
+
const content = fs.readFileSync(file, "utf8");
|
|
4
|
+
const parsed = JSON.parse(content);
|
|
5
|
+
if (!parsed.id || typeof parsed.id !== "string") {
|
|
6
|
+
throw new Error(`seller id is required in ${file}`);
|
|
7
|
+
}
|
|
8
|
+
return client.stageSeller(parsed);
|
|
9
|
+
}
|
|
10
|
+
export async function submitRelease({ client, stagedSellerIds, note }) {
|
|
11
|
+
if (stagedSellerIds.length === 0) {
|
|
12
|
+
throw new Error("at least one --staged <seller-id> is required");
|
|
13
|
+
}
|
|
14
|
+
return client.submitRelease({ stagedSellerIds, note });
|
|
15
|
+
}
|
|
16
|
+
export function printReleaseRequestSummary(record) {
|
|
17
|
+
if (!record) {
|
|
18
|
+
return "no release request";
|
|
19
|
+
}
|
|
20
|
+
const summary = record.payloadSummary || { count: 0, sellerIds: [] };
|
|
21
|
+
return [
|
|
22
|
+
`id: #${record.id}`,
|
|
23
|
+
`status: ${record.status}`,
|
|
24
|
+
`vendor: ${record.vendorId}`,
|
|
25
|
+
`sellers: ${summary.count} (${(summary.sellerIds || []).join(", ") || "—"})`,
|
|
26
|
+
`submittedAt: ${record.submittedAt || "—"}`,
|
|
27
|
+
`decidedAt: ${record.decidedAt || "—"}`,
|
|
28
|
+
`version: ${record.publishedVersion !== null && record.publishedVersion !== undefined ? `v${record.publishedVersion}` : "—"}`,
|
|
29
|
+
record.note ? `note: ${record.note}` : null,
|
|
30
|
+
record.errorMessage ? `error: ${record.errorMessage}` : null
|
|
31
|
+
].filter(Boolean).join("\n");
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=vendor-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-commands.js","sourceRoot":"","sources":["../../src/vendor-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AA0BzB,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAoB;IAC1E,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAwB,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAsB;IACvF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,MAAM,CAAC,aAAa,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAW;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACrE,OAAO;QACL,kBAAkB,MAAM,CAAC,EAAE,EAAE;QAC7B,iBAAiB,MAAM,CAAC,MAAM,EAAE;QAChC,iBAAiB,MAAM,CAAC,QAAQ,EAAE;QAClC,iBAAiB,OAAO,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG;QACjF,iBAAiB,MAAM,CAAC,WAAW,IAAI,GAAG,EAAE;QAC5C,iBAAiB,MAAM,CAAC,SAAS,IAAI,GAAG,EAAE;QAC1C,iBAAiB,MAAM,CAAC,gBAAgB,KAAK,IAAI,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;QAClI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;QACnD,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI;KACpE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|