apiblaze 0.4.8 → 0.4.10
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 +143 -86
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,10 +25,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
27
|
var import_commander = require("commander");
|
|
28
|
-
var
|
|
28
|
+
var import_chalk28 = __toESM(require("chalk"));
|
|
29
29
|
|
|
30
30
|
// package.json
|
|
31
|
-
var version = "0.4.
|
|
31
|
+
var version = "0.4.10";
|
|
32
32
|
|
|
33
33
|
// src/types.ts
|
|
34
34
|
var ApiError = class extends Error {
|
|
@@ -1165,7 +1165,7 @@ async function runCreate(opts = {}) {
|
|
|
1165
1165
|
const { rawName } = await inquirer2.prompt([{
|
|
1166
1166
|
type: "input",
|
|
1167
1167
|
name: "rawName",
|
|
1168
|
-
message: "Proxy name (your API will live at <name>.
|
|
1168
|
+
message: "Proxy name (your API will live at <name>.abz.run):",
|
|
1169
1169
|
transformer: (v) => normalizeName(v)
|
|
1170
1170
|
}]);
|
|
1171
1171
|
name = normalizeName(rawName);
|
|
@@ -1186,7 +1186,7 @@ async function runCreate(opts = {}) {
|
|
|
1186
1186
|
spinner2.stop();
|
|
1187
1187
|
console.log(import_chalk6.default.dim(" (could not verify availability; continuing)"));
|
|
1188
1188
|
}
|
|
1189
|
-
console.log(`${import_chalk6.default.cyan("\u2192")} Your API will live at ${import_chalk6.default.bold(`https://${name}.
|
|
1189
|
+
console.log(`${import_chalk6.default.cyan("\u2192")} Your API will live at ${import_chalk6.default.bold(`https://${name}.abz.run`)}
|
|
1190
1190
|
`);
|
|
1191
1191
|
break;
|
|
1192
1192
|
}
|
|
@@ -1241,7 +1241,7 @@ async function runCreate(opts = {}) {
|
|
|
1241
1241
|
const version2 = result.api_version || "1.0.0";
|
|
1242
1242
|
const keys = result.api_keys ?? {};
|
|
1243
1243
|
const adminKey = keys.dev ?? Object.values(keys)[0];
|
|
1244
|
-
const proxyUrl = `https://${name}.
|
|
1244
|
+
const proxyUrl = `https://${name}.abz.run/${version2}/dev`;
|
|
1245
1245
|
const devPortal = result.devPortal ? stripTenantFromPortal(result.devPortal) : void 0;
|
|
1246
1246
|
if (opts.json) {
|
|
1247
1247
|
process.stdout.write(JSON.stringify({
|
|
@@ -2172,8 +2172,64 @@ async function runDelete(project, version2, opts) {
|
|
|
2172
2172
|
if (opts.json) console.log(JSON.stringify({ project_id: proj2.projectId, api_version: proj2.apiVersion, deleted: true }));
|
|
2173
2173
|
}
|
|
2174
2174
|
|
|
2175
|
-
// src/commands/
|
|
2175
|
+
// src/commands/export.ts
|
|
2176
2176
|
var import_chalk19 = __toESM(require("chalk"));
|
|
2177
|
+
var import_fs3 = require("fs");
|
|
2178
|
+
var DASHBOARD_BASE4 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
2179
|
+
async function runExport(projectArg, versionArg, opts) {
|
|
2180
|
+
const token = getAccessToken();
|
|
2181
|
+
if (!token) throw new Error("Not authenticated. Run `apiblaze login` first.");
|
|
2182
|
+
const projects = await getProjects(opts.team ?? "");
|
|
2183
|
+
const match = projects.find((p) => p.projectId === projectArg || p.projectName === projectArg);
|
|
2184
|
+
if (!match) throw new Error(`Project "${projectArg}" not found. Run \`apiblaze projects\`.`);
|
|
2185
|
+
const projectId = match.projectId;
|
|
2186
|
+
const version2 = versionArg || match.apiVersion;
|
|
2187
|
+
const target = opts.kong ? "kong" : "data";
|
|
2188
|
+
const q = new URLSearchParams();
|
|
2189
|
+
if (opts.secrets) q.set("include_secrets", "1");
|
|
2190
|
+
if (opts.noConsumers) q.set("include_consumers", "0");
|
|
2191
|
+
if (opts.keys) q.set("keys", opts.keys);
|
|
2192
|
+
const qs = q.toString() ? `?${q.toString()}` : "";
|
|
2193
|
+
console.log(import_chalk19.default.dim(`Queuing ${target} export of ${projectId}@${version2}\u2026`));
|
|
2194
|
+
const job = await admin({
|
|
2195
|
+
path: `/projects/${projectId}/${version2}/export/${target}${qs}`,
|
|
2196
|
+
method: "GET",
|
|
2197
|
+
summary: `export ${projectId} (${target})`
|
|
2198
|
+
});
|
|
2199
|
+
if (!job?.job_id) throw new Error("Failed to queue export.");
|
|
2200
|
+
const statusPath = `/projects/${projectId}/${version2}/export/jobs/${job.job_id}`;
|
|
2201
|
+
let status = "queued";
|
|
2202
|
+
const started = Date.now();
|
|
2203
|
+
process.stdout.write(import_chalk19.default.dim("Building bundle"));
|
|
2204
|
+
while (status !== "ready" && status !== "failed") {
|
|
2205
|
+
if (Date.now() - started > 10 * 6e4) throw new Error("Export timed out after 10 minutes.");
|
|
2206
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
2207
|
+
process.stdout.write(import_chalk19.default.dim("."));
|
|
2208
|
+
const st = await admin({ path: statusPath, method: "GET", summary: "poll export" });
|
|
2209
|
+
status = st?.status ?? "queued";
|
|
2210
|
+
if (status === "failed") {
|
|
2211
|
+
process.stdout.write("\n");
|
|
2212
|
+
throw new Error(`Export failed: ${st?.error ?? "unknown error"}`);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
process.stdout.write("\n");
|
|
2216
|
+
const outFile = opts.out || `apiblaze-export-${projectId}-${version2}-${target}.zip`;
|
|
2217
|
+
const res = await fetch(`${DASHBOARD_BASE4}/api/cli/admin/download`, {
|
|
2218
|
+
method: "POST",
|
|
2219
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
2220
|
+
body: JSON.stringify({ path: `${statusPath}?download=1` })
|
|
2221
|
+
});
|
|
2222
|
+
if (!res.ok) throw new Error(`Download failed (${res.status}): ${await res.text().catch(() => "")}`);
|
|
2223
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
2224
|
+
(0, import_fs3.writeFileSync)(outFile, buf);
|
|
2225
|
+
console.log(import_chalk19.default.green(`\u2713 Saved ${outFile} (${(buf.length / 1024).toFixed(0)} KB)`));
|
|
2226
|
+
if (job.decryption_key) console.log(import_chalk19.default.yellow(`Decryption key (shown once): ${job.decryption_key}`));
|
|
2227
|
+
console.log(import_chalk19.default.dim("Read MIGRATION-REPORT.json inside the zip for the full fidelity ledger."));
|
|
2228
|
+
if (target === "kong") console.log(import_chalk19.default.dim("Kong: unzip, then `cd kong && docker compose up` (see kong/README.md)."));
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
// src/commands/config.ts
|
|
2232
|
+
var import_chalk20 = __toESM(require("chalk"));
|
|
2177
2233
|
var import_ora6 = __toESM(require("ora"));
|
|
2178
2234
|
async function patchConfig(project, opts, body, summary) {
|
|
2179
2235
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2195,7 +2251,7 @@ async function patchConfig(project, opts, body, summary) {
|
|
|
2195
2251
|
}
|
|
2196
2252
|
async function runTargetSet(project, opts) {
|
|
2197
2253
|
if (!opts.url) {
|
|
2198
|
-
console.error(
|
|
2254
|
+
console.error(import_chalk20.default.red("--url is required."));
|
|
2199
2255
|
process.exit(1);
|
|
2200
2256
|
}
|
|
2201
2257
|
const body = opts.env ? { environments: { [opts.env]: { target: opts.url } } } : { target_url: opts.url };
|
|
@@ -2208,31 +2264,31 @@ async function runThrottleSet(project, opts) {
|
|
|
2208
2264
|
if (opts.quota !== void 0) throttling.proxyQuota = Number(opts.quota);
|
|
2209
2265
|
if (opts.period !== void 0) {
|
|
2210
2266
|
if (!["daily", "weekly", "monthly"].includes(opts.period)) {
|
|
2211
|
-
console.error(
|
|
2267
|
+
console.error(import_chalk20.default.red("--period must be daily, weekly, or monthly."));
|
|
2212
2268
|
process.exit(1);
|
|
2213
2269
|
}
|
|
2214
2270
|
throttling.quotaPeriod = opts.period;
|
|
2215
2271
|
}
|
|
2216
2272
|
if (Object.keys(throttling).length === 0) {
|
|
2217
|
-
console.error(
|
|
2273
|
+
console.error(import_chalk20.default.red("Nothing to set. Pass at least one of --rate, --end-user-rate, --quota, --period."));
|
|
2218
2274
|
process.exit(1);
|
|
2219
2275
|
}
|
|
2220
2276
|
await patchConfig(project, opts, { throttling }, `Update throttling ${JSON.stringify(throttling)}`);
|
|
2221
2277
|
}
|
|
2222
2278
|
async function runRename(project, opts) {
|
|
2223
2279
|
if (!opts.displayName) {
|
|
2224
|
-
console.error(
|
|
2280
|
+
console.error(import_chalk20.default.red("--display-name is required."));
|
|
2225
2281
|
process.exit(1);
|
|
2226
2282
|
}
|
|
2227
2283
|
await patchConfig(project, opts, { display_name: opts.displayName }, `Rename \u2192 "${opts.displayName}"`);
|
|
2228
2284
|
}
|
|
2229
2285
|
|
|
2230
2286
|
// src/commands/domain.ts
|
|
2231
|
-
var
|
|
2287
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
2232
2288
|
var import_ora7 = __toESM(require("ora"));
|
|
2233
2289
|
async function runDomainAdd(project, opts) {
|
|
2234
2290
|
if (!opts.domain) {
|
|
2235
|
-
console.error(
|
|
2291
|
+
console.error(import_chalk21.default.red("--domain is required."));
|
|
2236
2292
|
process.exit(1);
|
|
2237
2293
|
}
|
|
2238
2294
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2251,9 +2307,9 @@ async function runDomainAdd(project, opts) {
|
|
|
2251
2307
|
console.log(JSON.stringify(out));
|
|
2252
2308
|
return;
|
|
2253
2309
|
}
|
|
2254
|
-
if (out?.cnameRecord) console.log(` ${
|
|
2255
|
-
if (out?.dcv) console.log(` ${
|
|
2256
|
-
if (out?.id) console.log(
|
|
2310
|
+
if (out?.cnameRecord) console.log(` ${import_chalk21.default.cyan("CNAME")} ${out.cnameRecord.name ?? opts.domain} \u2192 ${out.cnameRecord.value ?? out.cnameRecord.target}`);
|
|
2311
|
+
if (out?.dcv) console.log(` ${import_chalk21.default.cyan("TXT")} ${out.dcv.name} = ${out.dcv.value}`);
|
|
2312
|
+
if (out?.id) console.log(import_chalk21.default.dim(` domain id: ${out.id}`));
|
|
2257
2313
|
} catch (err) {
|
|
2258
2314
|
spinner.fail("Domain registration failed.");
|
|
2259
2315
|
throw err;
|
|
@@ -2273,14 +2329,14 @@ async function runDomainList(project, opts) {
|
|
|
2273
2329
|
return;
|
|
2274
2330
|
}
|
|
2275
2331
|
if (!domains.length) {
|
|
2276
|
-
console.log(
|
|
2332
|
+
console.log(import_chalk21.default.yellow("No custom domains."));
|
|
2277
2333
|
return;
|
|
2278
2334
|
}
|
|
2279
|
-
for (const d of domains) console.log(` ${
|
|
2335
|
+
for (const d of domains) console.log(` ${import_chalk21.default.bold(d.hostname)} ${import_chalk21.default.dim(d.status ?? "")} ${import_chalk21.default.dim(d.id ?? "")}`);
|
|
2280
2336
|
}
|
|
2281
2337
|
async function runDomainStatus(project, opts) {
|
|
2282
2338
|
if (!opts.id) {
|
|
2283
|
-
console.error(
|
|
2339
|
+
console.error(import_chalk21.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
|
|
2284
2340
|
process.exit(1);
|
|
2285
2341
|
}
|
|
2286
2342
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2290,11 +2346,11 @@ async function runDomainStatus(project, opts) {
|
|
|
2290
2346
|
path: `/projects/${proj2.projectId}/domains/${encodeURIComponent(opts.id)}/status`,
|
|
2291
2347
|
summary: `Check custom-domain status`
|
|
2292
2348
|
});
|
|
2293
|
-
console.log(opts.json ? JSON.stringify(out) : ` ${
|
|
2349
|
+
console.log(opts.json ? JSON.stringify(out) : ` ${import_chalk21.default.bold(out?.hostname ?? opts.id)}: ${import_chalk21.default.cyan(out?.status ?? "unknown")}`);
|
|
2294
2350
|
}
|
|
2295
2351
|
async function runDomainRemove(project, opts) {
|
|
2296
2352
|
if (!opts.id) {
|
|
2297
|
-
console.error(
|
|
2353
|
+
console.error(import_chalk21.default.red("--id <domainId> is required (see `apiblaze domain list`)."));
|
|
2298
2354
|
process.exit(1);
|
|
2299
2355
|
}
|
|
2300
2356
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2332,7 +2388,7 @@ async function runDomainSetBase(project, opts) {
|
|
|
2332
2388
|
}
|
|
2333
2389
|
|
|
2334
2390
|
// src/commands/tenant.ts
|
|
2335
|
-
var
|
|
2391
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
2336
2392
|
var import_ora8 = __toESM(require("ora"));
|
|
2337
2393
|
async function runTenantList(opts) {
|
|
2338
2394
|
const { teamId, teamName } = await resolveTeam(opts.team);
|
|
@@ -2347,18 +2403,18 @@ async function runTenantList(opts) {
|
|
|
2347
2403
|
return;
|
|
2348
2404
|
}
|
|
2349
2405
|
if (!tenants.length) {
|
|
2350
|
-
console.log(
|
|
2406
|
+
console.log(import_chalk22.default.yellow("No tenants."));
|
|
2351
2407
|
return;
|
|
2352
2408
|
}
|
|
2353
2409
|
for (const t of tenants) {
|
|
2354
2410
|
const name = typeof t === "string" ? t : t.tenant_name;
|
|
2355
|
-
const display = typeof t === "string" ? "" :
|
|
2356
|
-
console.log(` ${
|
|
2411
|
+
const display = typeof t === "string" ? "" : import_chalk22.default.dim(` ${t.display_name ?? ""}`);
|
|
2412
|
+
console.log(` ${import_chalk22.default.bold(name)}${display}`);
|
|
2357
2413
|
}
|
|
2358
2414
|
}
|
|
2359
2415
|
async function runTenantCreate(opts) {
|
|
2360
2416
|
if (!opts.name) {
|
|
2361
|
-
console.error(
|
|
2417
|
+
console.error(import_chalk22.default.red("--name (display name) is required."));
|
|
2362
2418
|
process.exit(1);
|
|
2363
2419
|
}
|
|
2364
2420
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2370,7 +2426,7 @@ async function runTenantCreate(opts) {
|
|
|
2370
2426
|
body: { display_name: opts.name, ...opts.slug ? { tenant_name: opts.slug } : {} },
|
|
2371
2427
|
summary: `Create tenant "${opts.name}"`
|
|
2372
2428
|
});
|
|
2373
|
-
spinner.succeed(`Created tenant ${
|
|
2429
|
+
spinner.succeed(`Created tenant ${import_chalk22.default.bold(out?.tenant_name ?? opts.name)}.`);
|
|
2374
2430
|
if (opts.json) console.log(JSON.stringify(out));
|
|
2375
2431
|
} catch (err) {
|
|
2376
2432
|
spinner.fail("Tenant create failed.");
|
|
@@ -2379,7 +2435,7 @@ async function runTenantCreate(opts) {
|
|
|
2379
2435
|
}
|
|
2380
2436
|
async function runTenantAttach(project, opts) {
|
|
2381
2437
|
if (!opts.tenant) {
|
|
2382
|
-
console.error(
|
|
2438
|
+
console.error(import_chalk22.default.red("--tenant <slug> is required."));
|
|
2383
2439
|
process.exit(1);
|
|
2384
2440
|
}
|
|
2385
2441
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2407,7 +2463,7 @@ async function runTenantDelete(slug, opts) {
|
|
|
2407
2463
|
{ type: "confirm", name: "confirm", message: `Permanently delete tenant "${slug}" and everything under it? This cannot be undone.`, default: false }
|
|
2408
2464
|
]);
|
|
2409
2465
|
if (!confirm) {
|
|
2410
|
-
console.log(
|
|
2466
|
+
console.log(import_chalk22.default.dim("Aborted."));
|
|
2411
2467
|
return;
|
|
2412
2468
|
}
|
|
2413
2469
|
}
|
|
@@ -2426,7 +2482,7 @@ async function runTenantDelete(slug, opts) {
|
|
|
2426
2482
|
}
|
|
2427
2483
|
async function runTenantCors(opts) {
|
|
2428
2484
|
if (!opts.tenant) {
|
|
2429
|
-
console.error(
|
|
2485
|
+
console.error(import_chalk22.default.red("--tenant <slug> is required."));
|
|
2430
2486
|
process.exit(1);
|
|
2431
2487
|
}
|
|
2432
2488
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2448,7 +2504,7 @@ async function runTenantCors(opts) {
|
|
|
2448
2504
|
}
|
|
2449
2505
|
|
|
2450
2506
|
// src/commands/key.ts
|
|
2451
|
-
var
|
|
2507
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
2452
2508
|
var import_ora9 = __toESM(require("ora"));
|
|
2453
2509
|
async function runApikeysMenu(opts) {
|
|
2454
2510
|
await runKeyList(opts);
|
|
@@ -2476,11 +2532,11 @@ async function runKeyList(opts) {
|
|
|
2476
2532
|
return;
|
|
2477
2533
|
}
|
|
2478
2534
|
if (!keys.length) {
|
|
2479
|
-
console.log(
|
|
2535
|
+
console.log(import_chalk23.default.yellow("No developer keys."));
|
|
2480
2536
|
return;
|
|
2481
2537
|
}
|
|
2482
2538
|
for (const k of keys) {
|
|
2483
|
-
console.log(` ${
|
|
2539
|
+
console.log(` ${import_chalk23.default.bold(k.key_id ?? k.id)} ${import_chalk23.default.dim(k.description ?? "")} ${import_chalk23.default.dim(k.expires_at ?? "no expiry")}`);
|
|
2484
2540
|
}
|
|
2485
2541
|
}
|
|
2486
2542
|
async function runKeyMint(opts) {
|
|
@@ -2501,9 +2557,9 @@ async function runKeyMint(opts) {
|
|
|
2501
2557
|
console.log(JSON.stringify(out));
|
|
2502
2558
|
return;
|
|
2503
2559
|
}
|
|
2504
|
-
console.log(` ${
|
|
2505
|
-
console.log(` ${
|
|
2506
|
-
if (out?.expires_at) console.log(` ${
|
|
2560
|
+
console.log(` ${import_chalk23.default.bold("key_id")}: ${out?.key_id}`);
|
|
2561
|
+
console.log(` ${import_chalk23.default.bold("key")}: ${import_chalk23.default.green(out?.key)} ${import_chalk23.default.dim("(shown once \u2014 store it now)")}`);
|
|
2562
|
+
if (out?.expires_at) console.log(` ${import_chalk23.default.dim("expires:")} ${out.expires_at}`);
|
|
2507
2563
|
} catch (err) {
|
|
2508
2564
|
spinner.fail("Mint failed.");
|
|
2509
2565
|
throw err;
|
|
@@ -2527,7 +2583,7 @@ async function runKeyRevoke(keyId, opts) {
|
|
|
2527
2583
|
|
|
2528
2584
|
// src/commands/spec.ts
|
|
2529
2585
|
var fs5 = __toESM(require("fs"));
|
|
2530
|
-
var
|
|
2586
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
2531
2587
|
var import_ora10 = __toESM(require("ora"));
|
|
2532
2588
|
async function runSpecGet(project, opts) {
|
|
2533
2589
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2541,14 +2597,14 @@ async function runSpecGet(project, opts) {
|
|
|
2541
2597
|
}
|
|
2542
2598
|
async function runSpecSet(project, opts) {
|
|
2543
2599
|
if (!opts.file) {
|
|
2544
|
-
console.error(
|
|
2600
|
+
console.error(import_chalk24.default.red("--file <path> is required (OpenAPI JSON or YAML)."));
|
|
2545
2601
|
process.exit(1);
|
|
2546
2602
|
}
|
|
2547
2603
|
let specContent;
|
|
2548
2604
|
try {
|
|
2549
2605
|
specContent = fs5.readFileSync(opts.file, "utf-8");
|
|
2550
2606
|
} catch {
|
|
2551
|
-
console.error(
|
|
2607
|
+
console.error(import_chalk24.default.red(`Cannot read file: ${opts.file}`));
|
|
2552
2608
|
process.exit(1);
|
|
2553
2609
|
}
|
|
2554
2610
|
const { teamId } = await resolveTeam(opts.team);
|
|
@@ -2570,11 +2626,11 @@ async function runSpecSet(project, opts) {
|
|
|
2570
2626
|
}
|
|
2571
2627
|
|
|
2572
2628
|
// src/commands/agent.ts
|
|
2573
|
-
var
|
|
2629
|
+
var import_chalk26 = __toESM(require("chalk"));
|
|
2574
2630
|
var import_ora11 = __toESM(require("ora"));
|
|
2575
2631
|
|
|
2576
2632
|
// src/lib/tools.ts
|
|
2577
|
-
var
|
|
2633
|
+
var import_chalk25 = __toESM(require("chalk"));
|
|
2578
2634
|
async function proj(teamId, name, version2) {
|
|
2579
2635
|
return resolveProject(teamId, name, version2);
|
|
2580
2636
|
}
|
|
@@ -2589,17 +2645,17 @@ var TOOLS = [
|
|
|
2589
2645
|
const version2 = res.api_version || "1.0.0";
|
|
2590
2646
|
const keys = res.api_keys ?? {};
|
|
2591
2647
|
const key = keys.dev ?? Object.values(keys)[0];
|
|
2592
|
-
const url = `https://${a.name}.
|
|
2648
|
+
const url = `https://${a.name}.abz.run/${version2}/dev`;
|
|
2593
2649
|
const tryIt = buildTryItCurl(url, auth, key);
|
|
2594
|
-
const lines = [` ${
|
|
2595
|
-
if (res.devPortal) lines.push(` ${
|
|
2650
|
+
const lines = [` ${import_chalk25.default.dim("Proxy URL:")} ${import_chalk25.default.bold(url)}`];
|
|
2651
|
+
if (res.devPortal) lines.push(` ${import_chalk25.default.dim("Dev portal:")} ${res.devPortal}`);
|
|
2596
2652
|
const envs = Object.keys(keys);
|
|
2597
2653
|
if (envs.length) {
|
|
2598
|
-
lines.push("", ` ${
|
|
2654
|
+
lines.push("", ` ${import_chalk25.default.bold("API keys")} ${import_chalk25.default.dim("(bootstrapped \u2014 send as the X-API-Key header; shown once):")}`);
|
|
2599
2655
|
const w = Math.max(...envs.map((e) => e.length));
|
|
2600
|
-
for (const env of envs) lines.push(` ${
|
|
2656
|
+
for (const env of envs) lines.push(` ${import_chalk25.default.cyan(env.padEnd(w))} ${import_chalk25.default.green(keys[env])}`);
|
|
2601
2657
|
}
|
|
2602
|
-
if (tryIt) lines.push("", ` ${
|
|
2658
|
+
if (tryIt) lines.push("", ` ${import_chalk25.default.dim("Try it:")}`, ` ${import_chalk25.default.cyan(tryIt)}`);
|
|
2603
2659
|
return { ...res, proxy_url: url, keys, ...tryIt ? { try_it: tryIt } : {}, display: lines.join("\n") };
|
|
2604
2660
|
}
|
|
2605
2661
|
},
|
|
@@ -2724,11 +2780,11 @@ function findTool(name) {
|
|
|
2724
2780
|
}
|
|
2725
2781
|
|
|
2726
2782
|
// src/commands/agent.ts
|
|
2727
|
-
var
|
|
2783
|
+
var DASHBOARD_BASE5 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
2728
2784
|
var MAX_TOOL_STEPS = 6;
|
|
2729
2785
|
async function callAgent(messages, teamId) {
|
|
2730
2786
|
const token = getAccessToken();
|
|
2731
|
-
const res = await fetch(`${
|
|
2787
|
+
const res = await fetch(`${DASHBOARD_BASE5}/api/cli/agent`, {
|
|
2732
2788
|
method: "POST",
|
|
2733
2789
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
2734
2790
|
body: JSON.stringify({ messages: messages.slice(-20), tools: toolCatalogue(), team_id: teamId })
|
|
@@ -2753,17 +2809,17 @@ function truncate(value, max = 1500) {
|
|
|
2753
2809
|
}
|
|
2754
2810
|
function printCost(llm) {
|
|
2755
2811
|
const usd = llm.cost > 0 ? `$${llm.cost.toFixed(4)}` : "<$0.0001";
|
|
2756
|
-
console.log(
|
|
2812
|
+
console.log(import_chalk26.default.magenta(` \u{1F4B3} ${usd}`) + import_chalk26.default.dim(` (${llm.model}, ${llm.total_tokens} tok)`));
|
|
2757
2813
|
}
|
|
2758
2814
|
async function runAgent(opts) {
|
|
2759
2815
|
requireAuth();
|
|
2760
2816
|
const { teamId, teamName } = await resolveTeam(opts.team);
|
|
2761
2817
|
const { default: inquirer2 } = await import("inquirer");
|
|
2762
|
-
console.log(
|
|
2763
|
-
console.log(
|
|
2818
|
+
console.log(import_chalk26.default.bold("APIblaze agent") + import_chalk26.default.dim(` \xB7 team ${teamName ?? teamId}`));
|
|
2819
|
+
console.log(import_chalk26.default.dim('Ask me to create/delete/configure proxies, tenants, keys, domains, specs. Type "exit" to quit.\n'));
|
|
2764
2820
|
const history = [];
|
|
2765
2821
|
while (true) {
|
|
2766
|
-
const { input } = await inquirer2.prompt([{ type: "input", name: "input", message:
|
|
2822
|
+
const { input } = await inquirer2.prompt([{ type: "input", name: "input", message: import_chalk26.default.cyan("you") + " \u203A" }]);
|
|
2767
2823
|
const text = (input ?? "").trim();
|
|
2768
2824
|
if (!text) continue;
|
|
2769
2825
|
if (["exit", "quit", ":q"].includes(text.toLowerCase())) break;
|
|
@@ -2777,14 +2833,14 @@ async function runAgent(opts) {
|
|
|
2777
2833
|
} catch (err) {
|
|
2778
2834
|
spinner.stop();
|
|
2779
2835
|
if (err instanceof ApiError && err.status === 402) {
|
|
2780
|
-
console.log(
|
|
2836
|
+
console.log(import_chalk26.default.yellow(" Insufficient credits \u2014 top up to keep using the agent."));
|
|
2781
2837
|
break;
|
|
2782
2838
|
}
|
|
2783
2839
|
throw err;
|
|
2784
2840
|
}
|
|
2785
2841
|
history.push({ role: "assistant", content: resp.raw });
|
|
2786
2842
|
printCost(resp.llm);
|
|
2787
|
-
if (resp.reply) console.log(
|
|
2843
|
+
if (resp.reply) console.log(import_chalk26.default.green("agent") + " \u203A " + resp.reply);
|
|
2788
2844
|
if (!resp.action) break;
|
|
2789
2845
|
const tool = findTool(resp.action.tool);
|
|
2790
2846
|
if (!tool) {
|
|
@@ -2809,15 +2865,15 @@ async function runAgent(opts) {
|
|
|
2809
2865
|
}
|
|
2810
2866
|
renderTrace();
|
|
2811
2867
|
if (step === MAX_TOOL_STEPS - 1) {
|
|
2812
|
-
console.log(
|
|
2868
|
+
console.log(import_chalk26.default.dim(" (paused after several steps \u2014 tell me how to continue)"));
|
|
2813
2869
|
}
|
|
2814
2870
|
}
|
|
2815
2871
|
}
|
|
2816
|
-
console.log(
|
|
2872
|
+
console.log(import_chalk26.default.dim("\nBye."));
|
|
2817
2873
|
}
|
|
2818
2874
|
|
|
2819
2875
|
// src/commands/consumer.ts
|
|
2820
|
-
var
|
|
2876
|
+
var import_chalk27 = __toESM(require("chalk"));
|
|
2821
2877
|
var import_ora12 = __toESM(require("ora"));
|
|
2822
2878
|
var DEFAULT_SCOPE = "openid email profile offline_access";
|
|
2823
2879
|
var APIKEYS_BASE = process.env.APIBLAZE_APIKEYS_BASE || "https://apikeys.apiblaze.com";
|
|
@@ -2837,7 +2893,7 @@ async function consumerFetch(creds, suffix, init) {
|
|
|
2837
2893
|
function requireConsumer() {
|
|
2838
2894
|
const c = loadConsumer();
|
|
2839
2895
|
if (!c) {
|
|
2840
|
-
console.error(
|
|
2896
|
+
console.error(import_chalk27.default.red("Not logged in as a consumer. Run `apiblaze consumer login` first."));
|
|
2841
2897
|
process.exit(1);
|
|
2842
2898
|
}
|
|
2843
2899
|
return c;
|
|
@@ -2848,7 +2904,7 @@ async function runConsumerLogin(opts) {
|
|
|
2848
2904
|
let clientId = opts.client;
|
|
2849
2905
|
if (clientId) {
|
|
2850
2906
|
if (!tenant2) {
|
|
2851
|
-
console.error(
|
|
2907
|
+
console.error(import_chalk27.default.red("When using --client, also pass --tenant <slug> (it sets which portal/keys host to use)."));
|
|
2852
2908
|
process.exit(1);
|
|
2853
2909
|
}
|
|
2854
2910
|
} else {
|
|
@@ -2861,7 +2917,7 @@ async function runConsumerLogin(opts) {
|
|
|
2861
2917
|
(t) => typeof t === "string" ? { tenant_name: t } : t
|
|
2862
2918
|
);
|
|
2863
2919
|
if (!tenants.length) {
|
|
2864
|
-
console.error(
|
|
2920
|
+
console.error(import_chalk27.default.red("This team has no tenants. Create one with `apiblaze tenant create`."));
|
|
2865
2921
|
process.exit(1);
|
|
2866
2922
|
}
|
|
2867
2923
|
if (!tenant2) {
|
|
@@ -2877,19 +2933,19 @@ async function runConsumerLogin(opts) {
|
|
|
2877
2933
|
const usable = (Array.isArray(clients) ? clients : []).filter((c) => c && (c.client_id || c.clientId));
|
|
2878
2934
|
const pick2 = usable.find((c) => c.is_default || c.default) ?? usable.find((c) => c.verified !== false) ?? usable[0];
|
|
2879
2935
|
if (!pick2) {
|
|
2880
|
-
console.error(
|
|
2936
|
+
console.error(import_chalk27.default.red(`Tenant "${tenant2}" has no login app configured. Set one up in the dashboard (or \`apiblaze create\` with auth).`));
|
|
2881
2937
|
process.exit(1);
|
|
2882
2938
|
}
|
|
2883
2939
|
clientId = pick2.client_id ?? pick2.clientId;
|
|
2884
2940
|
}
|
|
2885
2941
|
const portalResource = `https://${tenant2}.portal.apiblaze.com/1.0.0`;
|
|
2886
|
-
console.log(`${
|
|
2942
|
+
console.log(`${import_chalk27.default.cyan("\u2192")} Logging in to ${import_chalk27.default.bold(tenant2)} as a consumer...`);
|
|
2887
2943
|
const result = await deviceLogin(clientId, DEFAULT_SCOPE, ({ verificationUri, userCode }) => {
|
|
2888
2944
|
console.log(`
|
|
2889
|
-
Open: ${
|
|
2890
|
-
console.log(` Code: ${
|
|
2945
|
+
Open: ${import_chalk27.default.underline(verificationUri)}`);
|
|
2946
|
+
console.log(` Code: ${import_chalk27.default.bold(userCode)}
|
|
2891
2947
|
`);
|
|
2892
|
-
console.log(
|
|
2948
|
+
console.log(import_chalk27.default.dim(" (opening your browser\u2026 waiting for you to finish)"));
|
|
2893
2949
|
}, portalResource);
|
|
2894
2950
|
const claims = result.idToken && decodeJwt2(result.idToken) || (decodeJwt2(result.accessToken) ?? {});
|
|
2895
2951
|
const creds = {
|
|
@@ -2904,7 +2960,7 @@ async function runConsumerLogin(opts) {
|
|
|
2904
2960
|
obtainedAt: Date.now()
|
|
2905
2961
|
};
|
|
2906
2962
|
saveConsumer(creds);
|
|
2907
|
-
console.log(
|
|
2963
|
+
console.log(import_chalk27.default.green(`\u2714 Logged in as consumer${creds.email ? ` ${creds.email}` : ""} on ${tenant2}.`));
|
|
2908
2964
|
}
|
|
2909
2965
|
async function runConsumerTokens(opts) {
|
|
2910
2966
|
const creds = requireConsumer();
|
|
@@ -2917,18 +2973,18 @@ async function runConsumerTokens(opts) {
|
|
|
2917
2973
|
console.log(JSON.stringify({ tenant: fresh.tenant, access_token: fresh.accessToken, refresh_token: fresh.refreshToken, id_token: fresh.idToken, expires_at: new Date(fresh.expiresAt).toISOString() }, null, 2));
|
|
2918
2974
|
return;
|
|
2919
2975
|
}
|
|
2920
|
-
console.log(`${
|
|
2976
|
+
console.log(`${import_chalk27.default.cyan("Consumer")} ${import_chalk27.default.bold(fresh.email ?? fresh.tenant)} on ${import_chalk27.default.bold(fresh.tenant)}
|
|
2921
2977
|
`);
|
|
2922
|
-
console.log(`${
|
|
2978
|
+
console.log(`${import_chalk27.default.bold("access_token")} ${import_chalk27.default.dim("exp " + (exp(fresh.accessToken) ?? "?"))}
|
|
2923
2979
|
${fresh.accessToken}
|
|
2924
2980
|
`);
|
|
2925
|
-
if (fresh.idToken) console.log(`${
|
|
2981
|
+
if (fresh.idToken) console.log(`${import_chalk27.default.bold("id_token")} ${import_chalk27.default.dim("exp " + (exp(fresh.idToken) ?? "?"))}
|
|
2926
2982
|
${fresh.idToken}
|
|
2927
2983
|
`);
|
|
2928
|
-
if (fresh.refreshToken) console.log(`${
|
|
2984
|
+
if (fresh.refreshToken) console.log(`${import_chalk27.default.bold("refresh_token")}
|
|
2929
2985
|
${fresh.refreshToken}
|
|
2930
2986
|
`);
|
|
2931
|
-
console.log(
|
|
2987
|
+
console.log(import_chalk27.default.dim("These are your own tokens \u2014 keep them secret."));
|
|
2932
2988
|
}
|
|
2933
2989
|
async function runConsumerApikeys(opts) {
|
|
2934
2990
|
const creds = requireConsumer();
|
|
@@ -2938,8 +2994,8 @@ async function runConsumerApikeys(opts) {
|
|
|
2938
2994
|
const revealed = await consumerFetch(list.creds, "/apikeys/reveal").catch(() => ({ status: 0, data: null, creds: list.creds }));
|
|
2939
2995
|
spinner.stop();
|
|
2940
2996
|
if (list.status >= 400) {
|
|
2941
|
-
console.error(
|
|
2942
|
-
if (list.status === 401) console.error(
|
|
2997
|
+
console.error(import_chalk27.default.red(`Failed to list keys (${list.status}): ${list.data?.error ?? ""}`));
|
|
2998
|
+
if (list.status === 401) console.error(import_chalk27.default.dim("Your consumer session may have expired \u2014 run `apiblaze consumer login` again."));
|
|
2943
2999
|
process.exit(1);
|
|
2944
3000
|
}
|
|
2945
3001
|
const keys = list.data?.keys ?? [];
|
|
@@ -2947,16 +3003,16 @@ async function runConsumerApikeys(opts) {
|
|
|
2947
3003
|
if (opts.json) {
|
|
2948
3004
|
console.log(JSON.stringify({ keys, revealed: revealMap }, null, 2));
|
|
2949
3005
|
} else if (!keys.length) {
|
|
2950
|
-
console.log(
|
|
3006
|
+
console.log(import_chalk27.default.yellow("No API keys yet."));
|
|
2951
3007
|
} else {
|
|
2952
3008
|
for (const k of keys) {
|
|
2953
3009
|
const clear = revealMap[k.environment]?.key;
|
|
2954
|
-
const shown = clear ?
|
|
2955
|
-
const exp = k.expires_at ?
|
|
2956
|
-
console.log(` ${
|
|
3010
|
+
const shown = clear ? import_chalk27.default.green(clear) : import_chalk27.default.dim(`${k.key_prefix ?? ""}\u2026${k.key_suffix ?? ""}`);
|
|
3011
|
+
const exp = k.expires_at ? import_chalk27.default.dim(`exp ${k.expires_at}`) : import_chalk27.default.dim("no expiry");
|
|
3012
|
+
console.log(` ${import_chalk27.default.bold(k.environment ?? "")} ${shown} ${exp} ${import_chalk27.default.dim(k.description ?? "")}`);
|
|
2957
3013
|
}
|
|
2958
3014
|
if (Object.keys(revealMap).length === 0 && keys.some((k) => !k.expires_at)) {
|
|
2959
|
-
console.log(
|
|
3015
|
+
console.log(import_chalk27.default.dim("\n(Only expiring keys can be shown in clear; non-expiring keys show a prefix only.)"));
|
|
2960
3016
|
}
|
|
2961
3017
|
}
|
|
2962
3018
|
if (opts.json) return;
|
|
@@ -2978,8 +3034,8 @@ async function runConsumerApikeys(opts) {
|
|
|
2978
3034
|
}
|
|
2979
3035
|
s2.succeed("Key created.");
|
|
2980
3036
|
const key = created.data?.key ?? created.data?.fullKey;
|
|
2981
|
-
if (key) console.log(` ${
|
|
2982
|
-
else console.log(
|
|
3037
|
+
if (key) console.log(` ${import_chalk27.default.green(key)} ${import_chalk27.default.dim("(shown once \u2014 store it now)")}`);
|
|
3038
|
+
else console.log(import_chalk27.default.dim(" Key created; run `apiblaze consumer apikeys` to reveal it if it expires."));
|
|
2983
3039
|
}
|
|
2984
3040
|
|
|
2985
3041
|
// src/index.ts
|
|
@@ -3009,7 +3065,7 @@ program.command("login").description("Authenticate with APIblaze").action(async
|
|
|
3009
3065
|
process.exit(1);
|
|
3010
3066
|
}
|
|
3011
3067
|
});
|
|
3012
|
-
program.command("create").description("Create a new API proxy (no login needed \u2014 without auth it creates an anonymous proxy and prints a claim URL)").option("--name <name>", "Proxy name (becomes <name>.
|
|
3068
|
+
program.command("create").description("Create a new API proxy (no login needed \u2014 without auth it creates an anonymous proxy and prints a claim URL)").option("--name <name>", "Proxy name (becomes <name>.abz.run)").option("--target <url>", "Target URL to forward requests to").option("--team <id|name>", "Team to create under (defaults to your active team)").option("--auth <type>", "Auth type: api_key | none | oauth", "api_key").option("--apiversion <version>", "API version to create (e.g. 2.0.0). Creating a new version of a proxy you own adds a version to the existing project.").option("--product <slug>", "Product tag to group this project under in the portal (team-scoped; anonymous create). Defaults to your team's existing/placeholder tag.").option("--display-name <name>", "Human-friendly display name").option("--subdomain <slug>", "Explicit subdomain (defaults to --name)").option("--config <file>", "JSON file with the full request body (anonymous create): requests_auth, login providers + client/server token types, scopes, callback URLs, etc. See apiblaze_anonymous.yaml. Flags override its fields.").option("-y, --yes", "Skip the confirmation prompt").option("--json", "Output machine-readable JSON (non-interactive)").action(async (opts) => {
|
|
3013
3069
|
try {
|
|
3014
3070
|
await runCreate(opts);
|
|
3015
3071
|
} catch (err) {
|
|
@@ -3025,7 +3081,7 @@ program.command("dev").description("Put your localhost behind a public URL (dev
|
|
|
3025
3081
|
try {
|
|
3026
3082
|
const resolved = parseInt(port ?? opts.port, 10);
|
|
3027
3083
|
if (Number.isNaN(resolved)) {
|
|
3028
|
-
console.error(
|
|
3084
|
+
console.error(import_chalk28.default.red(`Invalid port: ${port ?? opts.port}`));
|
|
3029
3085
|
process.exit(1);
|
|
3030
3086
|
}
|
|
3031
3087
|
await runDev({ port: resolved, captureFile: opts.captureFile });
|
|
@@ -3072,6 +3128,7 @@ program.command("projects").description("List the projects in your team").action
|
|
|
3072
3128
|
}
|
|
3073
3129
|
});
|
|
3074
3130
|
program.command("delete").description("Delete a proxy and everything under it (asks first)").argument("<project>", "Project name or id (see `apiblaze projects`)").argument("[version]", "API version (defaults to the first match)").option("--team <id|name>", "Team the project is in (defaults to active team)").option("-y, --yes", "Skip the confirmation prompt").option("--json", "Output machine-readable JSON").action(action((project, version2, opts) => runDelete(project, version2, opts)));
|
|
3131
|
+
program.command("export").description("Export everything to migrate off apiblaze (no lock-in): config, users, keys + fidelity report").argument("<project>", "Project name or id (see `apiblaze projects`)").argument("[version]", "API version (defaults to the first match)").option("--kong", "Produce a runnable Kong OSS bundle (decK config + plugins + docker-compose)").option("--data", "Target-neutral data export (default)").option("--secrets", "Include decrypted producer-supplied secrets (member role; audit-logged)").option("--keys <mode>", "API-key export: hashes (default, consumers keep keys) | mint | none").option("--no-consumers", "Skip the end-user lane (users, groups, keys)").option("-o, --out <file>", "Output zip path").option("--team <id|name>", "Team the project is in (defaults to active team)").action(action((project, version2, opts) => runExport(project, version2, { ...opts, noConsumers: opts.consumers === false })));
|
|
3075
3132
|
program.command("target").description("Change where a proxy forwards requests").argument("<project>", "Project name or id").requiredOption("--url <url>", "Target URL to forward to").option("--env <env>", "Environment to scope the target to (e.g. prod, dev)").option("--team <id|name>", "Team the project is in").option("--apiversion <version>", "API version (defaults to the first match)").option("--json", "Output machine-readable JSON").action(action((project, opts) => runTargetSet(project, opts)));
|
|
3076
3133
|
program.command("throttle").description("Set rate limits and quotas for a proxy").argument("<project>", "Project name or id").option("--rate <n>", "User rate limit (requests/sec)").option("--end-user-rate <n>", "Per-end-user rate limit (requests/sec)").option("--quota <n>", "Proxy quota (requests/period)").option("--period <p>", "Quota period: daily | weekly | monthly").option("--team <id|name>", "Team the project is in").option("--apiversion <version>", "API version").option("--json", "Output machine-readable JSON").action(action((project, opts) => runThrottleSet(project, opts)));
|
|
3077
3134
|
program.command("rename").description("Change a proxy's display name").argument("<project>", "Project name or id").requiredOption("--display-name <name>", "New human-friendly display name").option("--team <id|name>", "Team the project is in").option("--apiversion <version>", "API version").option("--json", "Output machine-readable JSON").action(action((project, opts) => runRename(project, opts)));
|
|
@@ -3110,7 +3167,7 @@ function groupedCommandHelp() {
|
|
|
3110
3167
|
const c = byName.get(n);
|
|
3111
3168
|
return c ? ` ${n.padEnd(width)}${c.description()}` : "";
|
|
3112
3169
|
}).filter(Boolean).join("\n");
|
|
3113
|
-
return `${
|
|
3170
|
+
return `${import_chalk28.default.bold(g.title)}
|
|
3114
3171
|
${rows}`;
|
|
3115
3172
|
}).join("\n\n");
|
|
3116
3173
|
}
|
|
@@ -3136,13 +3193,13 @@ Examples:
|
|
|
3136
3193
|
`);
|
|
3137
3194
|
function printError(err) {
|
|
3138
3195
|
if (err instanceof ApiError) {
|
|
3139
|
-
console.error(
|
|
3196
|
+
console.error(import_chalk28.default.red(`
|
|
3140
3197
|
API error (${err.status}): ${err.message}`));
|
|
3141
3198
|
} else if (err instanceof Error) {
|
|
3142
|
-
console.error(
|
|
3199
|
+
console.error(import_chalk28.default.red(`
|
|
3143
3200
|
Error: ${err.message}`));
|
|
3144
3201
|
} else {
|
|
3145
|
-
console.error(
|
|
3202
|
+
console.error(import_chalk28.default.red("\nUnknown error"));
|
|
3146
3203
|
}
|
|
3147
3204
|
}
|
|
3148
3205
|
program.parse(process.argv);
|