apiblaze 0.19.9 → 0.19.12

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 CHANGED
@@ -933,7 +933,7 @@ var import_commander = require("commander");
933
933
  var import_chalk44 = __toESM(require("chalk"));
934
934
 
935
935
  // package.json
936
- var version = "0.19.9";
936
+ var version = "0.19.12";
937
937
 
938
938
  // src/index.ts
939
939
  init_types();
@@ -2643,7 +2643,8 @@ async function runAgentChatRepl(opts) {
2643
2643
  import_chalk16.default.dim("type to chat/refine"),
2644
2644
  ...commands.map((c) => import_chalk16.default.dim(`/${c.name} ${c.describe}`)),
2645
2645
  import_chalk16.default.dim("/show"),
2646
- import_chalk16.default.dim("/drop discard & exit")
2646
+ import_chalk16.default.dim("/exit when done"),
2647
+ import_chalk16.default.dim("/drop discard changes")
2647
2648
  ];
2648
2649
  return " " + import_chalk16.default.dim("[ ") + parts.join(import_chalk16.default.dim(" \xB7 ")) + import_chalk16.default.dim(" ]");
2649
2650
  };
@@ -2687,8 +2688,13 @@ async function runAgentChatRepl(opts) {
2687
2688
  console.log(footer());
2688
2689
  const line = (await ask(import_chalk16.default.green("you \u203A "))).trim();
2689
2690
  if (!line) continue;
2690
- if (line === "/drop" || line === "/exit" || line === "/quit") {
2691
- console.log(import_chalk16.default.dim(" Dropped \u2014 nothing applied.\n"));
2691
+ const lower = line.toLowerCase();
2692
+ if (line === "/exit" || line === "/quit" || lower === "exit" || lower === "quit" || lower === "q") {
2693
+ console.log(import_chalk16.default.dim(" Bye \u2014 anything you enabled or published stays in place.\n"));
2694
+ break;
2695
+ }
2696
+ if (line === "/drop") {
2697
+ console.log(import_chalk16.default.dim(" Dropped the pending proposal \u2014 rules you already enabled/published are untouched.\n"));
2692
2698
  break;
2693
2699
  }
2694
2700
  if (line === "/show") {
@@ -2784,7 +2790,7 @@ async function applyProposal(opts) {
2784
2790
  else fail5++;
2785
2791
  }
2786
2792
  if (enable) {
2787
- const e = await agentCall(`/${projectId}/${apiVersion}/config`, "PATCH", { authorization: { enforce_authorization: true }, tenant: tenant2 });
2793
+ const e = await agentCall(`/projects/${projectId}/${apiVersion}`, "PATCH", { authorization: { enforce_authorization: true }, tenant: tenant2 });
2788
2794
  if (e.status >= 400) {
2789
2795
  log(import_chalk17.default.red(` Enforced ${ok} route(s) but turning on the project-level switch failed (${e.status}). Toggle "Enforce Authorization" on in the dashboard.
2790
2796
  `));
@@ -2812,8 +2818,8 @@ async function runAuthz(projectArg, apiVersionArg) {
2812
2818
  const r = await applyProposal({ projectId, apiVersion, tenant: tenant2, proposal, enable, log: ctx.log });
2813
2819
  if (r.storeMissing) return;
2814
2820
  if (enable && r.enabled) {
2815
- ctx.log(import_chalk18.default.green(` \u2713 Enforcement ON \u2014 ${r.ok} route(s) + project switch on${r.fail ? `, ${r.fail} failed` : ""}.
2816
- `));
2821
+ ctx.log(import_chalk18.default.green(` \u2713 Enforcement ON \u2014 ${r.ok} route(s) + project switch on${r.fail ? `, ${r.fail} failed` : ""}.`));
2822
+ ctx.log(import_chalk18.default.dim(" Done here? Type /exit to leave the chat (your rule stays on).\n"));
2817
2823
  } else if (!enable) {
2818
2824
  ctx.log(import_chalk18.default.green(` \u2713 Published (shadow): model + ${r.ok} route(s)${r.fail ? `, ${r.fail} failed` : ""}. Review, then /enable.
2819
2825
  `));
@@ -5511,7 +5517,7 @@ async function runAdminsList(opts) {
5511
5517
  return;
5512
5518
  }
5513
5519
  if (!admins2.length) {
5514
- console.log(import_chalk36.default.yellow(`No admins for tenant ${tenant2} yet.`));
5520
+ console.log(import_chalk36.default.yellow(`No tenant admins for ${tenant2} yet.`));
5515
5521
  return;
5516
5522
  }
5517
5523
  for (const a of admins2) {
@@ -5524,7 +5530,7 @@ async function runAdminsAdd(email, opts) {
5524
5530
  const caller = requireCaller();
5525
5531
  const { teamId } = await resolveActingTeam(caller, opts.team);
5526
5532
  const tenant2 = requireTenant(opts);
5527
- const spinner = opts.json ? null : (0, import_ora19.default)(`Adding ${email} as admin of ${tenant2}...`).start();
5533
+ const spinner = opts.json ? null : (0, import_ora19.default)(`Adding ${email} as a tenant admin of ${tenant2}...`).start();
5528
5534
  try {
5529
5535
  const out = await producer(caller, {
5530
5536
  method: "POST",
@@ -5532,7 +5538,7 @@ async function runAdminsAdd(email, opts) {
5532
5538
  body: { email },
5533
5539
  summary: `Add ${email} to tenant ${tenant2} admins`
5534
5540
  });
5535
- spinner?.succeed(`${import_chalk36.default.bold(email)} is now an admin of ${import_chalk36.default.bold(tenant2)}.`);
5541
+ spinner?.succeed(`${import_chalk36.default.bold(email)} is now a tenant admin of ${import_chalk36.default.bold(tenant2)}.`);
5536
5542
  if (opts.json) console.log(JSON.stringify(out ?? { ok: true }));
5537
5543
  else console.log(import_chalk36.default.dim(" Reload the Users & Groups widget \u2014 access flips from \u201Cpending\u201D to ready."));
5538
5544
  } catch (err) {
@@ -5544,14 +5550,14 @@ async function runAdminsRemove(email, opts) {
5544
5550
  const caller = requireCaller();
5545
5551
  const { teamId } = await resolveActingTeam(caller, opts.team);
5546
5552
  const tenant2 = requireTenant(opts);
5547
- const spinner = opts.json ? null : (0, import_ora19.default)(`Removing ${email} from ${tenant2} admins...`).start();
5553
+ const spinner = opts.json ? null : (0, import_ora19.default)(`Removing ${email} from the tenant admins of ${tenant2}...`).start();
5548
5554
  try {
5549
5555
  await producer(caller, {
5550
5556
  method: "DELETE",
5551
5557
  path: `${base(teamId, tenant2)}/${encodeURIComponent(email)}`,
5552
5558
  summary: `Remove ${email} from tenant ${tenant2} admins`
5553
5559
  });
5554
- spinner?.succeed(`Removed ${import_chalk36.default.bold(email)} from ${import_chalk36.default.bold(tenant2)} admins.`);
5560
+ spinner?.succeed(`Removed ${import_chalk36.default.bold(email)} from the tenant admins of ${import_chalk36.default.bold(tenant2)}.`);
5555
5561
  } catch (err) {
5556
5562
  spinner?.fail("Remove failed.");
5557
5563
  throw err;
@@ -78,12 +78,14 @@ function Typeahead(props) {
78
78
  const [q, setQ] = React.useState("");
79
79
  const [results, setResults] = React.useState(null);
80
80
  const [loading, setLoading] = React.useState(false);
81
+ const [active, setActive] = React.useState(-1);
81
82
  const seq = React.useRef(0);
82
83
  React.useEffect(() => {
83
84
  const term = q.trim();
84
85
  if (term.length < 2) {
85
86
  setResults(null);
86
87
  setLoading(false);
88
+ setActive(-1);
87
89
  return;
88
90
  }
89
91
  const my = ++seq.current;
@@ -94,16 +96,44 @@ function Typeahead(props) {
94
96
  if (my === seq.current) {
95
97
  setResults(r);
96
98
  setLoading(false);
99
+ setActive(r.length ? 0 : -1);
97
100
  }
98
101
  } catch {
99
102
  if (my === seq.current) {
100
103
  setResults([]);
101
104
  setLoading(false);
105
+ setActive(-1);
102
106
  }
103
107
  }
104
108
  }, 250);
105
109
  return () => clearTimeout(h);
106
110
  }, [q]);
111
+ const pick = (it) => {
112
+ props.onPick(it);
113
+ setQ("");
114
+ setResults(null);
115
+ setActive(-1);
116
+ };
117
+ const onKeyDown = (e) => {
118
+ if (e.key === "Escape") {
119
+ setQ("");
120
+ setResults(null);
121
+ setActive(-1);
122
+ return;
123
+ }
124
+ if (!results || results.length === 0) return;
125
+ if (e.key === "ArrowDown") {
126
+ e.preventDefault();
127
+ setActive((a) => (a + 1) % results.length);
128
+ } else if (e.key === "ArrowUp") {
129
+ e.preventDefault();
130
+ setActive((a) => (a - 1 + results.length) % results.length);
131
+ } else if (e.key === "Enter") {
132
+ e.preventDefault();
133
+ pick(results[active >= 0 ? active : 0]);
134
+ }
135
+ };
136
+ const open = q.trim().length >= 2;
107
137
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { position: "relative", flex: 1, minWidth: 180 }, children: [
108
138
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
109
139
  "input",
@@ -112,23 +142,26 @@ function Typeahead(props) {
112
142
  placeholder: props.placeholder,
113
143
  value: q,
114
144
  onChange: (e) => setQ(e.target.value),
145
+ onKeyDown,
115
146
  disabled: props.disabled,
147
+ role: "combobox",
148
+ "aria-expanded": open,
149
+ "aria-autocomplete": "list",
116
150
  "aria-label": props.placeholder
117
151
  }
118
152
  ),
119
- q.trim().length >= 2 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { position: "absolute", zIndex: 5, left: 0, right: 0, top: "100%", marginTop: 4, background: props.s.surface, border: `1px solid ${props.s.border}`, borderRadius: 8, maxHeight: 220, overflowY: "auto", boxShadow: "0 6px 18px rgba(0,0,0,0.12)" }, children: [
153
+ open && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { role: "listbox", style: { position: "absolute", zIndex: 5, left: 0, right: 0, top: "100%", marginTop: 4, background: props.s.surface, border: `1px solid ${props.s.border}`, borderRadius: 8, maxHeight: 220, overflowY: "auto", boxShadow: "0 6px 18px rgba(0,0,0,0.12)" }, children: [
120
154
  loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "8px 10px", fontSize: 12, color: props.s.muted }, children: "Searching\u2026" }),
121
155
  !loading && results && results.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "8px 10px", fontSize: 12, color: props.s.muted }, children: "No matches" }),
122
- !loading && results && results.map((it) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
156
+ !loading && results && results.map((it, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
123
157
  "button",
124
158
  {
159
+ role: "option",
160
+ "aria-selected": i === active,
125
161
  onMouseDown: (e) => e.preventDefault(),
126
- onClick: () => {
127
- props.onPick(it);
128
- setQ("");
129
- setResults(null);
130
- },
131
- style: { display: "block", width: "100%", textAlign: "left", padding: "8px 10px", border: "none", borderBottom: `1px solid ${props.s.border}`, background: "transparent", cursor: "pointer", color: props.s.text, fontFamily: "inherit", fontSize: 13 },
162
+ onMouseEnter: () => setActive(i),
163
+ onClick: () => pick(it),
164
+ style: { display: "block", width: "100%", textAlign: "left", padding: "8px 10px", border: "none", borderBottom: `1px solid ${props.s.border}`, background: i === active ? `color-mix(in srgb, currentColor 8%, transparent)` : "transparent", cursor: "pointer", color: props.s.text, fontFamily: "inherit", fontSize: 13 },
132
165
  children: props.itemLabel(it)
133
166
  },
134
167
  props.itemKey(it)
@@ -43,12 +43,14 @@ function Typeahead(props) {
43
43
  const [q, setQ] = React.useState("");
44
44
  const [results, setResults] = React.useState(null);
45
45
  const [loading, setLoading] = React.useState(false);
46
+ const [active, setActive] = React.useState(-1);
46
47
  const seq = React.useRef(0);
47
48
  React.useEffect(() => {
48
49
  const term = q.trim();
49
50
  if (term.length < 2) {
50
51
  setResults(null);
51
52
  setLoading(false);
53
+ setActive(-1);
52
54
  return;
53
55
  }
54
56
  const my = ++seq.current;
@@ -59,16 +61,44 @@ function Typeahead(props) {
59
61
  if (my === seq.current) {
60
62
  setResults(r);
61
63
  setLoading(false);
64
+ setActive(r.length ? 0 : -1);
62
65
  }
63
66
  } catch {
64
67
  if (my === seq.current) {
65
68
  setResults([]);
66
69
  setLoading(false);
70
+ setActive(-1);
67
71
  }
68
72
  }
69
73
  }, 250);
70
74
  return () => clearTimeout(h);
71
75
  }, [q]);
76
+ const pick = (it) => {
77
+ props.onPick(it);
78
+ setQ("");
79
+ setResults(null);
80
+ setActive(-1);
81
+ };
82
+ const onKeyDown = (e) => {
83
+ if (e.key === "Escape") {
84
+ setQ("");
85
+ setResults(null);
86
+ setActive(-1);
87
+ return;
88
+ }
89
+ if (!results || results.length === 0) return;
90
+ if (e.key === "ArrowDown") {
91
+ e.preventDefault();
92
+ setActive((a) => (a + 1) % results.length);
93
+ } else if (e.key === "ArrowUp") {
94
+ e.preventDefault();
95
+ setActive((a) => (a - 1 + results.length) % results.length);
96
+ } else if (e.key === "Enter") {
97
+ e.preventDefault();
98
+ pick(results[active >= 0 ? active : 0]);
99
+ }
100
+ };
101
+ const open = q.trim().length >= 2;
72
102
  return /* @__PURE__ */ jsxs("div", { style: { position: "relative", flex: 1, minWidth: 180 }, children: [
73
103
  /* @__PURE__ */ jsx(
74
104
  "input",
@@ -77,23 +107,26 @@ function Typeahead(props) {
77
107
  placeholder: props.placeholder,
78
108
  value: q,
79
109
  onChange: (e) => setQ(e.target.value),
110
+ onKeyDown,
80
111
  disabled: props.disabled,
112
+ role: "combobox",
113
+ "aria-expanded": open,
114
+ "aria-autocomplete": "list",
81
115
  "aria-label": props.placeholder
82
116
  }
83
117
  ),
84
- q.trim().length >= 2 && /* @__PURE__ */ jsxs("div", { style: { position: "absolute", zIndex: 5, left: 0, right: 0, top: "100%", marginTop: 4, background: props.s.surface, border: `1px solid ${props.s.border}`, borderRadius: 8, maxHeight: 220, overflowY: "auto", boxShadow: "0 6px 18px rgba(0,0,0,0.12)" }, children: [
118
+ open && /* @__PURE__ */ jsxs("div", { role: "listbox", style: { position: "absolute", zIndex: 5, left: 0, right: 0, top: "100%", marginTop: 4, background: props.s.surface, border: `1px solid ${props.s.border}`, borderRadius: 8, maxHeight: 220, overflowY: "auto", boxShadow: "0 6px 18px rgba(0,0,0,0.12)" }, children: [
85
119
  loading && /* @__PURE__ */ jsx("div", { style: { padding: "8px 10px", fontSize: 12, color: props.s.muted }, children: "Searching\u2026" }),
86
120
  !loading && results && results.length === 0 && /* @__PURE__ */ jsx("div", { style: { padding: "8px 10px", fontSize: 12, color: props.s.muted }, children: "No matches" }),
87
- !loading && results && results.map((it) => /* @__PURE__ */ jsx(
121
+ !loading && results && results.map((it, i) => /* @__PURE__ */ jsx(
88
122
  "button",
89
123
  {
124
+ role: "option",
125
+ "aria-selected": i === active,
90
126
  onMouseDown: (e) => e.preventDefault(),
91
- onClick: () => {
92
- props.onPick(it);
93
- setQ("");
94
- setResults(null);
95
- },
96
- style: { display: "block", width: "100%", textAlign: "left", padding: "8px 10px", border: "none", borderBottom: `1px solid ${props.s.border}`, background: "transparent", cursor: "pointer", color: props.s.text, fontFamily: "inherit", fontSize: 13 },
127
+ onMouseEnter: () => setActive(i),
128
+ onClick: () => pick(it),
129
+ style: { display: "block", width: "100%", textAlign: "left", padding: "8px 10px", border: "none", borderBottom: `1px solid ${props.s.border}`, background: i === active ? `color-mix(in srgb, currentColor 8%, transparent)` : "transparent", cursor: "pointer", color: props.s.text, fontFamily: "inherit", fontSize: 13 },
97
130
  children: props.itemLabel(it)
98
131
  },
99
132
  props.itemKey(it)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.19.9",
3
+ "version": "0.19.12",
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",