apiblaze 0.19.17 → 0.19.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.
Files changed (3) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +27 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -33,6 +33,10 @@ npx apiblaze apichat --openapi https://apiblaze.com/pokeapi_openapi.yaml
33
33
  # Make an API in one line — no account needed (prints a claim URL)
34
34
  npx apiblaze create --target https://api.example.com
35
35
 
36
+ # Or build it straight from an OpenAPI spec — a URL or a local file.
37
+ # The routes, the API version and one environment per `servers` entry all come from the spec.
38
+ npx apiblaze create --openapi https://petstore3.swagger.io/api/v3/openapi.json
39
+
36
40
  # Configure how your backend is accessed through the proxy
37
41
  npx apiblaze config
38
42
 
@@ -114,6 +118,7 @@ Every chat turn shows its cost.
114
118
  | Command | What it does |
115
119
  |---|---|
116
120
  | `apiblaze create --target <url>` | Make an API from a backend (no account needed) |
121
+ | `apiblaze create --openapi <file\|url>` | Make an API from an OpenAPI spec — a local file or a spec URL (`--openapispec` is the same flag) |
117
122
  | `apiblaze sidecar` | Route a Next.js app's external `fetch()` calls through APIblaze (one command) |
118
123
  | `apiblaze dev [port]` | Put your localhost behind a public URL |
119
124
  | `apiblaze login` / `logout` | Sign in / out (logout asks producer or consumer) |
package/dist/index.js CHANGED
@@ -932,7 +932,7 @@ var import_commander = require("commander");
932
932
  var import_chalk44 = __toESM(require("chalk"));
933
933
 
934
934
  // package.json
935
- var version = "0.19.17";
935
+ var version = "0.19.18";
936
936
 
937
937
  // src/index.ts
938
938
  init_types();
@@ -1948,6 +1948,27 @@ function isHttpUrl(s) {
1948
1948
  return false;
1949
1949
  }
1950
1950
  }
1951
+ async function loadOpenapiSource(ref) {
1952
+ let text;
1953
+ if (isHttpUrl(ref)) {
1954
+ const res = await fetch(ref.trim(), {
1955
+ headers: { accept: "application/json, application/yaml, text/yaml, */*" }
1956
+ }).catch((err) => fail(`Could not fetch the OpenAPI spec at ${ref} \u2014 ${err.message}`));
1957
+ if (!res.ok) fail(`Could not fetch the OpenAPI spec at ${ref} (HTTP ${res.status}).`);
1958
+ text = await res.text();
1959
+ } else {
1960
+ try {
1961
+ text = import_fs2.default.readFileSync(ref, "utf8");
1962
+ } catch {
1963
+ fail(`Cannot read the OpenAPI spec "${ref}" \u2014 it is not a readable file, and not an http(s) URL.`);
1964
+ }
1965
+ }
1966
+ if (!text.trim()) fail(`The OpenAPI spec is empty: ${ref}`);
1967
+ if (!/["']?(openapi|swagger|paths)["']?\s*:/i.test(text)) {
1968
+ fail(`That does not look like an OpenAPI/Swagger document (no openapi/swagger/paths): ${ref}`);
1969
+ }
1970
+ return text;
1971
+ }
1951
1972
  function stripTenantFromPortal(devPortal) {
1952
1973
  try {
1953
1974
  const u = new URL(devPortal);
@@ -2056,12 +2077,7 @@ async function runCreate(opts = {}) {
2056
2077
  let openapiContent = null;
2057
2078
  if (opts.openapi !== void 0) {
2058
2079
  if (opts.target !== void 0) fail("Provide only one of --target or --openapi.");
2059
- try {
2060
- openapiContent = import_fs2.default.readFileSync(opts.openapi, "utf8");
2061
- } catch {
2062
- fail(`Cannot read --openapi file: ${opts.openapi}`);
2063
- }
2064
- if (!openapiContent || !openapiContent.trim()) fail(`--openapi file is empty: ${opts.openapi}`);
2080
+ openapiContent = await loadOpenapiSource(opts.openapi);
2065
2081
  }
2066
2082
  let targetUrl = "";
2067
2083
  if (openapiContent) {
@@ -2186,11 +2202,7 @@ async function runAnonymousCreate(opts) {
2186
2202
  fail("Proxy name must be at least 3 characters (letters and digits only).");
2187
2203
  }
2188
2204
  if (opts.openapi !== void 0) {
2189
- try {
2190
- body.openapi = import_fs2.default.readFileSync(opts.openapi, "utf8");
2191
- } catch {
2192
- fail(`Cannot read --openapi file: ${opts.openapi}`);
2193
- }
2205
+ body.openapi = await loadOpenapiSource(opts.openapi);
2194
2206
  }
2195
2207
  if (opts.target && !isHttpUrl(opts.target)) fail("--target must be a valid http(s) URL.");
2196
2208
  let target = opts.target?.trim() || (typeof body.target === "string" ? body.target : "") || (typeof body.target_url === "string" ? body.target_url : "");
@@ -7467,9 +7479,9 @@ program.command("login").description("Authenticate with APIblaze").option("--tea
7467
7479
  process.exit(1);
7468
7480
  }
7469
7481
  });
7470
- 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>", "Target URL to forward requests to").option("--openapi <file>", "Create FROM an OpenAPI file instead of --target: routes, API version and environments (one per `servers` entry) all come from the spec").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("--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) => {
7482
+ 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>", "Target URL to forward requests to").option("--openapi <file|url>", "Create FROM an OpenAPI spec instead of --target \u2014 a local file or a URL (e.g. https://pokeapi.co/openapi.yaml). Routes, API version and environments (one per `servers` entry) all come from the spec").option("--openapispec <file|url>", "Alias for --openapi").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("--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) => {
7471
7483
  try {
7472
- await runCreate(opts);
7484
+ await runCreate({ ...opts, openapi: opts.openapi ?? opts.openapispec });
7473
7485
  } catch (err) {
7474
7486
  await printError(err);
7475
7487
  process.exit(1);
@@ -7639,6 +7651,7 @@ Examples:
7639
7651
  $ npx apiblaze apichat --openapi https://pokeapi.co/openapi.yaml # chat with any API
7640
7652
  $ npx apiblaze agent # just chat
7641
7653
  $ npx apiblaze create --target https://api.example.com # one-line API
7654
+ $ npx apiblaze create --openapi https://pokeapi.co/openapi.yaml # build it from a spec URL
7642
7655
  $ npx apiblaze dev 3000 # localhost \u2192 public URL
7643
7656
  $ npx apiblaze throttle myapi --rate 50 --verbose # configure + show the API call
7644
7657
  $ npx apiblaze consumer login # act as a consumer of your API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.19.17",
3
+ "version": "0.19.18",
4
4
  "description": "APIblaze CLI — Chat with your APIs, Manage your API keys, users and groups with the APIblaze serverless proxy",
5
5
  "keywords": [
6
6
  "apiblaze",