apiblaze 0.20.13 → 0.20.14
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 +40 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1024,7 +1024,7 @@ var import_commander = require("commander");
|
|
|
1024
1024
|
var import_chalk53 = __toESM(require("chalk"));
|
|
1025
1025
|
|
|
1026
1026
|
// package.json
|
|
1027
|
-
var version = "0.20.
|
|
1027
|
+
var version = "0.20.14";
|
|
1028
1028
|
|
|
1029
1029
|
// src/index.ts
|
|
1030
1030
|
init_types();
|
|
@@ -2251,7 +2251,7 @@ async function runCreate(opts = {}) {
|
|
|
2251
2251
|
const { classifyTargetInput: classifyTargetInput2 } = await Promise.resolve().then(() => (init_spec_or_target(), spec_or_target_exports));
|
|
2252
2252
|
const c = await classifyTargetInput2(opts.target, fail);
|
|
2253
2253
|
if (c.kind === "spec") {
|
|
2254
|
-
console.log(import_chalk11.default.dim(` --target is an OpenAPI document (${c.source}) \u2014 creating FROM the spec.`));
|
|
2254
|
+
if (!opts.json) console.log(import_chalk11.default.dim(` --target is an OpenAPI document (${c.source}) \u2014 creating FROM the spec.`));
|
|
2255
2255
|
opts.openapi = opts.target;
|
|
2256
2256
|
opts.target = void 0;
|
|
2257
2257
|
}
|
|
@@ -2261,7 +2261,7 @@ async function runCreate(opts = {}) {
|
|
|
2261
2261
|
await runAnonymousCreate(opts);
|
|
2262
2262
|
return;
|
|
2263
2263
|
}
|
|
2264
|
-
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
2264
|
+
const interactive = !!process.stdin.isTTY && !opts.json && !opts.auto;
|
|
2265
2265
|
if (opts.apikey && opts.oauth !== void 0 && opts.oauth !== false) fail("Pass either --apikey or --oauth, not both.");
|
|
2266
2266
|
const oauthPlan = parseOauthFlag(opts.oauth);
|
|
2267
2267
|
const auth = (oauthPlan ? oauthPlan.auth : opts.apikey ? "api_key" : opts.auth ?? "api_key").toLowerCase();
|
|
@@ -2323,8 +2323,12 @@ async function runCreate(opts = {}) {
|
|
|
2323
2323
|
`);
|
|
2324
2324
|
break;
|
|
2325
2325
|
}
|
|
2326
|
+
} else if (opts.auto) {
|
|
2327
|
+
name = await pickGeneratedName(opts, teamId);
|
|
2328
|
+
if (!opts.json) console.log(`${import_chalk11.default.cyan("\u2192")} Your API will live at ${import_chalk11.default.bold(`https://${name}.abz.run`)}
|
|
2329
|
+
`);
|
|
2326
2330
|
} else {
|
|
2327
|
-
fail("--name is required in non-interactive mode.");
|
|
2331
|
+
fail("--name is required in non-interactive mode.", "Or pass --auto to have one generated for you.");
|
|
2328
2332
|
}
|
|
2329
2333
|
let openapiContent = null;
|
|
2330
2334
|
if (opts.openapi !== void 0) {
|
|
@@ -2354,7 +2358,7 @@ async function runCreate(opts = {}) {
|
|
|
2354
2358
|
} else {
|
|
2355
2359
|
fail("--target is required in non-interactive mode (a server base URL, a local OpenAPI file, or a remote OpenAPI URL).");
|
|
2356
2360
|
}
|
|
2357
|
-
if (interactive && !opts.yes) {
|
|
2361
|
+
if (interactive && !opts.yes && !opts.auto) {
|
|
2358
2362
|
const { default: inquirer3 } = await import("inquirer");
|
|
2359
2363
|
console.log(`${import_chalk11.default.cyan("\u2192")} Auth: ${import_chalk11.default.bold(auth)}${auth === "api_key" ? " \u2014 consumers send an X-API-Key header" : oauthPlan ? ` \u2014 ${oauthPlan.summary}` : ""}`);
|
|
2360
2364
|
const { ok } = await inquirer3.prompt([{
|
|
@@ -2370,7 +2374,7 @@ async function runCreate(opts = {}) {
|
|
|
2370
2374
|
}
|
|
2371
2375
|
const chosenTenant = await chooseTenantForCreate(teamId, name, {
|
|
2372
2376
|
tenant: opts.tenant,
|
|
2373
|
-
yes: opts.yes,
|
|
2377
|
+
yes: opts.yes || opts.auto,
|
|
2374
2378
|
json: opts.json
|
|
2375
2379
|
});
|
|
2376
2380
|
const spinner = !opts.json ? (0, import_ora5.default)("Creating proxy (tenant, keys, dev portal)...").start() : null;
|
|
@@ -2432,8 +2436,29 @@ async function applyCreateToggles(name, opts) {
|
|
|
2432
2436
|
if (opts.identified) await runIdentifiedToggle2(name, "require", toggleOpts);
|
|
2433
2437
|
if (opts.iam) await runIamToggle2(name, "on", toggleOpts);
|
|
2434
2438
|
}
|
|
2439
|
+
function deriveNameFrom(source) {
|
|
2440
|
+
if (!source) return null;
|
|
2441
|
+
try {
|
|
2442
|
+
const host = new URL(source).hostname;
|
|
2443
|
+
let base2 = normalizeName(host.split(".")[0]);
|
|
2444
|
+
if (base2.length < 3) base2 = normalizeName(host);
|
|
2445
|
+
if (base2.length < 3) return null;
|
|
2446
|
+
return `${base2}${Math.random().toString(36).slice(2, 6)}`;
|
|
2447
|
+
} catch {
|
|
2448
|
+
return null;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
async function pickGeneratedName(opts, teamId) {
|
|
2452
|
+
const source = opts.target ?? opts.openapi;
|
|
2453
|
+
for (let attempt = 0; attempt < 4; attempt++) {
|
|
2454
|
+
const candidate = (attempt === 0 ? deriveNameFrom(source) : null) ?? randomProxyName();
|
|
2455
|
+
const check = await checkProxyName(candidate, teamId, opts.apiversion).catch(() => null);
|
|
2456
|
+
if (!check || check.canUseProjectName && check.canUseApiVersion) return candidate;
|
|
2457
|
+
}
|
|
2458
|
+
fail("Could not find a free generated proxy name. Pass --name explicitly.");
|
|
2459
|
+
}
|
|
2435
2460
|
async function runAnonymousCreate(opts) {
|
|
2436
|
-
const interactive = !!process.stdin.isTTY && !opts.json;
|
|
2461
|
+
const interactive = !!process.stdin.isTTY && !opts.json && !opts.auto;
|
|
2437
2462
|
if (!opts.json) {
|
|
2438
2463
|
console.log(import_chalk11.default.bold("\nCreate an API proxy"));
|
|
2439
2464
|
console.log(import_chalk11.default.dim("Not logged in \u2014 creating an anonymous proxy. You can claim it to your account within 30 days.\n"));
|
|
@@ -2495,6 +2520,10 @@ async function runAnonymousCreate(opts) {
|
|
|
2495
2520
|
fail("A source is required: pass --target, or target/openapi/github in --config.");
|
|
2496
2521
|
}
|
|
2497
2522
|
}
|
|
2523
|
+
if (name === void 0 && opts.auto) {
|
|
2524
|
+
const nameSource = target || (typeof opts.openapi === "string" ? opts.openapi : void 0);
|
|
2525
|
+
name = deriveNameFrom(nameSource) ?? randomProxyName();
|
|
2526
|
+
}
|
|
2498
2527
|
if (target) {
|
|
2499
2528
|
body.target = target;
|
|
2500
2529
|
body.target_url = target;
|
|
@@ -11264,7 +11293,7 @@ program.command("login").description("Authenticate with APIblaze").option("--tea
|
|
|
11264
11293
|
process.exit(1);
|
|
11265
11294
|
}
|
|
11266
11295
|
});
|
|
11267
|
-
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>.abz.run)").option("--target <url|file>", "What to proxy \u2014 pass ANY of: a target server base URL (https://httpbin.org), a local OpenAPI file (./openapi.yaml), or a remote OpenAPI URL (https://acme.com/openapi.yaml). Spec inputs are detected automatically; routes, API version and environments then come from the spec").addOption(new import_commander.Option("--openapi <file|url>", "Deprecated alias \u2014 --target now detects spec files/URLs itself").hideHelp()).addOption(new import_commander.Option("--openapispec <file|url>", "Deprecated alias for --openapi").hideHelp()).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("--apikey", "Protect with API keys and print the bootstrap keys (the default, made explicit). Consumers send X-API-Key.").option("--oauth [config]", `Login door. Bare = APIblaze-hosted GitHub sign-in. '{"iss","aud","jwks"}' = trust YOUR hosted login's JWTs. '{"provider","clientId","clientSecret"}' = APIblaze-hosted login page with YOUR OAuth app (github \xB7 google \xB7 microsoft \xB7 facebook \xB7 auth0).`).option("--identified", "Require every call to identify its end user (X-End-User-Id or a login token); unattributed calls are rejected").option("--iam", "Turn IAM on for the proxy's tenant so users & groups apply to identified calls").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 to attach the proxy to (created if new). Omitted \u2192 your team's most-recently-used tenant.").option("--product <slug>", "Product tag to group this project under in the portal (team-scoped; anonymous create). Defaults to your team's existing/placeholder tag.").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("--new-session", "Start a fresh anonymous session (do not group with prior anonymous creates)").option("--json", "Output machine-readable JSON (non-interactive)").action(async (opts) => {
|
|
11296
|
+
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>.abz.run)").option("--target <url|file>", "What to proxy \u2014 pass ANY of: a target server base URL (https://httpbin.org), a local OpenAPI file (./openapi.yaml), or a remote OpenAPI URL (https://acme.com/openapi.yaml). Spec inputs are detected automatically; routes, API version and environments then come from the spec").addOption(new import_commander.Option("--openapi <file|url>", "Deprecated alias \u2014 --target now detects spec files/URLs itself").hideHelp()).addOption(new import_commander.Option("--openapispec <file|url>", "Deprecated alias for --openapi").hideHelp()).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("--apikey", "Protect with API keys and print the bootstrap keys (the default, made explicit). Consumers send X-API-Key.").option("--oauth [config]", `Login door. Bare = APIblaze-hosted GitHub sign-in. '{"iss","aud","jwks"}' = trust YOUR hosted login's JWTs. '{"provider","clientId","clientSecret"}' = APIblaze-hosted login page with YOUR OAuth app (github \xB7 google \xB7 microsoft \xB7 facebook \xB7 auth0).`).option("--identified", "Require every call to identify its end user (X-End-User-Id or a login token); unattributed calls are rejected").option("--iam", "Turn IAM on for the proxy's tenant so users & groups apply to identified calls").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 to attach the proxy to (created if new). Omitted \u2192 your team's most-recently-used tenant.").option("--product <slug>", "Product tag to group this project under in the portal (team-scoped; anonymous create). Defaults to your team's existing/placeholder tag.").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("--auto", "Zero prompts, start to finish: generates the proxy name when --name is omitted (from the target host, salted), takes every confirmation as yes, auto-picks the tenant. Implies --yes.").option("--new-session", "Start a fresh anonymous session (do not group with prior anonymous creates)").option("--json", "Output machine-readable JSON (non-interactive)").action(async (opts) => {
|
|
11268
11297
|
try {
|
|
11269
11298
|
await runCreate({ ...opts, openapi: opts.openapi ?? opts.openapispec });
|
|
11270
11299
|
} catch (err) {
|
|
@@ -11442,14 +11471,15 @@ ${groupedCommandHelp()}
|
|
|
11442
11471
|
Tips:
|
|
11443
11472
|
\u2022 \`apiblaze config <project>\` browses EVERY setting & feature (works logged-out to explore).
|
|
11444
11473
|
\u2022 Add --verbose to any command to see the equivalent API calls.
|
|
11474
|
+
\u2022 Add --auto to \`create\` for a scriptable run: no prompts, no TTY needed, proxy name generated.
|
|
11445
11475
|
\u2022 Full API reference: https://api.apiblaze.com/openapi.json
|
|
11446
11476
|
\u2022 Run \`apiblaze <command> --help\` (e.g. \`apiblaze consumer --help\`) for sub-commands.
|
|
11447
11477
|
|
|
11448
11478
|
Examples:
|
|
11449
|
-
$ npx apiblaze apichat --
|
|
11479
|
+
$ npx apiblaze apichat --target https://pokeapi.co/openapi.yaml # chat with any API
|
|
11450
11480
|
$ npx apiblaze agent # just chat
|
|
11451
11481
|
$ npx apiblaze create --target https://api.example.com # one-line API
|
|
11452
|
-
$ npx apiblaze create --
|
|
11482
|
+
$ npx apiblaze create --target https://pokeapi.co/openapi.yaml --auto # zero prompts, name generated
|
|
11453
11483
|
$ npx apiblaze search gmail # find a recipe (no login needed)
|
|
11454
11484
|
$ npx apiblaze install @julien/gmail # someone's whole working setup, your credentials
|
|
11455
11485
|
$ npx apiblaze publish mygmail # share yours back, as @yourgithubhandle/mygmail
|