apiblaze 0.1.12 → 0.1.13
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 +153 -194
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -69,9 +69,6 @@ function getAccessToken() {
|
|
|
69
69
|
}
|
|
70
70
|
return creds.accessToken;
|
|
71
71
|
}
|
|
72
|
-
function getApiblazeDir() {
|
|
73
|
-
return APIBLAZE_DIR;
|
|
74
|
-
}
|
|
75
72
|
var fs, os, path, APIBLAZE_DIR, CREDENTIALS_PATH;
|
|
76
73
|
var init_auth = __esm({
|
|
77
74
|
"src/lib/auth.ts"() {
|
|
@@ -95,9 +92,9 @@ __export(api_exports, {
|
|
|
95
92
|
getTeams: () => getTeams,
|
|
96
93
|
putDevTunnel: () => putDevTunnel
|
|
97
94
|
});
|
|
98
|
-
async function apiFetch(
|
|
95
|
+
async function apiFetch(path2, options = {}) {
|
|
99
96
|
const token = getAccessToken();
|
|
100
|
-
const url = `${DASHBOARD_BASE}${
|
|
97
|
+
const url = `${DASHBOARD_BASE}${path2}`;
|
|
101
98
|
const res = await fetch(url, {
|
|
102
99
|
...options,
|
|
103
100
|
headers: {
|
|
@@ -288,125 +285,11 @@ ${import_chalk.default.cyan("\u2192")} Team: ${import_chalk.default.bold(teamNam
|
|
|
288
285
|
|
|
289
286
|
// src/commands/dev.ts
|
|
290
287
|
var import_chalk3 = __toESM(require("chalk"));
|
|
291
|
-
var
|
|
288
|
+
var import_ora2 = __toESM(require("ora"));
|
|
292
289
|
var import_inquirer = __toESM(require("inquirer"));
|
|
293
290
|
init_auth();
|
|
294
291
|
init_api();
|
|
295
292
|
|
|
296
|
-
// src/lib/cloudflared.ts
|
|
297
|
-
var fs2 = __toESM(require("fs"));
|
|
298
|
-
var path2 = __toESM(require("path"));
|
|
299
|
-
var readline = __toESM(require("readline"));
|
|
300
|
-
var import_child_process = require("child_process");
|
|
301
|
-
var import_ora2 = __toESM(require("ora"));
|
|
302
|
-
init_auth();
|
|
303
|
-
var TUNNEL_URL_RE = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/;
|
|
304
|
-
var DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
305
|
-
var TUNNEL_START_TIMEOUT_MS = 3e4;
|
|
306
|
-
function getCloudflaredFilename() {
|
|
307
|
-
const platform = process.platform;
|
|
308
|
-
const arch = process.arch;
|
|
309
|
-
if (platform === "darwin" && arch === "arm64") return "cloudflared-darwin-arm64";
|
|
310
|
-
if (platform === "darwin" && arch === "x64") return "cloudflared-darwin-amd64";
|
|
311
|
-
if (platform === "linux" && arch === "arm64") return "cloudflared-linux-arm64";
|
|
312
|
-
if (platform === "linux" && arch === "x64") return "cloudflared-linux-amd64";
|
|
313
|
-
if (platform === "win32" && arch === "x64") return "cloudflared-windows-amd64.exe";
|
|
314
|
-
throw new Error(`Unsupported platform: ${platform} ${arch}`);
|
|
315
|
-
}
|
|
316
|
-
function getCloudflaredBinPath() {
|
|
317
|
-
const filename = process.platform === "win32" ? "cloudflared.exe" : "cloudflared";
|
|
318
|
-
return path2.join(getApiblazeDir(), "bin", filename);
|
|
319
|
-
}
|
|
320
|
-
function isExecutable(filePath) {
|
|
321
|
-
try {
|
|
322
|
-
fs2.accessSync(filePath, fs2.constants.X_OK);
|
|
323
|
-
return true;
|
|
324
|
-
} catch {
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
async function downloadCloudflared(binPath) {
|
|
329
|
-
const filename = getCloudflaredFilename();
|
|
330
|
-
const url = `https://github.com/cloudflare/cloudflared/releases/latest/download/${filename}`;
|
|
331
|
-
const res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
|
|
332
|
-
if (!res.ok || !res.body) {
|
|
333
|
-
throw new Error(`Failed to download cloudflared: ${res.status} ${res.statusText}`);
|
|
334
|
-
}
|
|
335
|
-
fs2.mkdirSync(path2.dirname(binPath), { recursive: true });
|
|
336
|
-
const tmpPath = `${binPath}.tmp`;
|
|
337
|
-
const writer = fs2.createWriteStream(tmpPath);
|
|
338
|
-
const reader = res.body.getReader();
|
|
339
|
-
try {
|
|
340
|
-
while (true) {
|
|
341
|
-
const { done, value } = await reader.read();
|
|
342
|
-
if (done) break;
|
|
343
|
-
await new Promise((resolve, reject) => {
|
|
344
|
-
writer.write(value, (err) => err ? reject(err) : resolve());
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
} finally {
|
|
348
|
-
reader.releaseLock();
|
|
349
|
-
}
|
|
350
|
-
await new Promise((resolve, reject) => {
|
|
351
|
-
writer.end((err) => err ? reject(err) : resolve());
|
|
352
|
-
});
|
|
353
|
-
fs2.renameSync(tmpPath, binPath);
|
|
354
|
-
if (process.platform !== "win32") {
|
|
355
|
-
fs2.chmodSync(binPath, 493);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
async function ensureCloudflared() {
|
|
359
|
-
const binPath = getCloudflaredBinPath();
|
|
360
|
-
if (fs2.existsSync(binPath) && isExecutable(binPath)) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const spinner = (0, import_ora2.default)("Downloading cloudflared...").start();
|
|
364
|
-
try {
|
|
365
|
-
await downloadCloudflared(binPath);
|
|
366
|
-
spinner.succeed("cloudflared downloaded.");
|
|
367
|
-
} catch (err) {
|
|
368
|
-
spinner.fail("Failed to download cloudflared.");
|
|
369
|
-
throw err;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
function spawnCloudflared(port) {
|
|
373
|
-
return new Promise((resolve, reject) => {
|
|
374
|
-
const binPath = getCloudflaredBinPath();
|
|
375
|
-
const proc = (0, import_child_process.spawn)(binPath, ["tunnel", "--url", `http://localhost:${port}`], {
|
|
376
|
-
stdio: ["ignore", "ignore", "pipe"]
|
|
377
|
-
});
|
|
378
|
-
const timer = setTimeout(() => {
|
|
379
|
-
proc.kill();
|
|
380
|
-
reject(new Error("Timed out waiting for cloudflared tunnel URL (30s). Is something already running on the port?"));
|
|
381
|
-
}, TUNNEL_START_TIMEOUT_MS);
|
|
382
|
-
const rl = readline.createInterface({ input: proc.stderr });
|
|
383
|
-
rl.on("line", (line) => {
|
|
384
|
-
const match = line.match(TUNNEL_URL_RE);
|
|
385
|
-
if (match) {
|
|
386
|
-
clearTimeout(timer);
|
|
387
|
-
rl.close();
|
|
388
|
-
resolve({ process: proc, tunnelUrl: match[0] });
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
proc.on("error", (err) => {
|
|
392
|
-
clearTimeout(timer);
|
|
393
|
-
reject(new Error(`Failed to start cloudflared: ${err.message}`));
|
|
394
|
-
});
|
|
395
|
-
proc.on("exit", (code) => {
|
|
396
|
-
clearTimeout(timer);
|
|
397
|
-
if (code !== null && code !== 0) {
|
|
398
|
-
reject(new Error(`cloudflared exited with code ${code}`));
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
function killCloudflared(proc) {
|
|
404
|
-
try {
|
|
405
|
-
proc.kill("SIGTERM");
|
|
406
|
-
} catch {
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
293
|
// src/lib/traffic.ts
|
|
411
294
|
var import_chalk2 = __toESM(require("chalk"));
|
|
412
295
|
var METHOD_COLORS = {
|
|
@@ -441,50 +324,135 @@ function formatLogLine(entry) {
|
|
|
441
324
|
return `${import_chalk2.default.gray(`[${ts}]`)} ${colorMethod(entry.method)} ${import_chalk2.default.white(entry.path)} ${import_chalk2.default.gray("\u2192")} ${colorStatus(entry.status)} ${import_chalk2.default.gray(`(${colorLatency(entry.latency)})`)}`;
|
|
442
325
|
}
|
|
443
326
|
|
|
444
|
-
// src/lib/
|
|
445
|
-
var
|
|
446
|
-
var
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
327
|
+
// src/lib/tunnel-client.ts
|
|
328
|
+
var import_ws = __toESM(require("ws"));
|
|
329
|
+
var CHUNK_BYTES = 512 * 1024;
|
|
330
|
+
var PING_INTERVAL_MS = 6e4;
|
|
331
|
+
var MAX_RECONNECT_DELAY_MS = 15e3;
|
|
332
|
+
var STRIP_HEADERS = /* @__PURE__ */ new Set([
|
|
333
|
+
"host",
|
|
334
|
+
"content-length",
|
|
335
|
+
"connection",
|
|
336
|
+
"keep-alive",
|
|
337
|
+
"transfer-encoding",
|
|
338
|
+
"upgrade",
|
|
339
|
+
"proxy-connection",
|
|
340
|
+
"expect"
|
|
341
|
+
]);
|
|
342
|
+
function stripHeaders(headers) {
|
|
343
|
+
const out = {};
|
|
344
|
+
for (const key of Object.keys(headers)) {
|
|
345
|
+
if (!STRIP_HEADERS.has(key.toLowerCase())) out[key] = headers[key];
|
|
346
|
+
}
|
|
347
|
+
return out;
|
|
348
|
+
}
|
|
349
|
+
function startTunnelClient(opts) {
|
|
350
|
+
const target = `http://127.0.0.1:${opts.localPort}`;
|
|
351
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
352
|
+
let ws = null;
|
|
353
|
+
let closed = false;
|
|
354
|
+
let reconnects = 0;
|
|
355
|
+
let pingTimer;
|
|
356
|
+
function connect() {
|
|
357
|
+
const url = `${opts.connectUrl}?project=${encodeURIComponent(opts.projectId)}&token=${encodeURIComponent(opts.token)}`;
|
|
358
|
+
const socket = new import_ws.default(url);
|
|
359
|
+
ws = socket;
|
|
360
|
+
socket.on("open", () => {
|
|
361
|
+
reconnects = 0;
|
|
362
|
+
opts.onStatus?.("connected");
|
|
363
|
+
pingTimer = setInterval(() => {
|
|
364
|
+
try {
|
|
365
|
+
socket.send("ping");
|
|
366
|
+
} catch {
|
|
459
367
|
}
|
|
460
|
-
);
|
|
461
|
-
proxyReq.on("error", () => {
|
|
462
|
-
onEntry({ method, path: path3, status: 502, latency: Date.now() - start });
|
|
463
|
-
if (!res.headersSent) res.writeHead(502);
|
|
464
|
-
res.end();
|
|
465
|
-
});
|
|
466
|
-
req.pipe(proxyReq);
|
|
368
|
+
}, PING_INTERVAL_MS);
|
|
467
369
|
});
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
${headerLines}\r
|
|
473
|
-
\r
|
|
474
|
-
`);
|
|
475
|
-
if (head && head.length) upstream.write(head);
|
|
476
|
-
upstream.pipe(clientSocket);
|
|
477
|
-
clientSocket.pipe(upstream);
|
|
478
|
-
});
|
|
479
|
-
upstream.on("error", () => clientSocket.destroy());
|
|
480
|
-
clientSocket.on("error", () => upstream.destroy());
|
|
370
|
+
socket.on("message", (data) => handleFrame(socket, data.toString()));
|
|
371
|
+
socket.on("close", () => {
|
|
372
|
+
if (pingTimer) clearInterval(pingTimer);
|
|
373
|
+
if (!closed) scheduleReconnect();
|
|
481
374
|
});
|
|
482
|
-
|
|
483
|
-
server.listen(0, "127.0.0.1", () => {
|
|
484
|
-
const { port } = server.address();
|
|
485
|
-
resolve({ port, close: () => server.close() });
|
|
375
|
+
socket.on("error", () => {
|
|
486
376
|
});
|
|
487
|
-
}
|
|
377
|
+
}
|
|
378
|
+
function scheduleReconnect() {
|
|
379
|
+
const delay = Math.min(1e3 * 2 ** reconnects, MAX_RECONNECT_DELAY_MS);
|
|
380
|
+
reconnects++;
|
|
381
|
+
opts.onStatus?.(`disconnected \u2014 reconnecting in ${Math.round(delay / 1e3)}s`);
|
|
382
|
+
setTimeout(() => {
|
|
383
|
+
if (!closed) connect();
|
|
384
|
+
}, delay);
|
|
385
|
+
}
|
|
386
|
+
function handleFrame(socket, raw) {
|
|
387
|
+
let frame;
|
|
388
|
+
try {
|
|
389
|
+
frame = JSON.parse(raw);
|
|
390
|
+
} catch {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (frame.type === "req") {
|
|
394
|
+
inflight.set(frame.id, {
|
|
395
|
+
method: frame.method,
|
|
396
|
+
path: frame.path,
|
|
397
|
+
headers: frame.headers ?? {},
|
|
398
|
+
chunks: [],
|
|
399
|
+
start: Date.now()
|
|
400
|
+
});
|
|
401
|
+
if (frame.bodyLen === 0) finish(socket, frame.id);
|
|
402
|
+
} else if (frame.type === "chunk") {
|
|
403
|
+
const f = inflight.get(frame.id);
|
|
404
|
+
if (!f) return;
|
|
405
|
+
f.chunks.push(Buffer.from(frame.data ?? "", "base64"));
|
|
406
|
+
if (frame.final) finish(socket, frame.id);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function finish(socket, id) {
|
|
410
|
+
const f = inflight.get(id);
|
|
411
|
+
if (!f) return;
|
|
412
|
+
inflight.delete(id);
|
|
413
|
+
void forward(socket, id, f);
|
|
414
|
+
}
|
|
415
|
+
async function forward(socket, id, f) {
|
|
416
|
+
const body = Buffer.concat(f.chunks);
|
|
417
|
+
const init = { method: f.method, headers: stripHeaders(f.headers) };
|
|
418
|
+
if (body.length) init.body = body;
|
|
419
|
+
let status = 502;
|
|
420
|
+
try {
|
|
421
|
+
const resp = await fetch(target + f.path, init);
|
|
422
|
+
status = resp.status;
|
|
423
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
424
|
+
const headers = {};
|
|
425
|
+
resp.headers.forEach((value, key) => {
|
|
426
|
+
if (!STRIP_HEADERS.has(key.toLowerCase())) headers[key] = value;
|
|
427
|
+
});
|
|
428
|
+
send(socket, { id, type: "res", status, headers, bodyLen: buf.length });
|
|
429
|
+
for (let off = 0, seq = 0; off < buf.length; off += CHUNK_BYTES) {
|
|
430
|
+
const slice = buf.subarray(off, Math.min(off + CHUNK_BYTES, buf.length));
|
|
431
|
+
send(socket, { id, type: "chunk", seq: seq++, data: slice.toString("base64"), final: off + CHUNK_BYTES >= buf.length });
|
|
432
|
+
}
|
|
433
|
+
} catch (err) {
|
|
434
|
+
const message = err?.cause?.message || err?.message || String(err);
|
|
435
|
+
send(socket, { id, type: "err", message });
|
|
436
|
+
}
|
|
437
|
+
opts.onEntry({ method: f.method, path: f.path, status, latency: Date.now() - f.start });
|
|
438
|
+
}
|
|
439
|
+
function send(socket, frame) {
|
|
440
|
+
try {
|
|
441
|
+
socket.send(JSON.stringify(frame));
|
|
442
|
+
} catch {
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
connect();
|
|
446
|
+
return {
|
|
447
|
+
close() {
|
|
448
|
+
closed = true;
|
|
449
|
+
if (pingTimer) clearInterval(pingTimer);
|
|
450
|
+
try {
|
|
451
|
+
ws?.close();
|
|
452
|
+
} catch {
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
};
|
|
488
456
|
}
|
|
489
457
|
|
|
490
458
|
// src/commands/dev.ts
|
|
@@ -519,7 +487,7 @@ async function runDev(options) {
|
|
|
519
487
|
}
|
|
520
488
|
let targets;
|
|
521
489
|
{
|
|
522
|
-
const spinner = (0,
|
|
490
|
+
const spinner = (0, import_ora2.default)("Fetching your localhost projects...").start();
|
|
523
491
|
try {
|
|
524
492
|
targets = await getLocalhostTargets(teamId);
|
|
525
493
|
spinner.stop();
|
|
@@ -529,8 +497,8 @@ async function runDev(options) {
|
|
|
529
497
|
}
|
|
530
498
|
}
|
|
531
499
|
if (targets.length === 0) {
|
|
532
|
-
console.log(import_chalk3.default.yellow("No projects found with
|
|
533
|
-
console.log("Set a project's upstream target to localhost in your APIblaze dashboard, then try again.");
|
|
500
|
+
console.log(import_chalk3.default.yellow("No projects found with an internal target."));
|
|
501
|
+
console.log("Set a project's upstream target to localhost or a private IP in your APIblaze dashboard, then try again.");
|
|
534
502
|
process.exit(0);
|
|
535
503
|
}
|
|
536
504
|
let selectedTargets;
|
|
@@ -538,7 +506,7 @@ async function runDev(options) {
|
|
|
538
506
|
const { confirmed } = await import_inquirer.default.prompt([{
|
|
539
507
|
type: "confirm",
|
|
540
508
|
name: "confirmed",
|
|
541
|
-
message: `Found 1 project
|
|
509
|
+
message: `Found 1 project with an internal target \u2014 tunnel "${import_chalk3.default.bold(targets[0].projectName)}" (${targets[0].tenantName})?`,
|
|
542
510
|
default: true
|
|
543
511
|
}]);
|
|
544
512
|
if (!confirmed) {
|
|
@@ -550,7 +518,7 @@ async function runDev(options) {
|
|
|
550
518
|
const { chosen } = await import_inquirer.default.prompt([{
|
|
551
519
|
type: "checkbox",
|
|
552
520
|
name: "chosen",
|
|
553
|
-
message: `Found ${targets.length} projects
|
|
521
|
+
message: `Found ${targets.length} projects with an internal target \u2014 select which to tunnel:`,
|
|
554
522
|
choices: targets.map((t) => ({
|
|
555
523
|
name: `${import_chalk3.default.bold(t.projectName)} (${t.tenantName}) \u2014 ${t.target}`,
|
|
556
524
|
value: t,
|
|
@@ -568,40 +536,32 @@ async function runDev(options) {
|
|
|
568
536
|
Tunneling ${selectedTargets.length} project(s) to localhost:${options.port}
|
|
569
537
|
`)
|
|
570
538
|
);
|
|
571
|
-
await ensureCloudflared();
|
|
572
|
-
const logger = await startPassthroughProxy(options.port, (entry) => {
|
|
573
|
-
console.log(formatLogLine(entry));
|
|
574
|
-
});
|
|
575
|
-
let cfProcess;
|
|
576
|
-
let tunnelUrl;
|
|
577
|
-
{
|
|
578
|
-
const spinner = (0, import_ora3.default)("Starting Cloudflare tunnel...").start();
|
|
579
|
-
try {
|
|
580
|
-
({ process: cfProcess, tunnelUrl } = await spawnCloudflared(logger.port));
|
|
581
|
-
spinner.succeed(`Tunnel active: ${import_chalk3.default.bold.cyan(tunnelUrl)}`);
|
|
582
|
-
} catch (err) {
|
|
583
|
-
spinner.fail("Failed to start cloudflared tunnel.");
|
|
584
|
-
logger.close();
|
|
585
|
-
throw err;
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
539
|
let restore = [];
|
|
540
|
+
let connect;
|
|
589
541
|
{
|
|
590
|
-
const spinner = (0,
|
|
542
|
+
const spinner = (0, import_ora2.default)("Registering tunnel with APIblaze...").start();
|
|
591
543
|
try {
|
|
592
544
|
const result = await putDevTunnel({
|
|
593
|
-
tunnelUrl,
|
|
594
545
|
targets: selectedTargets.map((t) => ({ projectId: t.projectId, tenantId: t.tenantId }))
|
|
595
546
|
});
|
|
596
547
|
restore = result.restore ?? [];
|
|
597
|
-
|
|
548
|
+
connect = result.connect;
|
|
549
|
+
spinner.succeed("Tunnel registered.");
|
|
598
550
|
} catch (err) {
|
|
599
551
|
spinner.fail("Failed to register tunnel.");
|
|
600
|
-
logger.close();
|
|
601
|
-
killCloudflared(cfProcess);
|
|
602
552
|
throw err;
|
|
603
553
|
}
|
|
604
554
|
}
|
|
555
|
+
const clients = connect.projects.map(
|
|
556
|
+
(projectId) => startTunnelClient({
|
|
557
|
+
connectUrl: connect.url,
|
|
558
|
+
token: connect.token,
|
|
559
|
+
projectId,
|
|
560
|
+
localPort: options.port,
|
|
561
|
+
onEntry: (entry) => console.log(formatLogLine(entry)),
|
|
562
|
+
onStatus: (status) => console.log(import_chalk3.default.gray(`[${projectId}] ${status}`))
|
|
563
|
+
})
|
|
564
|
+
);
|
|
605
565
|
console.log("\n" + import_chalk3.default.gray("\u2500".repeat(60)));
|
|
606
566
|
console.log(import_chalk3.default.bold("Live traffic") + import_chalk3.default.gray(" (Ctrl+C to stop)"));
|
|
607
567
|
console.log(import_chalk3.default.gray("\u2500".repeat(60)) + "\n");
|
|
@@ -610,10 +570,9 @@ Tunneling ${selectedTargets.length} project(s) to localhost:${options.port}
|
|
|
610
570
|
if (isCleaningUp) return;
|
|
611
571
|
isCleaningUp = true;
|
|
612
572
|
console.log(import_chalk3.default.gray("\n\nShutting down..."));
|
|
573
|
+
for (const client of clients) client.close();
|
|
613
574
|
await deleteDevTunnel(restore).catch(() => {
|
|
614
575
|
});
|
|
615
|
-
logger.close();
|
|
616
|
-
killCloudflared(cfProcess);
|
|
617
576
|
console.log(import_chalk3.default.green("Tunnel stopped."));
|
|
618
577
|
process.exit(0);
|
|
619
578
|
}
|
|
@@ -625,7 +584,7 @@ Tunneling ${selectedTargets.length} project(s) to localhost:${options.port}
|
|
|
625
584
|
|
|
626
585
|
// src/commands/projects.ts
|
|
627
586
|
var import_chalk4 = __toESM(require("chalk"));
|
|
628
|
-
var
|
|
587
|
+
var import_ora3 = __toESM(require("ora"));
|
|
629
588
|
init_auth();
|
|
630
589
|
init_api();
|
|
631
590
|
async function runProjects() {
|
|
@@ -662,7 +621,7 @@ async function runProjects() {
|
|
|
662
621
|
}
|
|
663
622
|
console.log(`${import_chalk4.default.cyan("\u2192")} Team: ${import_chalk4.default.bold(teamName ?? teamId)}
|
|
664
623
|
`);
|
|
665
|
-
const spinner = (0,
|
|
624
|
+
const spinner = (0, import_ora3.default)("Fetching projects...").start();
|
|
666
625
|
let projects;
|
|
667
626
|
try {
|
|
668
627
|
projects = await getProjects(teamId);
|
|
@@ -685,7 +644,7 @@ ${projects.length} project${projects.length === 1 ? "" : "s"}`));
|
|
|
685
644
|
|
|
686
645
|
// src/commands/create.ts
|
|
687
646
|
var import_chalk5 = __toESM(require("chalk"));
|
|
688
|
-
var
|
|
647
|
+
var import_ora4 = __toESM(require("ora"));
|
|
689
648
|
init_auth();
|
|
690
649
|
init_api();
|
|
691
650
|
function normalizeName(raw) {
|
|
@@ -764,7 +723,7 @@ async function runCreate(opts = {}) {
|
|
|
764
723
|
console.log(import_chalk5.default.yellow(" Name must be at least 3 characters (letters and digits only).\n"));
|
|
765
724
|
continue;
|
|
766
725
|
}
|
|
767
|
-
const spinner2 = (0,
|
|
726
|
+
const spinner2 = (0, import_ora4.default)("Checking availability...").start();
|
|
768
727
|
try {
|
|
769
728
|
const check = await checkProxyName(name, teamId);
|
|
770
729
|
spinner2.stop();
|
|
@@ -820,7 +779,7 @@ async function runCreate(opts = {}) {
|
|
|
820
779
|
return;
|
|
821
780
|
}
|
|
822
781
|
}
|
|
823
|
-
const spinner = !opts.json ? (0,
|
|
782
|
+
const spinner = !opts.json ? (0, import_ora4.default)("Creating proxy (tenant, keys, dev portal)...").start() : null;
|
|
824
783
|
let result;
|
|
825
784
|
try {
|
|
826
785
|
result = await createProxy({ name, target_url: targetUrl, auth_type: auth, team_id: teamId });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apiblaze",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Dev tunnel CLI for APIblaze — route localhost projects through
|
|
3
|
+
"version": "0.1.13",
|
|
4
|
+
"description": "Dev tunnel CLI for APIblaze — route localhost projects through your APIblaze endpoints",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apiblaze",
|
|
7
7
|
"dev-tunnel",
|
|
@@ -32,11 +32,13 @@
|
|
|
32
32
|
"chalk": "^4.1.2",
|
|
33
33
|
"commander": "^11.1.0",
|
|
34
34
|
"inquirer": "^8.2.6",
|
|
35
|
-
"ora": "^5.4.1"
|
|
35
|
+
"ora": "^5.4.1",
|
|
36
|
+
"ws": "^8.17.0"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@types/inquirer": "^8.2.10",
|
|
39
40
|
"@types/node": "^20.0.0",
|
|
41
|
+
"@types/ws": "^8.5.10",
|
|
40
42
|
"tsup": "^8.0.0",
|
|
41
43
|
"typescript": "^5.4.0"
|
|
42
44
|
}
|