apiblaze 0.21.46 → 0.21.47

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/README.md CHANGED
@@ -271,12 +271,13 @@ shows both, and `logout` asks which to drop.
271
271
 
272
272
  | Command | What it does |
273
273
  |---|---|
274
- | `apiblaze consumer login` | Pick a tenant and log in to its portal (device flow in your browser) |
274
+ | `apiblaze consumer login --tenant <slug>` | Log in to that tenant's portal (device flow in your browser); no producer account needed |
275
+ | `apiblaze consumer login` | Producer shortcut: pick one of your team's tenants |
275
276
  | `apiblaze consumer tokens` | Show your consumer access / refresh / id tokens |
276
277
  | `apiblaze consumer apikeys` | List your API keys (reveals expiring ones in clear), then offer to create one |
277
278
 
278
- > A standalone consumer (no producer account) can log in with
279
- > `apiblaze consumer login --tenant <slug> --client <appClientId>`.
279
+ > `--tenant` uses the tenant's default login app; add `--client <appClientId>` to
280
+ > pick a specific one.
280
281
  >
281
282
  > Advanced: `apiblaze apikeys` manages producer control-plane keys for scripting.
282
283
 
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
34
34
  var version;
35
35
  var init_package = __esm({
36
36
  "package.json"() {
37
- version = "0.21.46";
37
+ version = "0.21.47";
38
38
  }
39
39
  });
40
40
 
@@ -374,6 +374,7 @@ __export(api_exports, {
374
374
  GITHUB_LOGIN: () => GITHUB_LOGIN,
375
375
  INTEGRATION_STACKS: () => INTEGRATION_STACKS,
376
376
  LOCAL_SPEC_PATHS: () => LOCAL_SPEC_PATHS,
377
+ PUBLIC_API_BASE: () => PUBLIC_API_BASE,
377
378
  agentCall: () => agentCall,
378
379
  bothDoorsBody: () => bothDoorsBody,
379
380
  checkProxyName: () => checkProxyName,
@@ -3801,7 +3802,7 @@ async function replTurn(p, messages, userText) {
3801
3802
  }
3802
3803
  }
3803
3804
  console.log(import_chalk15.default.red(" This proxy signs consumers in with OAuth (a login), not an API key."));
3804
- console.log(import_chalk15.default.dim(" Sign in with: `apiblaze consumer login --tenant <tenant> --client <app-client-id>`, then re-run apichat."));
3805
+ console.log(import_chalk15.default.dim(" Sign in with: `apiblaze consumer login --tenant <tenant>`, then re-run apichat."));
3805
3806
  return;
3806
3807
  }
3807
3808
  if (keyWanted) {
@@ -16349,7 +16350,13 @@ async function runTenantPasswordDisable(tenantArg2, opts) {
16349
16350
  if (opts.json) console.log(JSON.stringify({ enabled: false }));
16350
16351
  }
16351
16352
  function printAccount(a) {
16352
- const flags = [a.disabled ? import_chalk59.default.red("blocked") : import_chalk59.default.green("active"), a.locked_until ? import_chalk59.default.yellow(`locked until ${a.locked_until}`) : "", a.purpose === "reviewer" ? import_chalk59.default.cyan("reviewer") : ""].filter(Boolean).join(" \xB7 ");
16353
+ const flags = [
16354
+ a.disabled ? import_chalk59.default.red("blocked") : import_chalk59.default.green("active"),
16355
+ a.locked_until ? import_chalk59.default.yellow(`locked until ${a.locked_until}`) : "",
16356
+ a.purpose === "reviewer" ? import_chalk59.default.cyan("reviewer") : "",
16357
+ a.self_signup ? import_chalk59.default.dim("signed up") : "",
16358
+ a.email && !a.email_verified_at ? import_chalk59.default.yellow("email unconfirmed") : ""
16359
+ ].filter(Boolean).join(" \xB7 ");
16353
16360
  console.log(` ${import_chalk59.default.bold(a.username)} ${flags}${a.email ? import_chalk59.default.dim(` ${a.email}`) : ""}${a.last_login_at ? import_chalk59.default.dim(` last login ${a.last_login_at}`) : ""}`);
16354
16361
  }
16355
16362
  async function runTenantPasswordList(tenantArg2, opts) {
@@ -16763,6 +16770,8 @@ var import_ora31 = __toESM(require("ora"));
16763
16770
  init_admin();
16764
16771
  init_resolve();
16765
16772
  init_caller();
16773
+ init_api();
16774
+ init_version_guard();
16766
16775
  init_paging();
16767
16776
  init_consumer_auth();
16768
16777
  var DEFAULT_SCOPE = "openid email profile offline_access";
@@ -16787,6 +16796,17 @@ function requireConsumer2() {
16787
16796
  }
16788
16797
  return c;
16789
16798
  }
16799
+ async function publicDefaultAppClient(tenant2, base2 = PUBLIC_API_BASE) {
16800
+ try {
16801
+ const res = await fetch(`${base2}/appClients?tenant=${encodeURIComponent(tenant2)}`, { headers: cliHeaders(), signal: AbortSignal.timeout(1e4) });
16802
+ if (res.status === 404) return { clientId: null, found: false };
16803
+ if (!res.ok) return { clientId: null, found: true };
16804
+ const body = await res.json();
16805
+ return { clientId: typeof body.defaultAppClientId === "string" && body.defaultAppClientId ? body.defaultAppClientId : null, found: true };
16806
+ } catch {
16807
+ return { clientId: null, found: true };
16808
+ }
16809
+ }
16790
16810
  async function runConsumerLogin(opts) {
16791
16811
  const { default: inquirer3 } = await import("inquirer");
16792
16812
  let tenant2 = opts.tenant;
@@ -16796,6 +16816,19 @@ async function runConsumerLogin(opts) {
16796
16816
  console.error(import_chalk62.default.red("When using --client, also pass --tenant <slug> (it sets which portal/keys host to use)."));
16797
16817
  process.exit(1);
16798
16818
  }
16819
+ } else if (tenant2) {
16820
+ const s = (0, import_ora31.default)("Finding the login app...").start();
16821
+ const r = await publicDefaultAppClient(tenant2);
16822
+ s.stop();
16823
+ if (!r.found) {
16824
+ console.error(import_chalk62.default.red(`No tenant named "${tenant2}".`));
16825
+ process.exit(1);
16826
+ }
16827
+ if (!r.clientId) {
16828
+ console.error(import_chalk62.default.red(`Tenant "${tenant2}" has no login app configured. Its owner sets one up in the dashboard (or \`apiblaze create\` with auth); or pass --client <appClientId>.`));
16829
+ process.exit(1);
16830
+ }
16831
+ clientId = r.clientId;
16799
16832
  } else {
16800
16833
  requireAuth();
16801
16834
  const { teamId, teamName } = await resolveTeam(opts.team);
@@ -18968,7 +19001,7 @@ program.command("dev").description(`Put the app running on THIS machine on the i
18968
19001
  }
18969
19002
  });
18970
19003
  var consumer = program.command("consumer").description("Act as a consumer of your API \u2014 log in, get tokens, manage API keys");
18971
- consumer.command("login").description("Log in to a tenant's portal as a consumer (device flow)").option("--team <id|name>", "Team whose tenants to choose from (producer mode)").option("--tenant <slug>", "Tenant to log in to (skips the picker)").option("--client <clientId>", "App client id \u2014 for standalone login without a producer session").action(action((opts) => runConsumerLogin(opts)));
19004
+ consumer.command("login").description("Log in to a tenant's portal as a consumer (device flow)").option("--tenant <slug>", "Tenant to log in to \u2014 uses its default login app; no producer login needed").option("--client <clientId>", "A specific app client id instead of the tenant's default (with --tenant)").option("--team <id|name>", "Without --tenant: the team whose tenants to pick from (producer session)").action(action((opts) => runConsumerLogin(opts)));
18972
19005
  consumer.command("tokens").description("Show the logged-in consumer access / refresh / id tokens").option("--json", "Output machine-readable JSON").action(action((opts) => runConsumerTokens(opts)));
18973
19006
  consumer.command("apikeys").description("List your consumer API keys (reveals expiring ones), then offer to create one").option("--json", "Output machine-readable JSON").action(action((opts) => runConsumerApikeys(opts)));
18974
19007
  var consumerLogs = consumer.command("logs").description("API Consumer view \u2014 stream YOUR OWN requests on this tenant live (see `consumer logs list` for past days)").option("--project <name>", "Only this project (when the tenant serves several)").option("--errors-only", "Only show 4xx/5xx responses").option("--json", "Emit raw NDJSON rows (pipe into jq)").action(action((opts) => runConsumerLogsTail(opts)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.21.46",
3
+ "version": "0.21.47",
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",