apiblaze 0.1.16 → 0.1.18
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 +173 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -86,12 +86,30 @@ var api_exports = {};
|
|
|
86
86
|
__export(api_exports, {
|
|
87
87
|
checkProxyName: () => checkProxyName,
|
|
88
88
|
createProxy: () => createProxy,
|
|
89
|
+
createProxyAnonymous: () => createProxyAnonymous,
|
|
89
90
|
deleteDevTunnel: () => deleteDevTunnel,
|
|
90
91
|
getLocalhostTargets: () => getLocalhostTargets,
|
|
91
92
|
getProjects: () => getProjects,
|
|
92
93
|
getTeams: () => getTeams,
|
|
93
94
|
putDevTunnel: () => putDevTunnel
|
|
94
95
|
});
|
|
96
|
+
async function createProxyAnonymous(body) {
|
|
97
|
+
const res = await fetch(`${PUBLIC_API_BASE}/proxy`, {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "Content-Type": "application/json" },
|
|
100
|
+
body: JSON.stringify(body)
|
|
101
|
+
});
|
|
102
|
+
if (!res.ok) {
|
|
103
|
+
let message = res.statusText;
|
|
104
|
+
try {
|
|
105
|
+
const b = await res.json();
|
|
106
|
+
message = b.details ?? b.error ?? message;
|
|
107
|
+
} catch {
|
|
108
|
+
}
|
|
109
|
+
throw new ApiError(res.status, message);
|
|
110
|
+
}
|
|
111
|
+
return res.json();
|
|
112
|
+
}
|
|
95
113
|
async function apiFetch(path2, options = {}) {
|
|
96
114
|
const token = getAccessToken();
|
|
97
115
|
const url = `${DASHBOARD_BASE}${path2}`;
|
|
@@ -153,13 +171,14 @@ async function deleteDevTunnel(restore) {
|
|
|
153
171
|
body: JSON.stringify({ restore })
|
|
154
172
|
});
|
|
155
173
|
}
|
|
156
|
-
var DASHBOARD_BASE;
|
|
174
|
+
var DASHBOARD_BASE, PUBLIC_API_BASE;
|
|
157
175
|
var init_api = __esm({
|
|
158
176
|
"src/lib/api.ts"() {
|
|
159
177
|
"use strict";
|
|
160
178
|
init_auth();
|
|
161
179
|
init_types();
|
|
162
180
|
DASHBOARD_BASE = "https://dashboard.apiblaze.com";
|
|
181
|
+
PUBLIC_API_BASE = "https://api.apiblaze.com";
|
|
163
182
|
}
|
|
164
183
|
});
|
|
165
184
|
|
|
@@ -168,7 +187,7 @@ var import_commander = require("commander");
|
|
|
168
187
|
var import_chalk7 = __toESM(require("chalk"));
|
|
169
188
|
|
|
170
189
|
// package.json
|
|
171
|
-
var version = "0.1.
|
|
190
|
+
var version = "0.1.18";
|
|
172
191
|
|
|
173
192
|
// src/index.ts
|
|
174
193
|
init_types();
|
|
@@ -521,21 +540,21 @@ async function runDev(options) {
|
|
|
521
540
|
}
|
|
522
541
|
selectedTargets = targets;
|
|
523
542
|
} else {
|
|
543
|
+
const ALL = "__all__";
|
|
524
544
|
const { chosen } = await import_inquirer.default.prompt([{
|
|
525
|
-
type: "
|
|
545
|
+
type: "list",
|
|
526
546
|
name: "chosen",
|
|
527
|
-
message: `Found ${targets.length} projects with an internal target \u2014 pick
|
|
528
|
-
choices:
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
547
|
+
message: `Found ${targets.length} projects with an internal target \u2014 pick one to tunnel:`,
|
|
548
|
+
choices: [
|
|
549
|
+
...targets.map((t) => ({
|
|
550
|
+
name: `${import_chalk3.default.bold(t.projectName)} (${t.tenantName}) \u2014 ${t.target}`,
|
|
551
|
+
value: t
|
|
552
|
+
})),
|
|
553
|
+
new import_inquirer.default.Separator(),
|
|
554
|
+
{ name: `Tunnel all ${targets.length}`, value: ALL }
|
|
555
|
+
]
|
|
533
556
|
}]);
|
|
534
|
-
|
|
535
|
-
console.log("No projects selected. Aborted.");
|
|
536
|
-
process.exit(0);
|
|
537
|
-
}
|
|
538
|
-
selectedTargets = chosen;
|
|
557
|
+
selectedTargets = chosen === ALL ? targets : [chosen];
|
|
539
558
|
}
|
|
540
559
|
console.log(
|
|
541
560
|
import_chalk3.default.green(`
|
|
@@ -649,6 +668,7 @@ ${projects.length} project${projects.length === 1 ? "" : "s"}`));
|
|
|
649
668
|
}
|
|
650
669
|
|
|
651
670
|
// src/commands/create.ts
|
|
671
|
+
var import_fs = __toESM(require("fs"));
|
|
652
672
|
var import_chalk5 = __toESM(require("chalk"));
|
|
653
673
|
var import_ora4 = __toESM(require("ora"));
|
|
654
674
|
init_auth();
|
|
@@ -684,7 +704,8 @@ var VALID_AUTH = ["api_key", "none", "oauth"];
|
|
|
684
704
|
async function runCreate(opts = {}) {
|
|
685
705
|
const creds = loadCredentials();
|
|
686
706
|
if (!creds) {
|
|
687
|
-
|
|
707
|
+
await runAnonymousCreate(opts);
|
|
708
|
+
return;
|
|
688
709
|
}
|
|
689
710
|
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
690
711
|
const auth = (opts.auth ?? "api_key").toLowerCase();
|
|
@@ -826,6 +847,121 @@ async function runCreate(opts = {}) {
|
|
|
826
847
|
}
|
|
827
848
|
console.log();
|
|
828
849
|
}
|
|
850
|
+
async function runAnonymousCreate(opts) {
|
|
851
|
+
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
852
|
+
if (!opts.json) {
|
|
853
|
+
console.log(import_chalk5.default.bold("\nCreate an API proxy"));
|
|
854
|
+
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"));
|
|
855
|
+
}
|
|
856
|
+
let body = {};
|
|
857
|
+
if (opts.config) {
|
|
858
|
+
let raw = "";
|
|
859
|
+
try {
|
|
860
|
+
raw = import_fs.default.readFileSync(opts.config, "utf8");
|
|
861
|
+
} catch {
|
|
862
|
+
fail(`Cannot read --config file: ${opts.config}`);
|
|
863
|
+
}
|
|
864
|
+
let parsed;
|
|
865
|
+
try {
|
|
866
|
+
parsed = JSON.parse(raw);
|
|
867
|
+
} catch {
|
|
868
|
+
fail(`--config is not valid JSON: ${opts.config}`);
|
|
869
|
+
}
|
|
870
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) fail("--config must be a JSON object.");
|
|
871
|
+
body = parsed;
|
|
872
|
+
}
|
|
873
|
+
let name = opts.name !== void 0 ? normalizeName(opts.name) : typeof body.name === "string" ? body.name : void 0;
|
|
874
|
+
if (opts.name !== void 0 && name.length < 3) {
|
|
875
|
+
fail("Proxy name must be at least 3 characters (letters and digits only).");
|
|
876
|
+
}
|
|
877
|
+
if (opts.target && !isHttpUrl(opts.target)) fail("--target must be a valid http(s) URL.");
|
|
878
|
+
let target = opts.target?.trim() || (typeof body.target === "string" ? body.target : "") || (typeof body.target_url === "string" ? body.target_url : "");
|
|
879
|
+
const hasOtherSource = !!(body.openapi || body.github);
|
|
880
|
+
if (!target && !hasOtherSource) {
|
|
881
|
+
if (interactive) {
|
|
882
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
883
|
+
if (name === void 0) {
|
|
884
|
+
const { rawName } = await inquirer2.prompt([{
|
|
885
|
+
type: "input",
|
|
886
|
+
name: "rawName",
|
|
887
|
+
message: "Proxy name (leave blank to auto-generate):",
|
|
888
|
+
transformer: (v) => normalizeName(v)
|
|
889
|
+
}]);
|
|
890
|
+
const n = normalizeName(rawName);
|
|
891
|
+
name = n.length >= 3 ? n : void 0;
|
|
892
|
+
}
|
|
893
|
+
for (; ; ) {
|
|
894
|
+
const { url } = await inquirer2.prompt([{
|
|
895
|
+
type: "input",
|
|
896
|
+
name: "url",
|
|
897
|
+
message: "Target URL to forward requests to (e.g. https://httpbin.org):"
|
|
898
|
+
}]);
|
|
899
|
+
if (!isHttpUrl(url)) {
|
|
900
|
+
console.log(import_chalk5.default.yellow(" Enter a valid http(s) URL.\n"));
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
target = url.trim();
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
} else {
|
|
907
|
+
fail("A source is required: pass --target, or target/openapi/github in --config.");
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (target) {
|
|
911
|
+
body.target = target;
|
|
912
|
+
body.target_url = target;
|
|
913
|
+
}
|
|
914
|
+
if (name) {
|
|
915
|
+
body.name = name;
|
|
916
|
+
body.subdomain = name;
|
|
917
|
+
}
|
|
918
|
+
if (opts.subdomain) body.subdomain = normalizeName(opts.subdomain);
|
|
919
|
+
if (opts.tenant) body.tenant = normalizeName(opts.tenant);
|
|
920
|
+
if (opts.product) body.product_slug = normalizeName(opts.product);
|
|
921
|
+
if (opts.displayName) body.display_name = opts.displayName;
|
|
922
|
+
if (opts.auth && opts.auth !== "api_key") body.auth_type = opts.auth;
|
|
923
|
+
const spinner = !opts.json ? (0, import_ora4.default)("Creating proxy...").start() : null;
|
|
924
|
+
let result;
|
|
925
|
+
try {
|
|
926
|
+
result = await createProxyAnonymous(body);
|
|
927
|
+
spinner?.succeed(import_chalk5.default.green("Proxy created!"));
|
|
928
|
+
} catch (err) {
|
|
929
|
+
spinner?.fail("Failed to create proxy.");
|
|
930
|
+
throw err;
|
|
931
|
+
}
|
|
932
|
+
const version2 = result.api_version || "1.0.0";
|
|
933
|
+
const keys = result.api_keys ?? {};
|
|
934
|
+
const apiKey = result.apiKey ?? keys.prod ?? Object.values(keys)[0];
|
|
935
|
+
const prodEndpoint = (result.endpoints || []).find((e) => e.endsWith("/prod")) || (result.endpoints || [])[0];
|
|
936
|
+
if (opts.json) {
|
|
937
|
+
process.stdout.write(JSON.stringify({
|
|
938
|
+
project_id: result.project_id,
|
|
939
|
+
api_version: version2,
|
|
940
|
+
endpoints: result.endpoints,
|
|
941
|
+
api_key: apiKey,
|
|
942
|
+
api_keys: keys,
|
|
943
|
+
claim_url: result.claim_url,
|
|
944
|
+
anonymous: true
|
|
945
|
+
}) + "\n");
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
console.log();
|
|
949
|
+
if (prodEndpoint) console.log(` ${import_chalk5.default.dim("Proxy URL: ")} ${import_chalk5.default.bold(prodEndpoint)}`);
|
|
950
|
+
if (result.portal) console.log(` ${import_chalk5.default.dim("Dev portal:")} ${import_chalk5.default.bold(result.portal)}`);
|
|
951
|
+
if (apiKey) {
|
|
952
|
+
console.log();
|
|
953
|
+
console.log(` ${import_chalk5.default.dim("API key:")}`);
|
|
954
|
+
console.log(` ${import_chalk5.default.bold.green(apiKey)}`);
|
|
955
|
+
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."));
|
|
956
|
+
}
|
|
957
|
+
if (result.claim_url) {
|
|
958
|
+
console.log();
|
|
959
|
+
console.log(` ${import_chalk5.default.yellow("\u26A0 Anonymous proxy \u2014 claim it to your account within 30 days or it expires:")}`);
|
|
960
|
+
console.log(` ${import_chalk5.default.bold(result.claim_url)}`);
|
|
961
|
+
console.log(import_chalk5.default.dim(" (or run `apiblaze login`, then re-run `apiblaze create` to create it under your account)"));
|
|
962
|
+
}
|
|
963
|
+
console.log();
|
|
964
|
+
}
|
|
829
965
|
|
|
830
966
|
// src/commands/team.ts
|
|
831
967
|
var import_chalk6 = __toESM(require("chalk"));
|
|
@@ -875,7 +1011,7 @@ async function runTeam(arg) {
|
|
|
875
1011
|
|
|
876
1012
|
// src/index.ts
|
|
877
1013
|
var program = new import_commander.Command();
|
|
878
|
-
program.name("apiblaze").description("APIblaze dev
|
|
1014
|
+
program.name("apiblaze").description("APIblaze CLI \u2014 create & manage API proxies and run dev tunnels").version(version);
|
|
879
1015
|
program.command("login").description("Authenticate with APIblaze").action(async () => {
|
|
880
1016
|
try {
|
|
881
1017
|
await runLogin();
|
|
@@ -884,7 +1020,7 @@ program.command("login").description("Authenticate with APIblaze").action(async
|
|
|
884
1020
|
process.exit(1);
|
|
885
1021
|
}
|
|
886
1022
|
});
|
|
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) => {
|
|
1023
|
+
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
1024
|
try {
|
|
889
1025
|
await runCreate(opts);
|
|
890
1026
|
} catch (err) {
|
|
@@ -921,6 +1057,26 @@ program.command("dev").description("Start a dev tunnel for your localhost projec
|
|
|
921
1057
|
process.exit(1);
|
|
922
1058
|
}
|
|
923
1059
|
});
|
|
1060
|
+
program.addHelpText(
|
|
1061
|
+
"after",
|
|
1062
|
+
`
|
|
1063
|
+
Examples:
|
|
1064
|
+
# No account needed \u2014 create an anonymous proxy, get a claim URL:
|
|
1065
|
+
$ npx apiblaze create --target https://api.example.com
|
|
1066
|
+
|
|
1067
|
+
# Non-interactive (CI / scripts):
|
|
1068
|
+
$ npx apiblaze create --target https://api.example.com --name myapi --json
|
|
1069
|
+
|
|
1070
|
+
# Sign in, then create under your team:
|
|
1071
|
+
$ npx apiblaze login
|
|
1072
|
+
$ npx apiblaze create --name myapi --target https://api.example.com --auth api_key
|
|
1073
|
+
|
|
1074
|
+
# Manage:
|
|
1075
|
+
$ npx apiblaze projects
|
|
1076
|
+
$ npx apiblaze team
|
|
1077
|
+
$ npx apiblaze dev 3000
|
|
1078
|
+
`
|
|
1079
|
+
);
|
|
924
1080
|
function printError(err) {
|
|
925
1081
|
if (err instanceof ApiError) {
|
|
926
1082
|
console.error(import_chalk7.default.red(`
|