@base44-preview/cli 0.0.32-pr.249.d9e0ae0 → 0.0.32-pr.249.f0fa2ca

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 base44
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/cli/index.js CHANGED
@@ -186785,12 +186785,12 @@ var BANNER_LINES = [
186785
186785
  "██████╔╝██║ ██║███████║███████╗ ██║ ██║",
186786
186786
  "╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
186787
186787
  ];
186788
- async function printBanner() {
186789
- if (process.stdout.isTTY) {
186790
- await printAnimatedLines(BANNER_LINES);
186791
- } else {
186788
+ async function printBanner(isNonInteractive) {
186789
+ if (isNonInteractive) {
186792
186790
  console.log(theme.colors.base44Orange(BANNER_LINES.join(`
186793
186791
  `)));
186792
+ } else {
186793
+ await printAnimatedLines(BANNER_LINES);
186794
186794
  }
186795
186795
  }
186796
186796
  // src/cli/errors.ts
@@ -193495,7 +193495,7 @@ var package_default = {
193495
193495
  "command-line"
193496
193496
  ],
193497
193497
  author: "",
193498
- license: "ISC",
193498
+ license: "MIT",
193499
193499
  repository: {
193500
193500
  type: "git",
193501
193501
  url: "https://github.com/base44/cli"
@@ -193595,7 +193595,7 @@ async function printUpgradeNotificationIfAvailable() {
193595
193595
  async function runCommand(commandFn, options, context) {
193596
193596
  console.log();
193597
193597
  if (options?.fullBanner) {
193598
- await printBanner();
193598
+ await printBanner(context.isNonInteractive);
193599
193599
  Ie("");
193600
193600
  } else {
193601
193601
  Ie(theme.colors.base44OrangeBackground(" Base 44 "));
@@ -194525,7 +194525,7 @@ function printSummary(results, oauthOutcomes) {
194525
194525
  M2.error(`Failed: ${r2.type}${r2.error ? ` - ${r2.error}` : ""}`);
194526
194526
  }
194527
194527
  }
194528
- async function pushConnectorsAction() {
194528
+ async function pushConnectorsAction(isNonInteractive) {
194529
194529
  const { connectors } = await readProjectConfig();
194530
194530
  if (connectors.length === 0) {
194531
194531
  M2.info("No local connectors found - checking for remote connectors to remove");
@@ -194539,18 +194539,18 @@ async function pushConnectorsAction() {
194539
194539
  const needsOAuth = filterPendingOAuth(results);
194540
194540
  let outroMessage = "Connectors pushed to Base44";
194541
194541
  const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
194542
- skipPrompt: !!process.env.CI
194542
+ skipPrompt: isNonInteractive
194543
194543
  });
194544
194544
  const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
194545
194545
  if (needsOAuth.length > 0 && !allAuthorized) {
194546
- outroMessage = process.env.CI ? "Skipped OAuth in CI. Run 'base44 connectors push' locally or open the links above to authorize." : "Some connectors still require authorization. Run 'base44 connectors push' or open the links above to authorize.";
194546
+ outroMessage = isNonInteractive ? "Skipped OAuth in non-interactive mode. Run 'base44 connectors push' locally or open the links above to authorize." : "Some connectors still require authorization. Run 'base44 connectors push' or open the links above to authorize.";
194547
194547
  }
194548
194548
  printSummary(results, oauthOutcomes);
194549
194549
  return { outroMessage };
194550
194550
  }
194551
194551
  function getConnectorsPushCommand(context) {
194552
194552
  return new Command("push").description("Push local connectors to Base44 (overwrites connectors on Base44)").action(async () => {
194553
- await runCommand(pushConnectorsAction, { requireAuth: true }, context);
194553
+ await runCommand(() => pushConnectorsAction(context.isNonInteractive), { requireAuth: true }, context);
194554
194554
  });
194555
194555
  }
194556
194556
 
@@ -194560,16 +194560,16 @@ function getConnectorsCommand(context) {
194560
194560
  }
194561
194561
 
194562
194562
  // src/cli/commands/dashboard/open.ts
194563
- async function openDashboard() {
194563
+ async function openDashboard(isNonInteractive) {
194564
194564
  const dashboardUrl = getDashboardUrl();
194565
- if (!process.env.CI) {
194565
+ if (!isNonInteractive) {
194566
194566
  await open_default(dashboardUrl);
194567
194567
  }
194568
194568
  return { outroMessage: `Dashboard opened at ${dashboardUrl}` };
194569
194569
  }
194570
194570
  function getDashboardOpenCommand(context) {
194571
194571
  return new Command("open").description("Open the app dashboard in your browser").action(async () => {
194572
- await runCommand(openDashboard, { requireAuth: true }, context);
194572
+ await runCommand(() => openDashboard(context.isNonInteractive), { requireAuth: true }, context);
194573
194573
  });
194574
194574
  }
194575
194575
 
@@ -194875,7 +194875,7 @@ ${summaryLines.join(`
194875
194875
  const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
194876
194876
  if (needsOAuth.length > 0) {
194877
194877
  const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
194878
- skipPrompt: options.yes || !!process.env.CI
194878
+ skipPrompt: options.yes || options.isNonInteractive
194879
194879
  });
194880
194880
  const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
194881
194881
  if (!allAuthorized) {
@@ -194890,7 +194890,10 @@ ${summaryLines.join(`
194890
194890
  }
194891
194891
  function getDeployCommand(context) {
194892
194892
  return new Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
194893
- await runCommand(() => deployAction(options), { requireAuth: true }, context);
194893
+ await runCommand(() => deployAction({
194894
+ ...options,
194895
+ isNonInteractive: context.isNonInteractive
194896
+ }), { requireAuth: true }, context);
194894
194897
  });
194895
194898
  }
194896
194899
 
@@ -195072,21 +195075,24 @@ async function deployAction2(options) {
195072
195075
  }
195073
195076
  function getSiteDeployCommand(context) {
195074
195077
  return new Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
195075
- await runCommand(() => deployAction2(options), { requireAuth: true }, context);
195078
+ await runCommand(() => deployAction2({
195079
+ ...options,
195080
+ isNonInteractive: context.isNonInteractive
195081
+ }), { requireAuth: true }, context);
195076
195082
  });
195077
195083
  }
195078
195084
 
195079
195085
  // src/cli/commands/site/open.ts
195080
- async function openAction() {
195086
+ async function openAction(isNonInteractive) {
195081
195087
  const siteUrl = await getSiteUrl();
195082
- if (!process.env.CI) {
195088
+ if (!isNonInteractive) {
195083
195089
  await open_default(siteUrl);
195084
195090
  }
195085
195091
  return { outroMessage: `Site opened at ${siteUrl}` };
195086
195092
  }
195087
195093
  function getSiteOpenCommand(context) {
195088
195094
  return new Command("open").description("Open the published site in your browser").action(async () => {
195089
- await runCommand(openAction, { requireAuth: true }, context);
195095
+ await runCommand(() => openAction(context.isNonInteractive), { requireAuth: true }, context);
195090
195096
  });
195091
195097
  }
195092
195098
 
@@ -195346,49 +195352,20 @@ async function getPorts(options8) {
195346
195352
  }
195347
195353
 
195348
195354
  // src/cli/dev/dev-server/main.ts
195349
- var import_http_proxy_middleware = __toESM(require_dist2(), 1);
195355
+ var import_http_proxy_middleware2 = __toESM(require_dist2(), 1);
195350
195356
 
195351
195357
  // src/cli/dev/createDevLogger.ts
195352
- var dateTimeFormat = new Intl.DateTimeFormat([], {
195353
- hour: "2-digit",
195354
- minute: "2-digit",
195355
- second: "2-digit",
195356
- hour12: false
195357
- });
195358
195358
  var colorByType = {
195359
195359
  error: theme.styles.error,
195360
195360
  warn: theme.styles.warn,
195361
195361
  log: (text) => text
195362
195362
  };
195363
- function createDevLogger(isPrefixed = true) {
195363
+ function createDevLogger() {
195364
195364
  const print = (type, msg) => {
195365
195365
  const colorize = colorByType[type];
195366
- switch (type) {
195367
- case "error":
195368
- console.error(colorize(msg));
195369
- break;
195370
- case "warn":
195371
- console.warn(colorize(msg));
195372
- break;
195373
- default:
195374
- console.log(msg);
195375
- }
195376
- };
195377
- const prefixedLog = (type, msg) => {
195378
- const timestamp = dateTimeFormat.format(new Date);
195379
- const colorize = colorByType[type];
195380
- console.log(`${theme.styles.dim(timestamp)} ${colorize(msg)}`);
195366
+ console[type](colorize(msg));
195381
195367
  };
195382
- return isPrefixed ? {
195383
- log: (msg) => prefixedLog("log", msg),
195384
- error: (msg, err) => {
195385
- prefixedLog("error", msg);
195386
- if (err) {
195387
- prefixedLog("error", String(err));
195388
- }
195389
- },
195390
- warn: (msg) => prefixedLog("warn", msg)
195391
- } : {
195368
+ return {
195392
195369
  log: (msg) => print("log", msg),
195393
195370
  error: (msg, err) => {
195394
195371
  print("error", msg);
@@ -195411,17 +195388,15 @@ var READY_TIMEOUT = 30000;
195411
195388
  class FunctionManager {
195412
195389
  functions;
195413
195390
  running = new Map;
195391
+ starting = new Map;
195414
195392
  logger;
195415
195393
  constructor(functions, logger) {
195416
195394
  this.functions = new Map(functions.map((f7) => [f7.name, f7]));
195417
195395
  this.logger = logger;
195418
195396
  }
195419
- functionNames() {
195397
+ getFunctionNames() {
195420
195398
  return Array.from(this.functions.keys());
195421
195399
  }
195422
- getFunction(name2) {
195423
- return this.functions.get(name2);
195424
- }
195425
195400
  verifyDenoIsInstalled() {
195426
195401
  if (this.functions.size > 0) {
195427
195402
  const result = spawnSync2("deno", ["--version"]);
@@ -195433,19 +195408,29 @@ class FunctionManager {
195433
195408
  }
195434
195409
  }
195435
195410
  async ensureRunning(name2) {
195436
- const existing = this.running.get(name2);
195437
- if (existing?.ready) {
195438
- return existing.port;
195439
- }
195440
195411
  const backendFunction = this.functions.get(name2);
195441
195412
  if (!backendFunction) {
195442
195413
  throw new InvalidInputError(`Function "${name2}" not found`, {
195443
195414
  hints: [{ message: "Check available functions in your project" }]
195444
195415
  });
195445
195416
  }
195446
- if (existing && !existing.ready) {
195447
- return this.waitForReady(name2, existing);
195417
+ const existing = this.running.get(name2);
195418
+ if (existing?.ready) {
195419
+ return existing.port;
195420
+ }
195421
+ const pending = this.starting.get(name2);
195422
+ if (pending) {
195423
+ return pending;
195448
195424
  }
195425
+ const promise2 = this.startFunction(name2, backendFunction);
195426
+ this.starting.set(name2, promise2);
195427
+ try {
195428
+ return await promise2;
195429
+ } finally {
195430
+ this.starting.delete(name2);
195431
+ }
195432
+ }
195433
+ async startFunction(name2, backendFunction) {
195449
195434
  const port = await this.allocatePort();
195450
195435
  const process21 = this.spawnFunction(backendFunction, port);
195451
195436
  const runningFunc = {
@@ -195457,16 +195442,13 @@ class FunctionManager {
195457
195442
  this.setupProcessHandlers(name2, process21);
195458
195443
  return this.waitForReady(name2, runningFunc);
195459
195444
  }
195460
- getPort(name2) {
195461
- const running = this.running.get(name2);
195462
- return running?.ready ? running.port : undefined;
195463
- }
195464
195445
  stopAll() {
195465
195446
  for (const [name2, { process: process21 }] of this.running) {
195466
195447
  this.logger.log(`[dev-server] Stopping function: ${name2}`);
195467
195448
  process21.kill();
195468
195449
  }
195469
195450
  this.running.clear();
195451
+ this.starting.clear();
195470
195452
  }
195471
195453
  stop(name2) {
195472
195454
  const running = this.running.get(name2);
@@ -195519,7 +195501,16 @@ class FunctionManager {
195519
195501
  }
195520
195502
  waitForReady(name2, runningFunc) {
195521
195503
  return new Promise((resolve5, reject) => {
195504
+ runningFunc.process.on("exit", (code2) => {
195505
+ if (!runningFunc.ready) {
195506
+ clearTimeout(timeout3);
195507
+ reject(new InternalError(`Function "${name2}" exited with code ${code2}`, {
195508
+ hints: [{ message: "Check the function code for errors" }]
195509
+ }));
195510
+ }
195511
+ });
195522
195512
  const timeout3 = setTimeout(() => {
195513
+ runningFunc.process.kill();
195523
195514
  reject(new InternalError(`Function "${name2}" failed to start within ${READY_TIMEOUT / 1000}s timeout`, {
195524
195515
  hints: [
195525
195516
  { message: "Check the function code for startup errors" }
@@ -195536,88 +195527,54 @@ class FunctionManager {
195536
195527
  }
195537
195528
  };
195538
195529
  runningFunc.process.stdout?.on("data", onData);
195539
- runningFunc.process.on("exit", (code2) => {
195540
- if (!runningFunc.ready) {
195541
- clearTimeout(timeout3);
195542
- reject(new InternalError(`Function "${name2}" exited with code ${code2}`, {
195543
- hints: [{ message: "Check the function code for errors" }]
195544
- }));
195545
- }
195546
- });
195547
195530
  });
195548
195531
  }
195549
195532
  }
195550
195533
 
195551
195534
  // src/cli/dev/dev-server/routes/functions.ts
195552
195535
  var import_express = __toESM(require_express(), 1);
195553
- import { request as httpRequest } from "node:http";
195554
- function createFunctionRoutes(manager, logger) {
195536
+ var import_http_proxy_middleware = __toESM(require_dist2(), 1);
195537
+ import { ServerResponse } from "node:http";
195538
+ function createFunctionRouter(manager, logger) {
195555
195539
  const router = import_express.Router({ mergeParams: true });
195556
- router.all("/:functionName", async (req, res) => {
195540
+ const portsByRequest = new WeakMap;
195541
+ const proxy = import_http_proxy_middleware.createProxyMiddleware({
195542
+ router: (req) => `http://localhost:${portsByRequest.get(req)}`,
195543
+ changeOrigin: true,
195544
+ on: {
195545
+ proxyReq: (proxyReq, req) => {
195546
+ const xAppId = req.headers["x-app-id"];
195547
+ if (xAppId) {
195548
+ proxyReq.setHeader("Base44-App-Id", xAppId);
195549
+ }
195550
+ proxyReq.setHeader("Base44-Api-Url", `${req.protocol}://${req.headers.host}`);
195551
+ },
195552
+ error: (err, _req, res) => {
195553
+ logger.error("Function proxy error:", err);
195554
+ if (res instanceof ServerResponse && !res.headersSent) {
195555
+ res.writeHead(502, { "Content-Type": "application/json" });
195556
+ res.end(JSON.stringify({
195557
+ error: "Failed to proxy request to function",
195558
+ details: err.message
195559
+ }));
195560
+ }
195561
+ }
195562
+ }
195563
+ });
195564
+ router.all("/:functionName", async (req, res, next) => {
195557
195565
  const { functionName } = req.params;
195558
195566
  try {
195559
- const func = manager.getFunction(functionName);
195560
- if (!func) {
195561
- res.status(404).json({
195562
- error: `Function "${functionName}" not found`
195563
- });
195564
- return;
195565
- }
195566
195567
  const port = await manager.ensureRunning(functionName);
195567
- await proxyRequest(req, res, port, logger);
195568
+ portsByRequest.set(req, port);
195569
+ next();
195568
195570
  } catch (error48) {
195569
- logger.error(`Function error:`, error48);
195571
+ logger.error("Function error:", error48);
195570
195572
  const message = error48 instanceof Error ? error48.message : String(error48);
195571
195573
  res.status(500).json({ error: message });
195572
195574
  }
195573
- });
195575
+ }, proxy);
195574
195576
  return router;
195575
195577
  }
195576
- function proxyRequest(req, res, port, logger) {
195577
- return new Promise((resolve5, reject) => {
195578
- const headers = {
195579
- ...req.headers
195580
- };
195581
- delete headers.host;
195582
- if (headers["x-app-id"]) {
195583
- headers["Base44-App-Id"] = headers["x-app-id"];
195584
- }
195585
- headers["Base44-Api-Url"] = `${req.protocol}://${req.get("host")}`;
195586
- const options8 = {
195587
- hostname: "localhost",
195588
- port,
195589
- path: req.url,
195590
- method: req.method,
195591
- headers
195592
- };
195593
- const proxyReq = httpRequest(options8, (proxyRes) => {
195594
- res.status(proxyRes.statusCode || 200);
195595
- for (const [key2, value] of Object.entries(proxyRes.headers)) {
195596
- if (value !== undefined) {
195597
- res.setHeader(key2, value);
195598
- }
195599
- }
195600
- proxyRes.pipe(res);
195601
- proxyRes.on("end", () => {
195602
- resolve5();
195603
- });
195604
- proxyRes.on("error", (error48) => {
195605
- reject(error48);
195606
- });
195607
- });
195608
- proxyReq.on("error", (error48) => {
195609
- logger.error(`Function proxy error:`, error48);
195610
- if (!res.headersSent) {
195611
- res.status(502).json({
195612
- error: "Failed to proxy request to function",
195613
- details: error48.message
195614
- });
195615
- }
195616
- resolve5();
195617
- });
195618
- req.pipe(proxyReq);
195619
- });
195620
- }
195621
195578
 
195622
195579
  // src/cli/dev/dev-server/main.ts
195623
195580
  var DEFAULT_PORT = 4400;
@@ -195628,7 +195585,7 @@ async function createDevServer(options8) {
195628
195585
  const { project: project2 } = await readProjectConfig();
195629
195586
  const configDir = dirname12(project2.configPath);
195630
195587
  const app = import_express2.default();
195631
- const remoteProxy = import_http_proxy_middleware.createProxyMiddleware({
195588
+ const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
195632
195589
  target: BASE44_APP_URL,
195633
195590
  changeOrigin: true
195634
195591
  });
@@ -195645,13 +195602,13 @@ async function createDevServer(options8) {
195645
195602
  next();
195646
195603
  });
195647
195604
  const functions = await functionResource.readAll(join16(configDir, project2.functionsDir));
195648
- const devLogger = createDevLogger(false);
195605
+ const devLogger = createDevLogger();
195649
195606
  const functionManager = new FunctionManager(functions, devLogger);
195650
195607
  functionManager.verifyDenoIsInstalled();
195651
- if (functionManager.functionNames().length > 0) {
195652
- M2.info(`Loaded functions: ${functionManager.functionNames().join(", ")}`);
195608
+ if (functionManager.getFunctionNames().length > 0) {
195609
+ M2.info(`Loaded functions: ${functionManager.getFunctionNames().join(", ")}`);
195653
195610
  }
195654
- const functionRoutes = createFunctionRoutes(functionManager, devLogger);
195611
+ const functionRoutes = createFunctionRouter(functionManager, devLogger);
195655
195612
  app.use("/api/apps/:appId/functions", functionRoutes);
195656
195613
  app.use((req, res, next) => {
195657
195614
  return remoteProxy(req, res, next);
@@ -195783,7 +195740,7 @@ async function eject(options8) {
195783
195740
  }
195784
195741
  function getEjectCommand(context) {
195785
195742
  return new Command("eject").description("Download the code for an existing Base44 project").option("-p, --path <path>", "Path where to write the project").option("--project-id <id>", "Project ID to eject (skips interactive selection)").option("-y, --yes", "Skip confirmation prompts").action(async (options8) => {
195786
- await runCommand(() => eject(options8), { requireAuth: true, requireAppConfig: false }, context);
195743
+ await runCommand(() => eject({ ...options8, isNonInteractive: context.isNonInteractive }), { requireAuth: true, requireAppConfig: false }, context);
195787
195744
  });
195788
195745
  }
195789
195746
 
@@ -200050,7 +200007,8 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
200050
200007
  async function runCLI() {
200051
200008
  const errorReporter = new ErrorReporter;
200052
200009
  errorReporter.registerProcessErrorHandlers();
200053
- const context = { errorReporter };
200010
+ const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
200011
+ const context = { errorReporter, isNonInteractive };
200054
200012
  const program2 = createProgram(context);
200055
200013
  try {
200056
200014
  const userInfo = await readAuth();
@@ -200075,4 +200033,4 @@ export {
200075
200033
  CLIExitError
200076
200034
  };
200077
200035
 
200078
- //# debugId=C673BE16F37436A364756E2164756E21
200036
+ //# debugId=B4C79353BCDBC07064756E2164756E21