apiblaze 0.1.5 → 0.1.7
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 +154 -33
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -87,6 +87,8 @@ var init_auth = __esm({
|
|
|
87
87
|
// src/lib/api.ts
|
|
88
88
|
var api_exports = {};
|
|
89
89
|
__export(api_exports, {
|
|
90
|
+
checkProxyName: () => checkProxyName,
|
|
91
|
+
createProxy: () => createProxy,
|
|
90
92
|
deleteDevTunnel: () => deleteDevTunnel,
|
|
91
93
|
getLocalhostTargets: () => getLocalhostTargets,
|
|
92
94
|
getProjects: () => getProjects,
|
|
@@ -119,7 +121,12 @@ async function apiFetch(path3, options = {}) {
|
|
|
119
121
|
return res.json();
|
|
120
122
|
}
|
|
121
123
|
async function getTeams() {
|
|
122
|
-
|
|
124
|
+
const res = await apiFetch("/api/cli/teams");
|
|
125
|
+
const raw = Array.isArray(res) ? res : res?.teams ?? res?.data ?? [];
|
|
126
|
+
return raw.map((t) => {
|
|
127
|
+
const teamId = t.teamId ?? t.team_id;
|
|
128
|
+
return { teamId: teamId ?? "", name: t.name ?? teamId ?? "" };
|
|
129
|
+
}).filter((t) => t.teamId);
|
|
123
130
|
}
|
|
124
131
|
async function getLocalhostTargets(teamId) {
|
|
125
132
|
return apiFetch(`/api/cli/localhost-targets?team_id=${encodeURIComponent(teamId)}`);
|
|
@@ -127,6 +134,15 @@ async function getLocalhostTargets(teamId) {
|
|
|
127
134
|
async function getProjects(teamId) {
|
|
128
135
|
return apiFetch(`/api/cli/projects?team_id=${encodeURIComponent(teamId)}`);
|
|
129
136
|
}
|
|
137
|
+
async function checkProxyName(name) {
|
|
138
|
+
return apiFetch(`/api/cli/check-name?name=${encodeURIComponent(name)}`);
|
|
139
|
+
}
|
|
140
|
+
async function createProxy(payload) {
|
|
141
|
+
return apiFetch("/api/cli/create-proxy", {
|
|
142
|
+
method: "POST",
|
|
143
|
+
body: JSON.stringify(payload)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
130
146
|
async function putDevTunnel(payload) {
|
|
131
147
|
return apiFetch("/api/cli/dev-tunnel", {
|
|
132
148
|
method: "PUT",
|
|
@@ -148,7 +164,7 @@ var init_api = __esm({
|
|
|
148
164
|
|
|
149
165
|
// src/index.ts
|
|
150
166
|
var import_commander = require("commander");
|
|
151
|
-
var
|
|
167
|
+
var import_chalk6 = __toESM(require("chalk"));
|
|
152
168
|
init_types();
|
|
153
169
|
|
|
154
170
|
// src/commands/login.ts
|
|
@@ -226,7 +242,7 @@ async function runLogin() {
|
|
|
226
242
|
});
|
|
227
243
|
spinner.succeed(import_chalk.default.green("Authorized!"));
|
|
228
244
|
if (githubHandle) {
|
|
229
|
-
console.log(`${import_chalk.default.cyan("\u2192")} Logged in as ${import_chalk.default.bold("@" + githubHandle)}
|
|
245
|
+
console.log(`${import_chalk.default.cyan("\u2192")} Logged in as ${import_chalk.default.bold("@" + githubHandle)}`);
|
|
230
246
|
}
|
|
231
247
|
let teamId = defaultTeamId ?? void 0;
|
|
232
248
|
let teamName;
|
|
@@ -602,36 +618,32 @@ async function runProjects() {
|
|
|
602
618
|
process.exit(1);
|
|
603
619
|
}
|
|
604
620
|
if (creds.githubHandle) {
|
|
605
|
-
console.log(
|
|
606
|
-
`${import_chalk4.default.cyan("\u2192")} Logged in as ${import_chalk4.default.bold("@" + creds.githubHandle)}` + (creds.apiblazeUserId ? import_chalk4.default.dim(` (${creds.apiblazeUserId})`) : "")
|
|
607
|
-
);
|
|
621
|
+
console.log(`${import_chalk4.default.cyan("\u2192")} Logged in as ${import_chalk4.default.bold("@" + creds.githubHandle)}`);
|
|
608
622
|
}
|
|
609
|
-
let teamId;
|
|
610
|
-
let teamName;
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
teamId = chosen;
|
|
628
|
-
teamName = teams.find((t) => t.teamId === chosen)?.name;
|
|
623
|
+
let teamId = creds.teamId;
|
|
624
|
+
let teamName = creds.teamName;
|
|
625
|
+
if (!teamId) {
|
|
626
|
+
const teams = await getTeams().catch(() => []);
|
|
627
|
+
if (teams.length === 1) {
|
|
628
|
+
teamId = teams[0].teamId;
|
|
629
|
+
teamName = teams[0].name;
|
|
630
|
+
} else if (teams.length > 1) {
|
|
631
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
632
|
+
const { chosen } = await inquirer2.prompt([{
|
|
633
|
+
type: "list",
|
|
634
|
+
name: "chosen",
|
|
635
|
+
message: "Which team do you want to use?",
|
|
636
|
+
choices: teams.map((t) => ({ name: t.name, value: t.teamId }))
|
|
637
|
+
}]);
|
|
638
|
+
teamId = chosen;
|
|
639
|
+
teamName = teams.find((t) => t.teamId === chosen)?.name;
|
|
640
|
+
}
|
|
629
641
|
}
|
|
630
642
|
if (!teamId) {
|
|
631
643
|
console.error(import_chalk4.default.red("No team found. Run `apiblaze login` to set up your team."));
|
|
632
644
|
process.exit(1);
|
|
633
645
|
}
|
|
634
|
-
console.log(`${import_chalk4.default.cyan("\u2192")} Team: ${import_chalk4.default.bold(teamName ?? teamId)}
|
|
646
|
+
console.log(`${import_chalk4.default.cyan("\u2192")} Team: ${import_chalk4.default.bold(teamName ?? teamId)}
|
|
635
647
|
`);
|
|
636
648
|
const spinner = (0, import_ora4.default)("Fetching projects...").start();
|
|
637
649
|
let projects;
|
|
@@ -646,12 +658,113 @@ async function runProjects() {
|
|
|
646
658
|
console.log(import_chalk4.default.yellow("No projects found for this team."));
|
|
647
659
|
return;
|
|
648
660
|
}
|
|
661
|
+
const width = Math.max(...projects.map((p) => p.projectName.length));
|
|
649
662
|
for (const p of projects) {
|
|
650
|
-
console.log(
|
|
651
|
-
console.log(` ${import_chalk4.default.dim("version:")} ${p.apiVersion} ${import_chalk4.default.dim("team:")} ${p.teamId}`);
|
|
663
|
+
console.log(` ${import_chalk4.default.bold(p.projectName.padEnd(width))} ${import_chalk4.default.dim("v" + p.apiVersion)}`);
|
|
652
664
|
}
|
|
653
665
|
console.log(import_chalk4.default.dim(`
|
|
654
|
-
${projects.length} project
|
|
666
|
+
${projects.length} project${projects.length === 1 ? "" : "s"}`));
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// src/commands/create.ts
|
|
670
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
671
|
+
var import_ora5 = __toESM(require("ora"));
|
|
672
|
+
init_auth();
|
|
673
|
+
init_api();
|
|
674
|
+
function normalizeName(raw) {
|
|
675
|
+
return (raw || "").toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
676
|
+
}
|
|
677
|
+
function isHttpUrl(s) {
|
|
678
|
+
try {
|
|
679
|
+
const u = new URL(s.trim());
|
|
680
|
+
return u.protocol === "http:" || u.protocol === "https:";
|
|
681
|
+
} catch {
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
async function runCreate() {
|
|
686
|
+
const creds = loadCredentials();
|
|
687
|
+
if (!creds) {
|
|
688
|
+
console.error(import_chalk5.default.red("Not logged in. Run `apiblaze login` first."));
|
|
689
|
+
process.exit(1);
|
|
690
|
+
}
|
|
691
|
+
console.log(import_chalk5.default.bold("\nCreate an API proxy\n"));
|
|
692
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
693
|
+
let name = "";
|
|
694
|
+
for (; ; ) {
|
|
695
|
+
const { rawName } = await inquirer2.prompt([{
|
|
696
|
+
type: "input",
|
|
697
|
+
name: "rawName",
|
|
698
|
+
message: "Proxy name (your API will live at <name>.apiblaze.com):",
|
|
699
|
+
transformer: (v) => normalizeName(v)
|
|
700
|
+
}]);
|
|
701
|
+
name = normalizeName(rawName);
|
|
702
|
+
if (name.length < 3) {
|
|
703
|
+
console.log(import_chalk5.default.yellow(" Name must be at least 3 characters (letters and digits only).\n"));
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
const spinner2 = (0, import_ora5.default)("Checking availability...").start();
|
|
707
|
+
try {
|
|
708
|
+
const check = await checkProxyName(name);
|
|
709
|
+
spinner2.stop();
|
|
710
|
+
if (!check.canUseProjectName || !check.canUseApiVersion) {
|
|
711
|
+
const why = check.message ? ` \u2014 ${check.message}` : "";
|
|
712
|
+
console.log(import_chalk5.default.yellow(` "${name}" is not available${why}. Try another.
|
|
713
|
+
`));
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
} catch {
|
|
717
|
+
spinner2.stop();
|
|
718
|
+
console.log(import_chalk5.default.dim(" (could not verify availability; continuing)"));
|
|
719
|
+
}
|
|
720
|
+
console.log(`${import_chalk5.default.cyan("\u2192")} Your API will live at ${import_chalk5.default.bold(`https://${name}.apiblaze.com`)}
|
|
721
|
+
`);
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
let targetUrl = "";
|
|
725
|
+
for (; ; ) {
|
|
726
|
+
const { url } = await inquirer2.prompt([{
|
|
727
|
+
type: "input",
|
|
728
|
+
name: "url",
|
|
729
|
+
message: "Target URL to forward requests to (e.g. https://httpbin.org):"
|
|
730
|
+
}]);
|
|
731
|
+
if (!isHttpUrl(url)) {
|
|
732
|
+
console.log(import_chalk5.default.yellow(" Enter a valid http(s) URL.\n"));
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
targetUrl = url.trim();
|
|
736
|
+
break;
|
|
737
|
+
}
|
|
738
|
+
console.log(`${import_chalk5.default.cyan("\u2192")} Auth: ${import_chalk5.default.bold("API key")} \u2014 consumers send an X-API-Key header
|
|
739
|
+
`);
|
|
740
|
+
const spinner = (0, import_ora5.default)("Creating proxy (tenant, keys, dev portal)...").start();
|
|
741
|
+
let result;
|
|
742
|
+
try {
|
|
743
|
+
result = await createProxy({ name, target_url: targetUrl, auth_type: "api_key" });
|
|
744
|
+
spinner.succeed(import_chalk5.default.green("Proxy created!"));
|
|
745
|
+
} catch (err) {
|
|
746
|
+
spinner.fail("Failed to create proxy.");
|
|
747
|
+
throw err;
|
|
748
|
+
}
|
|
749
|
+
const version = result.api_version || "1.0.0";
|
|
750
|
+
const keys = result.api_keys ?? {};
|
|
751
|
+
const adminKey = keys.prod ?? Object.values(keys)[0];
|
|
752
|
+
console.log();
|
|
753
|
+
console.log(` ${import_chalk5.default.dim("Proxy URL: ")} ${import_chalk5.default.bold(`https://${name}.apiblaze.com/${version}/prod`)}`);
|
|
754
|
+
if (result.devPortal) {
|
|
755
|
+
console.log(` ${import_chalk5.default.dim("Dev portal:")} ${import_chalk5.default.bold(result.devPortal)}`);
|
|
756
|
+
}
|
|
757
|
+
if (adminKey) {
|
|
758
|
+
console.log();
|
|
759
|
+
console.log(` ${import_chalk5.default.dim("Consumer admin API key (prod):")}`);
|
|
760
|
+
console.log(` ${import_chalk5.default.bold.green(adminKey)}`);
|
|
761
|
+
console.log(import_chalk5.default.dim("\n Save this now \u2014 send it as the X-API-Key header. It may not be shown again."));
|
|
762
|
+
const otherEnvs = Object.keys(keys).filter((e) => e !== "prod");
|
|
763
|
+
if (otherEnvs.length) {
|
|
764
|
+
console.log(import_chalk5.default.dim(` (Separate keys were also created for: ${otherEnvs.join(", ")}.)`));
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
console.log();
|
|
655
768
|
}
|
|
656
769
|
|
|
657
770
|
// src/index.ts
|
|
@@ -665,6 +778,14 @@ program.command("login").description("Authenticate with APIblaze").action(async
|
|
|
665
778
|
process.exit(1);
|
|
666
779
|
}
|
|
667
780
|
});
|
|
781
|
+
program.command("create").description("Create a new API proxy").action(async () => {
|
|
782
|
+
try {
|
|
783
|
+
await runCreate();
|
|
784
|
+
} catch (err) {
|
|
785
|
+
printError(err);
|
|
786
|
+
process.exit(1);
|
|
787
|
+
}
|
|
788
|
+
});
|
|
668
789
|
program.command("projects").description("List the projects in your team").action(async () => {
|
|
669
790
|
try {
|
|
670
791
|
await runProjects();
|
|
@@ -683,13 +804,13 @@ program.command("dev").description("Start a dev tunnel for your localhost projec
|
|
|
683
804
|
});
|
|
684
805
|
function printError(err) {
|
|
685
806
|
if (err instanceof ApiError) {
|
|
686
|
-
console.error(
|
|
807
|
+
console.error(import_chalk6.default.red(`
|
|
687
808
|
API error (${err.status}): ${err.message}`));
|
|
688
809
|
} else if (err instanceof Error) {
|
|
689
|
-
console.error(
|
|
810
|
+
console.error(import_chalk6.default.red(`
|
|
690
811
|
Error: ${err.message}`));
|
|
691
812
|
} else {
|
|
692
|
-
console.error(
|
|
813
|
+
console.error(import_chalk6.default.red("\nUnknown error"));
|
|
693
814
|
}
|
|
694
815
|
}
|
|
695
816
|
program.parse(process.argv);
|