apiblaze 0.1.17 → 0.1.19
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 +297 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51,6 +51,14 @@ function saveCredentials(creds) {
|
|
|
51
51
|
fs.writeFileSync(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
|
|
52
52
|
fs.chmodSync(CREDENTIALS_PATH, 384);
|
|
53
53
|
}
|
|
54
|
+
function clearCredentials() {
|
|
55
|
+
try {
|
|
56
|
+
fs.unlinkSync(CREDENTIALS_PATH);
|
|
57
|
+
return true;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
54
62
|
function loadCredentials() {
|
|
55
63
|
try {
|
|
56
64
|
const raw = fs.readFileSync(CREDENTIALS_PATH, "utf-8");
|
|
@@ -85,13 +93,32 @@ var init_auth = __esm({
|
|
|
85
93
|
var api_exports = {};
|
|
86
94
|
__export(api_exports, {
|
|
87
95
|
checkProxyName: () => checkProxyName,
|
|
96
|
+
claimProxy: () => claimProxy,
|
|
88
97
|
createProxy: () => createProxy,
|
|
98
|
+
createProxyAnonymous: () => createProxyAnonymous,
|
|
89
99
|
deleteDevTunnel: () => deleteDevTunnel,
|
|
90
100
|
getLocalhostTargets: () => getLocalhostTargets,
|
|
91
101
|
getProjects: () => getProjects,
|
|
92
102
|
getTeams: () => getTeams,
|
|
93
103
|
putDevTunnel: () => putDevTunnel
|
|
94
104
|
});
|
|
105
|
+
async function createProxyAnonymous(body) {
|
|
106
|
+
const res = await fetch(`${PUBLIC_API_BASE}/proxy`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: { "Content-Type": "application/json" },
|
|
109
|
+
body: JSON.stringify(body)
|
|
110
|
+
});
|
|
111
|
+
if (!res.ok) {
|
|
112
|
+
let message = res.statusText;
|
|
113
|
+
try {
|
|
114
|
+
const b = await res.json();
|
|
115
|
+
message = b.details ?? b.error ?? message;
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
throw new ApiError(res.status, message);
|
|
119
|
+
}
|
|
120
|
+
return res.json();
|
|
121
|
+
}
|
|
95
122
|
async function apiFetch(path2, options = {}) {
|
|
96
123
|
const token = getAccessToken();
|
|
97
124
|
const url = `${DASHBOARD_BASE}${path2}`;
|
|
@@ -141,6 +168,12 @@ async function createProxy(payload) {
|
|
|
141
168
|
body: JSON.stringify(payload)
|
|
142
169
|
});
|
|
143
170
|
}
|
|
171
|
+
async function claimProxy(claimCode, teamId) {
|
|
172
|
+
return apiFetch("/api/cli/claim", {
|
|
173
|
+
method: "POST",
|
|
174
|
+
body: JSON.stringify({ claimCode, team_id: teamId })
|
|
175
|
+
});
|
|
176
|
+
}
|
|
144
177
|
async function putDevTunnel(payload) {
|
|
145
178
|
return apiFetch("/api/cli/dev-tunnel", {
|
|
146
179
|
method: "PUT",
|
|
@@ -153,22 +186,23 @@ async function deleteDevTunnel(restore) {
|
|
|
153
186
|
body: JSON.stringify({ restore })
|
|
154
187
|
});
|
|
155
188
|
}
|
|
156
|
-
var DASHBOARD_BASE;
|
|
189
|
+
var DASHBOARD_BASE, PUBLIC_API_BASE;
|
|
157
190
|
var init_api = __esm({
|
|
158
191
|
"src/lib/api.ts"() {
|
|
159
192
|
"use strict";
|
|
160
193
|
init_auth();
|
|
161
194
|
init_types();
|
|
162
195
|
DASHBOARD_BASE = "https://dashboard.apiblaze.com";
|
|
196
|
+
PUBLIC_API_BASE = "https://api.apiblaze.com";
|
|
163
197
|
}
|
|
164
198
|
});
|
|
165
199
|
|
|
166
200
|
// src/index.ts
|
|
167
201
|
var import_commander = require("commander");
|
|
168
|
-
var
|
|
202
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
169
203
|
|
|
170
204
|
// package.json
|
|
171
|
-
var version = "0.1.
|
|
205
|
+
var version = "0.1.19";
|
|
172
206
|
|
|
173
207
|
// src/index.ts
|
|
174
208
|
init_types();
|
|
@@ -649,6 +683,7 @@ ${projects.length} project${projects.length === 1 ? "" : "s"}`));
|
|
|
649
683
|
}
|
|
650
684
|
|
|
651
685
|
// src/commands/create.ts
|
|
686
|
+
var import_fs = __toESM(require("fs"));
|
|
652
687
|
var import_chalk5 = __toESM(require("chalk"));
|
|
653
688
|
var import_ora4 = __toESM(require("ora"));
|
|
654
689
|
init_auth();
|
|
@@ -684,7 +719,8 @@ var VALID_AUTH = ["api_key", "none", "oauth"];
|
|
|
684
719
|
async function runCreate(opts = {}) {
|
|
685
720
|
const creds = loadCredentials();
|
|
686
721
|
if (!creds) {
|
|
687
|
-
|
|
722
|
+
await runAnonymousCreate(opts);
|
|
723
|
+
return;
|
|
688
724
|
}
|
|
689
725
|
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
690
726
|
const auth = (opts.auth ?? "api_key").toLowerCase();
|
|
@@ -826,8 +862,123 @@ async function runCreate(opts = {}) {
|
|
|
826
862
|
}
|
|
827
863
|
console.log();
|
|
828
864
|
}
|
|
865
|
+
async function runAnonymousCreate(opts) {
|
|
866
|
+
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
867
|
+
if (!opts.json) {
|
|
868
|
+
console.log(import_chalk5.default.bold("\nCreate an API proxy"));
|
|
869
|
+
console.log(import_chalk5.default.dim("Not logged in \u2014 creating an anonymous proxy. You can claim it to your account within 30 days.\n"));
|
|
870
|
+
}
|
|
871
|
+
let body = {};
|
|
872
|
+
if (opts.config) {
|
|
873
|
+
let raw = "";
|
|
874
|
+
try {
|
|
875
|
+
raw = import_fs.default.readFileSync(opts.config, "utf8");
|
|
876
|
+
} catch {
|
|
877
|
+
fail(`Cannot read --config file: ${opts.config}`);
|
|
878
|
+
}
|
|
879
|
+
let parsed;
|
|
880
|
+
try {
|
|
881
|
+
parsed = JSON.parse(raw);
|
|
882
|
+
} catch {
|
|
883
|
+
fail(`--config is not valid JSON: ${opts.config}`);
|
|
884
|
+
}
|
|
885
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) fail("--config must be a JSON object.");
|
|
886
|
+
body = parsed;
|
|
887
|
+
}
|
|
888
|
+
let name = opts.name !== void 0 ? normalizeName(opts.name) : typeof body.name === "string" ? body.name : void 0;
|
|
889
|
+
if (opts.name !== void 0 && name.length < 3) {
|
|
890
|
+
fail("Proxy name must be at least 3 characters (letters and digits only).");
|
|
891
|
+
}
|
|
892
|
+
if (opts.target && !isHttpUrl(opts.target)) fail("--target must be a valid http(s) URL.");
|
|
893
|
+
let target = opts.target?.trim() || (typeof body.target === "string" ? body.target : "") || (typeof body.target_url === "string" ? body.target_url : "");
|
|
894
|
+
const hasOtherSource = !!(body.openapi || body.github);
|
|
895
|
+
if (!target && !hasOtherSource) {
|
|
896
|
+
if (interactive) {
|
|
897
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
898
|
+
if (name === void 0) {
|
|
899
|
+
const { rawName } = await inquirer2.prompt([{
|
|
900
|
+
type: "input",
|
|
901
|
+
name: "rawName",
|
|
902
|
+
message: "Proxy name (leave blank to auto-generate):",
|
|
903
|
+
transformer: (v) => normalizeName(v)
|
|
904
|
+
}]);
|
|
905
|
+
const n = normalizeName(rawName);
|
|
906
|
+
name = n.length >= 3 ? n : void 0;
|
|
907
|
+
}
|
|
908
|
+
for (; ; ) {
|
|
909
|
+
const { url } = await inquirer2.prompt([{
|
|
910
|
+
type: "input",
|
|
911
|
+
name: "url",
|
|
912
|
+
message: "Target URL to forward requests to (e.g. https://httpbin.org):"
|
|
913
|
+
}]);
|
|
914
|
+
if (!isHttpUrl(url)) {
|
|
915
|
+
console.log(import_chalk5.default.yellow(" Enter a valid http(s) URL.\n"));
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
target = url.trim();
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
} else {
|
|
922
|
+
fail("A source is required: pass --target, or target/openapi/github in --config.");
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
if (target) {
|
|
926
|
+
body.target = target;
|
|
927
|
+
body.target_url = target;
|
|
928
|
+
}
|
|
929
|
+
if (name) {
|
|
930
|
+
body.name = name;
|
|
931
|
+
body.subdomain = name;
|
|
932
|
+
}
|
|
933
|
+
if (opts.subdomain) body.subdomain = normalizeName(opts.subdomain);
|
|
934
|
+
if (opts.tenant) body.tenant = normalizeName(opts.tenant);
|
|
935
|
+
if (opts.product) body.product_slug = normalizeName(opts.product);
|
|
936
|
+
if (opts.displayName) body.display_name = opts.displayName;
|
|
937
|
+
if (opts.auth && opts.auth !== "api_key") body.auth_type = opts.auth;
|
|
938
|
+
const spinner = !opts.json ? (0, import_ora4.default)("Creating proxy...").start() : null;
|
|
939
|
+
let result;
|
|
940
|
+
try {
|
|
941
|
+
result = await createProxyAnonymous(body);
|
|
942
|
+
spinner?.succeed(import_chalk5.default.green("Proxy created!"));
|
|
943
|
+
} catch (err) {
|
|
944
|
+
spinner?.fail("Failed to create proxy.");
|
|
945
|
+
throw err;
|
|
946
|
+
}
|
|
947
|
+
const version2 = result.api_version || "1.0.0";
|
|
948
|
+
const keys = result.api_keys ?? {};
|
|
949
|
+
const apiKey = result.apiKey ?? keys.prod ?? Object.values(keys)[0];
|
|
950
|
+
const prodEndpoint = (result.endpoints || []).find((e) => e.endsWith("/prod")) || (result.endpoints || [])[0];
|
|
951
|
+
if (opts.json) {
|
|
952
|
+
process.stdout.write(JSON.stringify({
|
|
953
|
+
project_id: result.project_id,
|
|
954
|
+
api_version: version2,
|
|
955
|
+
endpoints: result.endpoints,
|
|
956
|
+
api_key: apiKey,
|
|
957
|
+
api_keys: keys,
|
|
958
|
+
claim_url: result.claim_url,
|
|
959
|
+
anonymous: true
|
|
960
|
+
}) + "\n");
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
console.log();
|
|
964
|
+
if (prodEndpoint) console.log(` ${import_chalk5.default.dim("Proxy URL: ")} ${import_chalk5.default.bold(prodEndpoint)}`);
|
|
965
|
+
if (result.portal) console.log(` ${import_chalk5.default.dim("Dev portal:")} ${import_chalk5.default.bold(result.portal)}`);
|
|
966
|
+
if (apiKey) {
|
|
967
|
+
console.log();
|
|
968
|
+
console.log(` ${import_chalk5.default.dim("API key:")}`);
|
|
969
|
+
console.log(` ${import_chalk5.default.bold.green(apiKey)}`);
|
|
970
|
+
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."));
|
|
971
|
+
}
|
|
972
|
+
if (result.claim_url) {
|
|
973
|
+
console.log();
|
|
974
|
+
console.log(` ${import_chalk5.default.yellow("\u26A0 Anonymous proxy \u2014 claim it to your account within 30 days or it expires:")}`);
|
|
975
|
+
console.log(` ${import_chalk5.default.bold(result.claim_url)}`);
|
|
976
|
+
console.log(import_chalk5.default.dim(" (or run `apiblaze login`, then re-run `apiblaze create` to create it under your account)"));
|
|
977
|
+
}
|
|
978
|
+
console.log();
|
|
979
|
+
}
|
|
829
980
|
|
|
830
|
-
// src/commands/
|
|
981
|
+
// src/commands/claim.ts
|
|
831
982
|
var import_chalk6 = __toESM(require("chalk"));
|
|
832
983
|
init_auth();
|
|
833
984
|
init_api();
|
|
@@ -835,26 +986,112 @@ function fail2(message) {
|
|
|
835
986
|
console.error(import_chalk6.default.red(`Error: ${message}`));
|
|
836
987
|
process.exit(1);
|
|
837
988
|
}
|
|
838
|
-
async function
|
|
989
|
+
async function runClaim(claimCodeArg, opts) {
|
|
839
990
|
const creds = loadCredentials();
|
|
840
991
|
if (!creds) {
|
|
841
|
-
fail2("Not logged in. Run `apiblaze login` first.");
|
|
992
|
+
fail2("Not logged in. Run `apiblaze login` first, then claim.");
|
|
993
|
+
}
|
|
994
|
+
let claimCode = (claimCodeArg ?? "").trim();
|
|
995
|
+
if (!claimCode && process.stdin.isTTY) {
|
|
996
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
997
|
+
const { code } = await inquirer2.prompt([{
|
|
998
|
+
type: "input",
|
|
999
|
+
name: "code",
|
|
1000
|
+
message: "Claim code (from the create output / claim URL):"
|
|
1001
|
+
}]);
|
|
1002
|
+
claimCode = (code ?? "").trim();
|
|
1003
|
+
}
|
|
1004
|
+
if (!claimCode) {
|
|
1005
|
+
fail2("A claim code is required: `apiblaze claim <code>`.");
|
|
842
1006
|
}
|
|
843
1007
|
const teams = await getTeams().catch(() => []);
|
|
844
1008
|
if (teams.length === 0) {
|
|
845
1009
|
fail2("No teams found for your account.");
|
|
846
1010
|
}
|
|
1011
|
+
let teamId;
|
|
1012
|
+
if (opts.team) {
|
|
1013
|
+
const match = teams.find(
|
|
1014
|
+
(t) => t.teamId === opts.team || t.name.toLowerCase() === opts.team.toLowerCase()
|
|
1015
|
+
);
|
|
1016
|
+
if (!match) {
|
|
1017
|
+
fail2(`Team "${opts.team}" not found. Available: ${teams.map((t) => t.name).join(", ")}.`);
|
|
1018
|
+
}
|
|
1019
|
+
teamId = match.teamId;
|
|
1020
|
+
} else if (creds.teamId && teams.some((t) => t.teamId === creds.teamId)) {
|
|
1021
|
+
teamId = creds.teamId;
|
|
1022
|
+
} else if (teams.length === 1) {
|
|
1023
|
+
teamId = teams[0].teamId;
|
|
1024
|
+
} else if (process.stdin.isTTY) {
|
|
1025
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
1026
|
+
const { picked } = await inquirer2.prompt([{
|
|
1027
|
+
type: "list",
|
|
1028
|
+
name: "picked",
|
|
1029
|
+
message: "Claim into which team?",
|
|
1030
|
+
choices: teams.map((t) => ({ name: t.name, value: t.teamId }))
|
|
1031
|
+
}]);
|
|
1032
|
+
teamId = picked;
|
|
1033
|
+
} else {
|
|
1034
|
+
fail2(`Specify a team: \`apiblaze claim ${claimCode} --team <name|id>\`. Available: ${teams.map((t) => t.name).join(", ")}.`);
|
|
1035
|
+
}
|
|
1036
|
+
const teamName = teams.find((t) => t.teamId === teamId)?.name ?? teamId;
|
|
1037
|
+
const result = await claimProxy(claimCode, teamId);
|
|
1038
|
+
if (opts.json) {
|
|
1039
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
console.log(import_chalk6.default.green(`
|
|
1043
|
+
\u2714 Claimed into ${import_chalk6.default.bold(teamName)}.`));
|
|
1044
|
+
if (result.project_id) console.log(` Project: ${import_chalk6.default.bold(result.project_id)}`);
|
|
1045
|
+
if (result.endpoints?.length) {
|
|
1046
|
+
console.log(" Endpoints:");
|
|
1047
|
+
for (const e of result.endpoints) console.log(` ${e}`);
|
|
1048
|
+
}
|
|
1049
|
+
console.log(`
|
|
1050
|
+
Manage it at ${import_chalk6.default.cyan("https://dashboard.apiblaze.com/dashboard")}`);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// src/commands/logout.ts
|
|
1054
|
+
var import_chalk7 = __toESM(require("chalk"));
|
|
1055
|
+
init_auth();
|
|
1056
|
+
async function runLogout() {
|
|
1057
|
+
const creds = loadCredentials();
|
|
1058
|
+
const removed = clearCredentials();
|
|
1059
|
+
if (!removed) {
|
|
1060
|
+
console.log(import_chalk7.default.yellow("You were not logged in."));
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
const who = creds?.githubHandle ?? creds?.email;
|
|
1064
|
+
console.log(import_chalk7.default.green(`\u2714 Logged out${who ? ` (${who})` : ""}.`));
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/commands/team.ts
|
|
1068
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
1069
|
+
init_auth();
|
|
1070
|
+
init_api();
|
|
1071
|
+
function fail3(message) {
|
|
1072
|
+
console.error(import_chalk8.default.red(`Error: ${message}`));
|
|
1073
|
+
process.exit(1);
|
|
1074
|
+
}
|
|
1075
|
+
async function runTeam(arg) {
|
|
1076
|
+
const creds = loadCredentials();
|
|
1077
|
+
if (!creds) {
|
|
1078
|
+
fail3("Not logged in. Run `apiblaze login` first.");
|
|
1079
|
+
}
|
|
1080
|
+
const teams = await getTeams().catch(() => []);
|
|
1081
|
+
if (teams.length === 0) {
|
|
1082
|
+
fail3("No teams found for your account.");
|
|
1083
|
+
}
|
|
847
1084
|
let chosen;
|
|
848
1085
|
if (arg) {
|
|
849
1086
|
chosen = teams.find(
|
|
850
1087
|
(t) => t.teamId === arg || t.name.toLowerCase() === arg.toLowerCase()
|
|
851
1088
|
);
|
|
852
1089
|
if (!chosen) {
|
|
853
|
-
|
|
1090
|
+
fail3(`Team "${arg}" not found. Available: ${teams.map((t) => t.name).join(", ")}.`);
|
|
854
1091
|
}
|
|
855
1092
|
} else if (teams.length === 1) {
|
|
856
1093
|
chosen = teams[0];
|
|
857
|
-
console.log(`${
|
|
1094
|
+
console.log(`${import_chalk8.default.cyan("\u2192")} You only have one team: ${import_chalk8.default.bold(chosen.name)}`);
|
|
858
1095
|
} else if (process.stdin.isTTY) {
|
|
859
1096
|
const { default: inquirer2 } = await import("inquirer");
|
|
860
1097
|
const { picked } = await inquirer2.prompt([{
|
|
@@ -866,16 +1103,16 @@ async function runTeam(arg) {
|
|
|
866
1103
|
}]);
|
|
867
1104
|
chosen = teams.find((t) => t.teamId === picked);
|
|
868
1105
|
} else {
|
|
869
|
-
|
|
1106
|
+
fail3(`Specify a team: \`apiblaze team <name|id>\`. Available: ${teams.map((t) => t.name).join(", ")}.`);
|
|
870
1107
|
}
|
|
871
1108
|
saveCredentials({ ...creds, teamId: chosen.teamId, teamName: chosen.name });
|
|
872
|
-
console.log(
|
|
873
|
-
\u2714 Active team: ${
|
|
1109
|
+
console.log(import_chalk8.default.green(`
|
|
1110
|
+
\u2714 Active team: ${import_chalk8.default.bold(chosen.name)}`));
|
|
874
1111
|
}
|
|
875
1112
|
|
|
876
1113
|
// src/index.ts
|
|
877
1114
|
var program = new import_commander.Command();
|
|
878
|
-
program.name("apiblaze").description("APIblaze dev
|
|
1115
|
+
program.name("apiblaze").description("APIblaze CLI \u2014 create & manage API proxies and run dev tunnels").version(version);
|
|
879
1116
|
program.command("login").description("Authenticate with APIblaze").action(async () => {
|
|
880
1117
|
try {
|
|
881
1118
|
await runLogin();
|
|
@@ -884,7 +1121,7 @@ program.command("login").description("Authenticate with APIblaze").action(async
|
|
|
884
1121
|
process.exit(1);
|
|
885
1122
|
}
|
|
886
1123
|
});
|
|
887
|
-
program.command("create").description("Create a new API proxy").option("--name <name>", "Proxy name (becomes <name>.apiblaze.com)").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("-y, --yes", "Skip the confirmation prompt").option("--json", "Output machine-readable JSON (non-interactive)").action(async (opts) => {
|
|
1124
|
+
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>.apiblaze.com)").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("--tenant <slug>", "Tenant slug (anonymous create; generated if omitted)").option("--product <slug>", "Product slug (anonymous create; defaults to the proxy name)").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) => {
|
|
888
1125
|
try {
|
|
889
1126
|
await runCreate(opts);
|
|
890
1127
|
} catch (err) {
|
|
@@ -892,6 +1129,22 @@ program.command("create").description("Create a new API proxy").option("--name <
|
|
|
892
1129
|
process.exit(1);
|
|
893
1130
|
}
|
|
894
1131
|
});
|
|
1132
|
+
program.command("logout").description("Sign out \u2014 remove stored credentials from this machine").action(async () => {
|
|
1133
|
+
try {
|
|
1134
|
+
await runLogout();
|
|
1135
|
+
} catch (err) {
|
|
1136
|
+
printError(err);
|
|
1137
|
+
process.exit(1);
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
program.command("claim").description("Claim an anonymously-created proxy into one of your teams (requires login)").argument("[code]", "Claim code from `create` output / claim URL (prompted if omitted)").option("--team <id|name>", "Team to claim into (defaults to your active team)").option("--json", "Output machine-readable JSON (non-interactive)").action(async (code, opts) => {
|
|
1141
|
+
try {
|
|
1142
|
+
await runClaim(code, opts);
|
|
1143
|
+
} catch (err) {
|
|
1144
|
+
printError(err);
|
|
1145
|
+
process.exit(1);
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
895
1148
|
program.command("team").description("Switch the active team").argument("[team]", "Team name or id to switch to (omit to choose interactively)").action(async (team) => {
|
|
896
1149
|
try {
|
|
897
1150
|
await runTeam(team);
|
|
@@ -912,7 +1165,7 @@ program.command("dev").description("Start a dev tunnel for your localhost projec
|
|
|
912
1165
|
try {
|
|
913
1166
|
const resolved = parseInt(port ?? opts.port, 10);
|
|
914
1167
|
if (Number.isNaN(resolved)) {
|
|
915
|
-
console.error(
|
|
1168
|
+
console.error(import_chalk9.default.red(`Invalid port: ${port ?? opts.port}`));
|
|
916
1169
|
process.exit(1);
|
|
917
1170
|
}
|
|
918
1171
|
await runDev({ port: resolved });
|
|
@@ -921,15 +1174,41 @@ program.command("dev").description("Start a dev tunnel for your localhost projec
|
|
|
921
1174
|
process.exit(1);
|
|
922
1175
|
}
|
|
923
1176
|
});
|
|
1177
|
+
program.addHelpText(
|
|
1178
|
+
"after",
|
|
1179
|
+
`
|
|
1180
|
+
Examples:
|
|
1181
|
+
# No account needed \u2014 create an anonymous proxy, get a claim URL:
|
|
1182
|
+
$ npx apiblaze create --target https://api.example.com
|
|
1183
|
+
|
|
1184
|
+
# Non-interactive (CI / scripts):
|
|
1185
|
+
$ npx apiblaze create --target https://api.example.com --name myapi --json
|
|
1186
|
+
|
|
1187
|
+
# Claim that anonymous proxy into your team (after signing in):
|
|
1188
|
+
$ npx apiblaze login
|
|
1189
|
+
$ npx apiblaze claim G7QN-62JB-VN3D-RQNR-F6EZ
|
|
1190
|
+
$ npx apiblaze claim G7QN-62JB-VN3D-RQNR-F6EZ --team my-team
|
|
1191
|
+
|
|
1192
|
+
# Sign in, then create under your team:
|
|
1193
|
+
$ npx apiblaze login
|
|
1194
|
+
$ npx apiblaze create --name myapi --target https://api.example.com --auth api_key
|
|
1195
|
+
|
|
1196
|
+
# Manage:
|
|
1197
|
+
$ npx apiblaze projects
|
|
1198
|
+
$ npx apiblaze team
|
|
1199
|
+
$ npx apiblaze dev 3000
|
|
1200
|
+
$ npx apiblaze logout
|
|
1201
|
+
`
|
|
1202
|
+
);
|
|
924
1203
|
function printError(err) {
|
|
925
1204
|
if (err instanceof ApiError) {
|
|
926
|
-
console.error(
|
|
1205
|
+
console.error(import_chalk9.default.red(`
|
|
927
1206
|
API error (${err.status}): ${err.message}`));
|
|
928
1207
|
} else if (err instanceof Error) {
|
|
929
|
-
console.error(
|
|
1208
|
+
console.error(import_chalk9.default.red(`
|
|
930
1209
|
Error: ${err.message}`));
|
|
931
1210
|
} else {
|
|
932
|
-
console.error(
|
|
1211
|
+
console.error(import_chalk9.default.red("\nUnknown error"));
|
|
933
1212
|
}
|
|
934
1213
|
}
|
|
935
1214
|
program.parse(process.argv);
|