@base44-preview/cli 0.1.32-pr.663.57b7b28 → 0.1.32-pr.663.d960536

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
@@ -43,8 +43,9 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
43
43
 
44
44
  | Command | Description |
45
45
  | ------- | ----------- |
46
+ | `api catalog [area]` | List the API's areas, or every operation in one area |
46
47
  | `api search <text>` | Search every public Base44 API operation by what it does |
47
- | `api grep <pattern>` | Search the raw API spec with a regular expression |
48
+ | `api grep <pattern>` | Search the raw API spec with a regular expression; `--area` narrows it to one area |
48
49
  | `api fetch <METHOD> <path>` | Call any public Base44 API operation, like curl; `--help` after a path prints its contract |
49
50
  | [`create`](https://docs.base44.com/developers/references/cli/commands/create) | Create a new Base44 project from a template |
50
51
  | [`deploy`](https://docs.base44.com/developers/references/cli/commands/deploy) | Deploy all project resources and site to Base44 |
package/dist/cli/index.js CHANGED
@@ -248042,28 +248042,6 @@ function getAgentsCommand() {
248042
248042
  return new Command2("agents").description("Manage project agents").addCommand(getAgentsPushCommand()).addCommand(getAgentsPullCommand());
248043
248043
  }
248044
248044
 
248045
- // src/core/api-spec/body.ts
248046
- var METHODS_WITHOUT_BODY = new Set(["GET", "HEAD"]);
248047
- async function resolveRequestBody(method, flag, source) {
248048
- const takesBody = !METHODS_WITHOUT_BODY.has(method.toUpperCase());
248049
- if (flag !== undefined && !takesBody) {
248050
- throw new InvalidInputError(`${method.toUpperCase()} requests cannot have a body.`);
248051
- }
248052
- if (flag === "@-") {
248053
- return source.readStdin();
248054
- }
248055
- if (flag?.startsWith("@")) {
248056
- return readTextFile(flag.slice(1));
248057
- }
248058
- if (flag !== undefined) {
248059
- return flag;
248060
- }
248061
- if (!takesBody || source.stdinIsTTY) {
248062
- return;
248063
- }
248064
- const piped = await source.readStdin();
248065
- return piped.trim() ? piped : undefined;
248066
- }
248067
248045
  // ../../node_modules/minisearch/dist/es/index.js
248068
248046
  var ENTRIES = "ENTRIES";
248069
248047
  var KEYS = "KEYS";
@@ -249164,6 +249142,38 @@ function searchOperations(operations, query, options = {}) {
249164
249142
  });
249165
249143
  }
249166
249144
 
249145
+ // src/core/api-spec/catalog.ts
249146
+ var INLINE_AREA_MAX = 2;
249147
+ var AREA_SAMPLE_MAX = 3;
249148
+ var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
249149
+ function areaOf(path) {
249150
+ const parts = path.split("/").filter(Boolean);
249151
+ const appIdIndex = parts.indexOf("{app_id}");
249152
+ if (appIdIndex !== -1 && appIdIndex + 1 < parts.length) {
249153
+ return parts[appIdIndex + 1] ?? "other";
249154
+ }
249155
+ if (parts[0] === "api" && parts.length > 1) {
249156
+ return parts[1] ?? "other";
249157
+ }
249158
+ return parts[0] ?? "other";
249159
+ }
249160
+ function groupByArea(operations) {
249161
+ const sorted = [...operations].sort((a, b) => byCodePoint(`${a.method} ${a.path}`, `${b.method} ${b.path}`));
249162
+ const areas = new Map;
249163
+ for (const op of sorted) {
249164
+ const area = areaOf(op.path);
249165
+ areas.set(area, [...areas.get(area) ?? [], op]);
249166
+ }
249167
+ return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
249168
+ }
249169
+ function catalogIndex(operations) {
249170
+ const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
249171
+ area,
249172
+ operationCount: ops.length,
249173
+ sample: ops.slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
249174
+ });
249175
+ return { areas, total: operations.length };
249176
+ }
249167
249177
  // src/core/api-spec/grep.ts
249168
249178
  var CONTEXT_CHARS = 40;
249169
249179
  var MAX_SNIPPETS = 3;
@@ -249183,13 +249193,15 @@ function snippets(text, pattern) {
249183
249193
  function grepSpec(spec, operations, pattern, options = {}) {
249184
249194
  const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
249185
249195
  const hits = [];
249186
- for (const op of operations) {
249196
+ const inArea = (op) => options.area === undefined || areaOf(op.path) === options.area;
249197
+ for (const op of operations.filter(inArea)) {
249187
249198
  const matches = snippets(`${op.method} ${op.path} ${JSON.stringify(op.operation)}`, regex);
249188
249199
  if (matches.length > 0) {
249189
249200
  hits.push({ ...toOperationSummary(op), matches });
249190
249201
  }
249191
249202
  }
249192
- for (const [schema, definition] of Object.entries(spec.components?.schemas ?? {})) {
249203
+ const schemas = options.area === undefined ? spec.components?.schemas : {};
249204
+ for (const [schema, definition] of Object.entries(schemas ?? {})) {
249193
249205
  const matches = snippets(JSON.stringify(definition), regex);
249194
249206
  if (matches.length > 0) {
249195
249207
  hits.push({ schema, matches });
@@ -249437,6 +249449,56 @@ function loadSpecTask({ runTask }, refresh) {
249437
249449
  successMessage: "Loaded the API spec"
249438
249450
  });
249439
249451
  }
249452
+ function operationsInArea(operations, area) {
249453
+ const areas = groupByArea(operations);
249454
+ const inArea = areas.get(area);
249455
+ if (!inArea) {
249456
+ throw new InvalidInputError(`Unknown API area: ${area}`, {
249457
+ details: [`Areas: ${[...areas.keys()].join(", ")}`],
249458
+ hints: [{ message: "List the areas", command: "base44 api catalog" }]
249459
+ });
249460
+ }
249461
+ return inArea;
249462
+ }
249463
+ async function readRequestBody(method, flag) {
249464
+ if (flag === "@-") {
249465
+ return readStdin("--body @-", { trim: false });
249466
+ }
249467
+ if (flag?.startsWith("@")) {
249468
+ return readTextFile(flag.slice(1));
249469
+ }
249470
+ if (flag !== undefined) {
249471
+ return flag;
249472
+ }
249473
+ if (method === "GET" || method === "HEAD" || process.stdin.isTTY) {
249474
+ return;
249475
+ }
249476
+ const piped = await readStdin("--body", { trim: false });
249477
+ return piped.trim() ? piped : undefined;
249478
+ }
249479
+
249480
+ // src/cli/commands/api/catalog.ts
249481
+ async function catalogAction(ctx, area, options) {
249482
+ const { spec } = await loadSpecTask(ctx, options.refresh);
249483
+ const operations = listOperations(spec);
249484
+ if (area === undefined) {
249485
+ return { stdout: formatJson(catalogIndex(operations)) };
249486
+ }
249487
+ const inArea = operationsInArea(operations, area);
249488
+ return {
249489
+ stdout: formatJson({
249490
+ area,
249491
+ operations: inArea.map(toOperationSummary),
249492
+ total: inArea.length
249493
+ })
249494
+ };
249495
+ }
249496
+ function getApiCatalogCommand() {
249497
+ return new Base44Command("catalog", {
249498
+ requireAuth: false,
249499
+ requireAppContext: false
249500
+ }).description("List the API's areas, or every operation in one area").argument("[area]", 'An area from the list, e.g. "workflows"').option("--refresh", REFRESH_OPTION_HELP).action(catalogAction);
249501
+ }
249440
249502
 
249441
249503
  // src/cli/commands/api/fetch.ts
249442
249504
  async function findOperation(ctx, method, path, refresh) {
@@ -249462,12 +249524,6 @@ async function fetchAction(ctx, methodArg, path, options, command) {
249462
249524
  throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
249463
249525
  }
249464
249526
  const method = methodArg.toUpperCase();
249465
- if (!HTTP_METHODS.some((m) => m.toUpperCase() === method)) {
249466
- throw new InvalidInputError(`Unknown HTTP method: ${methodArg}`);
249467
- }
249468
- if (!path.startsWith("/")) {
249469
- throw new InvalidInputError(`The path must start with "/", got ${path}.`);
249470
- }
249471
249527
  if (options.help) {
249472
249528
  const { spec, op } = await findOperation(ctx, method, path, options.refresh);
249473
249529
  return { stdout: formatJson(getOperationContract(spec, op)) };
@@ -249478,11 +249534,8 @@ async function fetchAction(ctx, methodArg, path, options, command) {
249478
249534
  throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
249479
249535
  }
249480
249536
  }
249481
- const body = await resolveRequestBody(method, options.body, {
249482
- stdinIsTTY: Boolean(process.stdin.isTTY),
249483
- readStdin: () => readStdin("--body @-", { trim: false })
249484
- });
249485
249537
  await ensureAuth(ctx);
249538
+ const body = await readRequestBody(method, options.body);
249486
249539
  const text = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), { successMessage: `Called ${method} ${path}` });
249487
249540
  return { stdout: formatResponseBody(text) };
249488
249541
  }
@@ -249505,7 +249558,12 @@ async function grepAction(ctx, pattern, options) {
249505
249558
  const limit = parseLimit(options.limit);
249506
249559
  assertValidRegex(pattern);
249507
249560
  const { spec } = await loadSpecTask(ctx, options.refresh);
249508
- const hits = grepSpec(spec, listOperations(spec), pattern, {
249561
+ const operations = listOperations(spec);
249562
+ if (options.area !== undefined) {
249563
+ operationsInArea(operations, options.area);
249564
+ }
249565
+ const hits = grepSpec(spec, operations, pattern, {
249566
+ area: options.area,
249509
249567
  ignoreCase: options.ignoreCase,
249510
249568
  limit
249511
249569
  });
@@ -249515,7 +249573,7 @@ function getApiGrepCommand() {
249515
249573
  return new Base44Command("grep", {
249516
249574
  requireAuth: false,
249517
249575
  requireAppContext: false
249518
- }).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
249576
+ }).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("--area <area>", "Search only one area's operations (see base44 api catalog)").option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
249519
249577
  }
249520
249578
 
249521
249579
  // src/cli/commands/api/search.ts
@@ -249537,7 +249595,7 @@ function getApiSearchCommand() {
249537
249595
 
249538
249596
  // src/cli/commands/api/index.ts
249539
249597
  function getApiCommand() {
249540
- return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
249598
+ return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiCatalogCommand()).addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
249541
249599
  }
249542
249600
 
249543
249601
  // src/cli/commands/auth/password-login.ts
@@ -254901,6 +254959,12 @@ var deno2 = Object.freeze({
254901
254959
  });
254902
254960
  globalThis.Deno = deno2;
254903
254961
  globalThis.Buffer = Buffer2;
254962
+ try {
254963
+ new AsyncLocalStorage().enterWith(void 0);
254964
+ } catch {
254965
+ AsyncLocalStorage.prototype.enterWith = () => {
254966
+ };
254967
+ }
254904
254968
  function getRegisteredHandler() {
254905
254969
  return registeredHandler;
254906
254970
  }
@@ -257866,7 +257930,7 @@ var TELEMETRY_PATCH = [
257866
257930
  var TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
257867
257931
 
257868
257932
  // ../functions-compiler/src/version.ts
257869
- var COMPILER_VERSION = "0.1.7";
257933
+ var COMPILER_VERSION = "0.1.8";
257870
257934
 
257871
257935
  // ../functions-compiler/src/worker-entry.ts
257872
257936
  function denoShimSource() {
@@ -262490,6 +262554,174 @@ function runtimeVirtualPlugin() {
262490
262554
  };
262491
262555
  }
262492
262556
 
262557
+ // ../functions-compiler/src/esbuild/ws-native-virtual.ts
262558
+ var NAMESPACE4 = "base44-ws-native";
262559
+ var WS_SPECIFIER = /^(npm:)?ws(@[^/]+)?$/;
262560
+ var ADAPTER = `"use strict";
262561
+ const toBuffer = (value) => (globalThis.Buffer ? globalThis.Buffer.from(value) : value);
262562
+ const READY_STATES = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
262563
+ const later = (fn, ...args) => queueMicrotask(() => fn(...args));
262564
+ const upgradeHeaders = (options) => {
262565
+ const headers = new Headers(options?.headers);
262566
+ for (const name of headers.keys()) if (name !== "user-agent") return headers;
262567
+ return null;
262568
+ };
262569
+ class WebSocket {
262570
+ static CONNECTING = 0;
262571
+ static OPEN = 1;
262572
+ static CLOSING = 2;
262573
+ static CLOSED = 3;
262574
+ #socket = null;
262575
+ #state = 0;
262576
+ #url;
262577
+ #closeRequested = null;
262578
+ #terminated = false;
262579
+ #listeners = new Map();
262580
+ constructor(address, protocols, options) {
262581
+ if (protocols && typeof protocols === "object" && !Array.isArray(protocols)) {
262582
+ options = protocols;
262583
+ protocols = undefined;
262584
+ }
262585
+ this.#url = String(address);
262586
+ const headers = upgradeHeaders(options);
262587
+ if (headers) {
262588
+ this.#upgrade(headers, protocols);
262589
+ } else {
262590
+ this.#attach(new globalThis.WebSocket(this.#url, protocols));
262591
+ }
262592
+ }
262593
+ get readyState() {
262594
+ if (this.#terminated) return 3;
262595
+ return this.#socket ? this.#socket.readyState : this.#state;
262596
+ }
262597
+ get url() { return this.#url; }
262598
+ get protocol() { return this.#socket ? this.#socket.protocol ?? "" : ""; }
262599
+ on(name, listener) { return this.#add(name, listener, false); }
262600
+ addListener(name, listener) { return this.#add(name, listener, false); }
262601
+ once(name, listener) { return this.#add(name, listener, true); }
262602
+ off(name, listener) { return this.removeListener(name, listener); }
262603
+ removeListener(name, listener) {
262604
+ const listeners = this.#listeners.get(name);
262605
+ if (listeners) this.#listeners.set(name, listeners.filter((entry) => entry.listener !== listener));
262606
+ return this;
262607
+ }
262608
+ removeAllListeners(name) {
262609
+ if (name === undefined) this.#listeners.clear();
262610
+ else this.#listeners.delete(name);
262611
+ return this;
262612
+ }
262613
+ emit(name, ...args) {
262614
+ const listeners = this.#listeners.get(name) ?? [];
262615
+ this.#listeners.set(name, listeners.filter((entry) => !entry.once));
262616
+ for (const entry of listeners) entry.listener.apply(this, args);
262617
+ return listeners.length > 0;
262618
+ }
262619
+ send(data, options, callback) {
262620
+ const done = typeof options === "function" ? options : callback;
262621
+ try {
262622
+ if (!this.#socket) {
262623
+ throw new Error("WebSocket is not open: readyState " + this.#state + " (" + READY_STATES[this.#state] + ")");
262624
+ }
262625
+ this.#socket.send(data);
262626
+ done?.();
262627
+ } catch (error) {
262628
+ if (!done) throw error;
262629
+ done(error);
262630
+ }
262631
+ }
262632
+ close(code, reason) {
262633
+ if (this.#socket) this.#socket.close(code, reason);
262634
+ else if (this.#state === 0) {
262635
+ // Upgrade still in flight: close as soon as it lands.
262636
+ this.#closeRequested = [code, reason];
262637
+ this.#state = 2;
262638
+ }
262639
+ }
262640
+ // \`ws\` tears the connection down at once. workerd has no abrupt close, so the
262641
+ // socket is closed normally and "close" is reported now, not on the reply.
262642
+ terminate() {
262643
+ if (this.#terminated || this.readyState === 3) return;
262644
+ this.#terminated = true;
262645
+ if (this.#socket) {
262646
+ try { this.#socket.close(); } catch {}
262647
+ } else {
262648
+ // Upgrade still in flight: close it on arrival, without an "open".
262649
+ this.#closeRequested = [];
262650
+ this.#state = 3;
262651
+ }
262652
+ later(() => this.emit("close", 1006, toBuffer("")));
262653
+ }
262654
+ #attach(socket) {
262655
+ this.#socket = socket;
262656
+ try { socket.binaryType = "arraybuffer"; } catch {}
262657
+ socket.addEventListener("open", () => this.emit("open"));
262658
+ socket.addEventListener("message", (event) => {
262659
+ const isBinary = typeof event.data !== "string";
262660
+ this.emit("message", toBuffer(isBinary ? new Uint8Array(event.data) : event.data), isBinary);
262661
+ });
262662
+ socket.addEventListener("error", (event) => this.emit("error", event.error ?? new Error(event.message || "WebSocket error")));
262663
+ socket.addEventListener("close", (event) => {
262664
+ if (!this.#terminated) this.emit("close", event.code, toBuffer(event.reason ?? ""));
262665
+ });
262666
+ }
262667
+ #upgrade(headers, protocols) {
262668
+ headers.set("Upgrade", "websocket");
262669
+ if (protocols) headers.set("Sec-WebSocket-Protocol", [].concat(protocols).join(", "));
262670
+ const httpUrl = this.#url.replace(/^ws(s?):/i, "http$1:");
262671
+ const fail = (error) => {
262672
+ this.#state = 3;
262673
+ if (this.#terminated) return;
262674
+ this.emit("error", error);
262675
+ this.emit("close", 1006, toBuffer(""));
262676
+ };
262677
+ // Two-argument then(): an exception from an "open" listener must not be
262678
+ // reported as a failed upgrade.
262679
+ fetch(httpUrl, { headers }).then((response) => {
262680
+ const socket = response.webSocket;
262681
+ if (!socket) {
262682
+ response.body?.cancel();
262683
+ return fail(new Error("Unexpected server response: " + response.status));
262684
+ }
262685
+ socket.accept();
262686
+ this.#attach(socket);
262687
+ if (this.#closeRequested) return socket.close(...this.#closeRequested);
262688
+ // accept() opens the socket without dispatching an "open" event.
262689
+ this.emit("open");
262690
+ }, fail);
262691
+ }
262692
+ #add(name, listener, once) {
262693
+ const listeners = this.#listeners.get(name) ?? [];
262694
+ listeners.push({ listener, once });
262695
+ this.#listeners.set(name, listeners);
262696
+ return this;
262697
+ }
262698
+ }
262699
+ class WebSocketServer {
262700
+ constructor() {
262701
+ throw new Error("ws WebSocketServer is not available in Base44 functions: a function can open WebSocket connections but cannot listen for them.");
262702
+ }
262703
+ }
262704
+ module.exports = WebSocket;
262705
+ module.exports.WebSocket = WebSocket;
262706
+ module.exports.WebSocketServer = WebSocketServer;
262707
+ module.exports.default = WebSocket;
262708
+ `;
262709
+ function wsNativeVirtualPlugin() {
262710
+ return {
262711
+ name: "base44-ws-native",
262712
+ setup(build) {
262713
+ build.onResolve({ filter: WS_SPECIFIER }, () => ({
262714
+ path: "ws",
262715
+ namespace: NAMESPACE4
262716
+ }));
262717
+ build.onLoad({ filter: /.*/, namespace: NAMESPACE4 }, () => ({
262718
+ contents: ADAPTER,
262719
+ loader: "js"
262720
+ }));
262721
+ }
262722
+ };
262723
+ }
262724
+
262493
262725
  // ../functions-compiler/src/deno-bundle.ts
262494
262726
  async function bundleToModule(prepared, nodeModulesDir = "none") {
262495
262727
  const dir = await mkdtemp(path21.join(tmpdir2(), "b44-bundle-"));
@@ -262513,6 +262745,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
262513
262745
  sourcemap: false,
262514
262746
  logLevel: "silent",
262515
262747
  plugins: [
262748
+ wsNativeVirtualPlugin(),
262516
262749
  nodeBuiltinRequirePlugin(),
262517
262750
  userFilesPlugin(prepared.files, prepared.entry),
262518
262751
  privateDataSourcesVirtualPlugin(),
@@ -272902,4 +273135,4 @@ export {
272902
273135
  runCLI
272903
273136
  };
272904
273137
 
272905
- //# debugId=FA1E97B3DE15B20C64756E2164756E21
273138
+ //# debugId=6956BED77F56E7A964756E2164756E21