apiblaze 0.1.20 → 0.1.22
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 +64 -12
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -36,9 +36,10 @@ var init_types = __esm({
|
|
|
36
36
|
"src/types.ts"() {
|
|
37
37
|
"use strict";
|
|
38
38
|
ApiError = class extends Error {
|
|
39
|
-
constructor(status, message) {
|
|
39
|
+
constructor(status, message, body) {
|
|
40
40
|
super(message);
|
|
41
41
|
this.status = status;
|
|
42
|
+
this.body = body;
|
|
42
43
|
this.name = "ApiError";
|
|
43
44
|
}
|
|
44
45
|
};
|
|
@@ -132,12 +133,14 @@ async function apiFetch(path2, options = {}) {
|
|
|
132
133
|
});
|
|
133
134
|
if (!res.ok) {
|
|
134
135
|
let message = res.statusText;
|
|
136
|
+
let parsed;
|
|
135
137
|
try {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
parsed = await res.json();
|
|
139
|
+
const b = parsed;
|
|
140
|
+
message = b.message ?? b.error ?? message;
|
|
138
141
|
} catch {
|
|
139
142
|
}
|
|
140
|
-
throw new ApiError(res.status, message);
|
|
143
|
+
throw new ApiError(res.status, message, parsed);
|
|
141
144
|
}
|
|
142
145
|
if (res.status === 204) {
|
|
143
146
|
return void 0;
|
|
@@ -158,9 +161,10 @@ async function getLocalhostTargets(teamId) {
|
|
|
158
161
|
async function getProjects(teamId) {
|
|
159
162
|
return apiFetch(`/api/cli/projects?team_id=${encodeURIComponent(teamId)}`);
|
|
160
163
|
}
|
|
161
|
-
async function checkProxyName(name, teamId) {
|
|
164
|
+
async function checkProxyName(name, teamId, apiVersion) {
|
|
162
165
|
const q = teamId ? `&team_id=${encodeURIComponent(teamId)}` : "";
|
|
163
|
-
|
|
166
|
+
const v = apiVersion ? `&api_version=${encodeURIComponent(apiVersion)}` : "";
|
|
167
|
+
return apiFetch(`/api/cli/check-name?name=${encodeURIComponent(name)}${q}${v}`);
|
|
164
168
|
}
|
|
165
169
|
async function createProxy(payload) {
|
|
166
170
|
return apiFetch("/api/cli/create-proxy", {
|
|
@@ -202,7 +206,7 @@ var import_commander = require("commander");
|
|
|
202
206
|
var import_chalk10 = __toESM(require("chalk"));
|
|
203
207
|
|
|
204
208
|
// package.json
|
|
205
|
-
var version = "0.1.
|
|
209
|
+
var version = "0.1.22";
|
|
206
210
|
|
|
207
211
|
// src/index.ts
|
|
208
212
|
init_types();
|
|
@@ -715,6 +719,16 @@ function fail(message) {
|
|
|
715
719
|
console.error(import_chalk5.default.red(`Error: ${message}`));
|
|
716
720
|
process.exit(1);
|
|
717
721
|
}
|
|
722
|
+
function printCurlExample(url, apiKey) {
|
|
723
|
+
console.log();
|
|
724
|
+
console.log(` ${import_chalk5.default.dim("Try it with curl:")}`);
|
|
725
|
+
if (apiKey) {
|
|
726
|
+
console.log(` ${import_chalk5.default.cyan(`curl ${url} \\`)}`);
|
|
727
|
+
console.log(` ${import_chalk5.default.cyan(` -H "X-API-Key: ${apiKey}"`)}`);
|
|
728
|
+
} else {
|
|
729
|
+
console.log(` ${import_chalk5.default.cyan(`curl ${url}`)}`);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
718
732
|
var VALID_AUTH = ["api_key", "none", "oauth"];
|
|
719
733
|
async function runCreate(opts = {}) {
|
|
720
734
|
const creds = loadCredentials();
|
|
@@ -747,7 +761,7 @@ async function runCreate(opts = {}) {
|
|
|
747
761
|
if (opts.name !== void 0) {
|
|
748
762
|
name = normalizeName(opts.name);
|
|
749
763
|
if (name.length < 3) fail("Proxy name must be at least 3 characters (letters and digits only).");
|
|
750
|
-
const check = await checkProxyName(name, teamId).catch(() => null);
|
|
764
|
+
const check = await checkProxyName(name, teamId, opts.apiversion).catch(() => null);
|
|
751
765
|
if (check && (!check.canUseProjectName || !check.canUseApiVersion)) {
|
|
752
766
|
fail(`Proxy name "${name}" is not available${check.message ? ` \u2014 ${check.message}` : ""}.`);
|
|
753
767
|
}
|
|
@@ -767,7 +781,7 @@ async function runCreate(opts = {}) {
|
|
|
767
781
|
}
|
|
768
782
|
const spinner2 = (0, import_ora4.default)("Checking availability...").start();
|
|
769
783
|
try {
|
|
770
|
-
const check = await checkProxyName(name, teamId);
|
|
784
|
+
const check = await checkProxyName(name, teamId, opts.apiversion);
|
|
771
785
|
spinner2.stop();
|
|
772
786
|
if (!check.canUseProjectName || !check.canUseApiVersion) {
|
|
773
787
|
console.log(import_chalk5.default.yellow(` "${name}" is not available${check.message ? ` \u2014 ${check.message}` : ""}. Try another.
|
|
@@ -824,11 +838,46 @@ async function runCreate(opts = {}) {
|
|
|
824
838
|
const spinner = !opts.json ? (0, import_ora4.default)("Creating proxy (tenant, keys, dev portal)...").start() : null;
|
|
825
839
|
let result;
|
|
826
840
|
try {
|
|
827
|
-
result = await createProxy({ name, target_url: targetUrl, auth_type: auth, team_id: teamId });
|
|
841
|
+
result = await createProxy({ name, target_url: targetUrl, auth_type: auth, team_id: teamId, ...opts.apiversion ? { api_version: opts.apiversion } : {} });
|
|
828
842
|
spinner?.succeed(import_chalk5.default.green("Proxy created!"));
|
|
829
843
|
} catch (err) {
|
|
844
|
+
const e = err;
|
|
845
|
+
const ownedByYou = e?.status === 409 && e?.body?.reason === "slug_owned_by_your_other_team" && !opts.team;
|
|
830
846
|
spinner?.fail("Failed to create proxy.");
|
|
831
|
-
|
|
847
|
+
if (ownedByYou) {
|
|
848
|
+
const ownerId = e.body.owning_team_id;
|
|
849
|
+
const ownerName = e.body.owning_team_name || ownerId;
|
|
850
|
+
if (!opts.json) console.log(import_chalk5.default.yellow(`
|
|
851
|
+
You already own "${e.body.product_slug}" under your team "${ownerName}".`));
|
|
852
|
+
let doSwitch = false;
|
|
853
|
+
if (interactive && !opts.yes) {
|
|
854
|
+
const { default: inquirer2 } = await import("inquirer");
|
|
855
|
+
const { ok } = await inquirer2.prompt([{
|
|
856
|
+
type: "confirm",
|
|
857
|
+
name: "ok",
|
|
858
|
+
message: `Switch to team "${ownerName}" and create "${name}" there?`,
|
|
859
|
+
default: true
|
|
860
|
+
}]);
|
|
861
|
+
doSwitch = ok;
|
|
862
|
+
}
|
|
863
|
+
if (!doSwitch) {
|
|
864
|
+
if (!opts.json) console.log(import_chalk5.default.dim(` Run \`apiblaze team ${ownerId}\` to switch, then retry \u2014 or pick another --name.`));
|
|
865
|
+
throw err;
|
|
866
|
+
}
|
|
867
|
+
const creds2 = loadCredentials();
|
|
868
|
+
if (creds2) saveCredentials({ ...creds2, teamId: ownerId, teamName: ownerName });
|
|
869
|
+
teamId = ownerId;
|
|
870
|
+
const spinner2 = !opts.json ? (0, import_ora4.default)(`Creating proxy under "${ownerName}"...`).start() : null;
|
|
871
|
+
try {
|
|
872
|
+
result = await createProxy({ name, target_url: targetUrl, auth_type: auth, team_id: ownerId, ...opts.apiversion ? { api_version: opts.apiversion } : {} });
|
|
873
|
+
spinner2?.succeed(import_chalk5.default.green(`Proxy created \u2014 active team switched to "${ownerName}".`));
|
|
874
|
+
} catch (err2) {
|
|
875
|
+
spinner2?.fail("Failed to create proxy after switching team.");
|
|
876
|
+
throw err2;
|
|
877
|
+
}
|
|
878
|
+
} else {
|
|
879
|
+
throw err;
|
|
880
|
+
}
|
|
832
881
|
}
|
|
833
882
|
const version2 = result.api_version || "1.0.0";
|
|
834
883
|
const keys = result.api_keys ?? {};
|
|
@@ -860,6 +909,7 @@ async function runCreate(opts = {}) {
|
|
|
860
909
|
console.log(import_chalk5.default.dim(` (Separate keys were also created for: ${otherEnvs.join(", ")}.)`));
|
|
861
910
|
}
|
|
862
911
|
}
|
|
912
|
+
printCurlExample(proxyUrl, auth === "none" ? void 0 : adminKey);
|
|
863
913
|
console.log();
|
|
864
914
|
}
|
|
865
915
|
async function runAnonymousCreate(opts) {
|
|
@@ -934,6 +984,7 @@ async function runAnonymousCreate(opts) {
|
|
|
934
984
|
if (opts.tenant) body.tenant = normalizeName(opts.tenant);
|
|
935
985
|
if (opts.product) body.product_slug = normalizeName(opts.product);
|
|
936
986
|
if (opts.displayName) body.display_name = opts.displayName;
|
|
987
|
+
if (opts.apiversion) body.api_version = opts.apiversion;
|
|
937
988
|
if (opts.auth && opts.auth !== "api_key") body.auth_type = opts.auth;
|
|
938
989
|
const spinner = !opts.json ? (0, import_ora4.default)("Creating proxy...").start() : null;
|
|
939
990
|
let result;
|
|
@@ -969,6 +1020,7 @@ async function runAnonymousCreate(opts) {
|
|
|
969
1020
|
console.log(` ${import_chalk5.default.bold.green(apiKey)}`);
|
|
970
1021
|
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
1022
|
}
|
|
1023
|
+
if (prodEndpoint) printCurlExample(prodEndpoint, apiKey);
|
|
972
1024
|
if (result.claim_url) {
|
|
973
1025
|
console.log();
|
|
974
1026
|
console.log(` ${import_chalk5.default.yellow("\u26A0 Anonymous proxy \u2014 claim it to your account within 30 days or it expires:")}`);
|
|
@@ -1159,7 +1211,7 @@ program.command("login").description("Authenticate with APIblaze").action(async
|
|
|
1159
1211
|
process.exit(1);
|
|
1160
1212
|
}
|
|
1161
1213
|
});
|
|
1162
|
-
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) => {
|
|
1214
|
+
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("--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("--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) => {
|
|
1163
1215
|
try {
|
|
1164
1216
|
await runCreate(opts);
|
|
1165
1217
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apiblaze",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Dev tunnel CLI for APIblaze — route localhost projects through your APIblaze endpoints",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apiblaze",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"build": "tsup",
|
|
27
27
|
"build:watch": "tsup --watch",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
|
-
"prepublishOnly": "npm run build && npm run typecheck"
|
|
29
|
+
"prepublishOnly": "npm run build && npm run typecheck",
|
|
30
|
+
"release": "bash scripts/release.sh"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"chalk": "^4.1.2",
|