@base44-preview/cli 0.0.32-pr.248.70443e1 → 0.0.32-pr.249.063e424

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/cli/index.js CHANGED
@@ -178102,6 +178102,18 @@ class InvalidInputError extends UserError {
178102
178102
  code = "INVALID_INPUT";
178103
178103
  }
178104
178104
 
178105
+ class DependencyNotFoundError extends UserError {
178106
+ code = "DEPENDENCY_NOT_FOUND";
178107
+ constructor(message, options) {
178108
+ super(message, {
178109
+ hints: options?.hints ?? [
178110
+ { message: "Install the required dependency and try again" }
178111
+ ],
178112
+ cause: options?.cause
178113
+ });
178114
+ }
178115
+ }
178116
+
178105
178117
  class ApiError extends SystemError {
178106
178118
  code = "API_ERROR";
178107
178119
  statusCode;
@@ -178217,6 +178229,21 @@ class FileReadError extends SystemError {
178217
178229
  });
178218
178230
  }
178219
178231
  }
178232
+
178233
+ class InternalError extends SystemError {
178234
+ code = "INTERNAL_ERROR";
178235
+ constructor(message, options) {
178236
+ super(message, {
178237
+ hints: options?.hints ?? [
178238
+ {
178239
+ message: "This is an unexpected error. Please report it if it persists."
178240
+ }
178241
+ ],
178242
+ cause: options?.cause
178243
+ });
178244
+ }
178245
+ }
178246
+
178220
178247
  class TypeGenerationError extends SystemError {
178221
178248
  code = "TYPE_GENERATION_ERROR";
178222
178249
  entityName;
@@ -185051,6 +185078,10 @@ var TikTokConnectorSchema = exports_external.object({
185051
185078
  type: exports_external.literal("tiktok"),
185052
185079
  scopes: exports_external.array(exports_external.string()).default([])
185053
185080
  });
185081
+ var GoogleBigQueryConnectorSchema = exports_external.object({
185082
+ type: exports_external.literal("googlebigquery"),
185083
+ scopes: exports_external.array(exports_external.string()).default([])
185084
+ });
185054
185085
  var CustomTypeSchema = exports_external.string().min(1).regex(/^[a-z0-9_-]+$/i);
185055
185086
  var GenericConnectorSchema = exports_external.object({
185056
185087
  type: CustomTypeSchema,
@@ -185063,6 +185094,7 @@ var ConnectorResourceSchema = exports_external.union([
185063
185094
  GoogleSheetsConnectorSchema,
185064
185095
  GoogleDocsConnectorSchema,
185065
185096
  GoogleSlidesConnectorSchema,
185097
+ GoogleBigQueryConnectorSchema,
185066
185098
  SlackConnectorSchema,
185067
185099
  NotionConnectorSchema,
185068
185100
  SalesforceConnectorSchema,
@@ -185078,6 +185110,7 @@ var KnownIntegrationTypes = [
185078
185110
  "googlesheets",
185079
185111
  "googledocs",
185080
185112
  "googleslides",
185113
+ "googlebigquery",
185081
185114
  "slack",
185082
185115
  "notion",
185083
185116
  "salesforce",
@@ -185340,7 +185373,10 @@ var connectorResource = {
185340
185373
  // src/core/resources/entity/schema.ts
185341
185374
  var FieldConditionSchema = exports_external.union([
185342
185375
  exports_external.string(),
185343
- exports_external.object({
185376
+ exports_external.number(),
185377
+ exports_external.boolean(),
185378
+ exports_external.null(),
185379
+ exports_external.looseObject({
185344
185380
  $in: exports_external.unknown().optional(),
185345
185381
  $nin: exports_external.unknown().optional(),
185346
185382
  $ne: exports_external.unknown().optional(),
@@ -185357,6 +185393,15 @@ var rlsConditionAllowedKeys = new Set([
185357
185393
  "user_condition",
185358
185394
  "created_by",
185359
185395
  "created_by_id",
185396
+ "id",
185397
+ "_id",
185398
+ "created_date",
185399
+ "updated_date",
185400
+ "app_id",
185401
+ "entity_name",
185402
+ "is_deleted",
185403
+ "deleted_date",
185404
+ "environment",
185360
185405
  "$or",
185361
185406
  "$and",
185362
185407
  "$nor"
@@ -185385,60 +185430,33 @@ var isValidFieldCondition = (value) => {
185385
185430
  }
185386
185431
  return false;
185387
185432
  };
185388
- var RefineRLSConditionSchema = RLSConditionSchema.refine((val) => Object.entries(val).every(([key, value]) => {
185389
- if (rlsConditionAllowedKeys.has(key)) {
185390
- return true;
185391
- }
185392
- if (!key.startsWith("data.")) {
185393
- return false;
185394
- }
185395
- return isValidFieldCondition(value);
185396
- }), "Keys must be known RLS keys or match data.* pattern with valid value");
185433
+ var RefineRLSConditionSchema = RLSConditionSchema.refine((val) => Object.entries(val).every(([key, value]) => rlsConditionAllowedKeys.has(key) || isValidFieldCondition(value)), "Field condition values must be a primitive or an operator object ($in, $nin, $ne, $all)");
185397
185434
  var RLSRuleSchema = exports_external.union([exports_external.boolean(), RefineRLSConditionSchema]);
185398
- var EntityRLSSchema = exports_external.strictObject({
185435
+ var EntityRLSSchema = exports_external.looseObject({
185399
185436
  create: RLSRuleSchema.optional(),
185400
185437
  read: RLSRuleSchema.optional(),
185401
185438
  update: RLSRuleSchema.optional(),
185402
185439
  delete: RLSRuleSchema.optional(),
185403
185440
  write: RLSRuleSchema.optional()
185404
185441
  });
185405
- var FieldRLSSchema = exports_external.strictObject({
185442
+ var FieldRLSSchema = exports_external.looseObject({
185406
185443
  read: RLSRuleSchema.optional(),
185407
185444
  write: RLSRuleSchema.optional(),
185408
185445
  create: RLSRuleSchema.optional(),
185409
185446
  update: RLSRuleSchema.optional(),
185410
185447
  delete: RLSRuleSchema.optional()
185411
185448
  });
185412
- var PropertyTypeSchema = exports_external.enum([
185413
- "string",
185414
- "number",
185415
- "integer",
185416
- "boolean",
185417
- "array",
185418
- "object"
185419
- ]);
185420
- var StringFormatSchema = exports_external.enum([
185421
- "date",
185422
- "date-time",
185423
- "time",
185424
- "email",
185425
- "uri",
185426
- "hostname",
185427
- "ipv4",
185428
- "ipv6",
185429
- "uuid"
185430
- ]);
185431
- var PropertyDefinitionSchema = exports_external.object({
185432
- type: PropertyTypeSchema,
185449
+ var PropertyDefinitionSchema = exports_external.looseObject({
185450
+ type: exports_external.string().optional(),
185433
185451
  title: exports_external.string().optional(),
185434
185452
  description: exports_external.string().optional(),
185435
185453
  minLength: exports_external.number().int().min(0).optional(),
185436
185454
  maxLength: exports_external.number().int().min(0).optional(),
185437
185455
  pattern: exports_external.string().optional(),
185438
- format: StringFormatSchema.optional(),
185456
+ format: exports_external.string().optional(),
185439
185457
  minimum: exports_external.number().optional(),
185440
185458
  maximum: exports_external.number().optional(),
185441
- enum: exports_external.array(exports_external.string()).optional(),
185459
+ enum: exports_external.array(exports_external.unknown()).optional(),
185442
185460
  enumNames: exports_external.array(exports_external.string()).optional(),
185443
185461
  default: exports_external.unknown().optional(),
185444
185462
  $ref: exports_external.string().optional(),
@@ -185451,12 +185469,12 @@ var PropertyDefinitionSchema = exports_external.object({
185451
185469
  return exports_external.record(exports_external.string(), PropertyDefinitionSchema).optional();
185452
185470
  }
185453
185471
  });
185454
- var EntitySchema = exports_external.object({
185455
- type: exports_external.literal("object"),
185456
- name: exports_external.string().regex(/^[a-zA-Z0-9]+$/, "Entity name must be alphanumeric only"),
185472
+ var EntitySchema = exports_external.looseObject({
185473
+ type: exports_external.literal("object").default("object"),
185474
+ name: exports_external.string().min(1).regex(/^[a-zA-Z0-9]+$/, "Entity name must be alphanumeric only"),
185457
185475
  title: exports_external.string().optional(),
185458
185476
  description: exports_external.string().optional(),
185459
- properties: exports_external.record(exports_external.string(), PropertyDefinitionSchema),
185477
+ properties: exports_external.record(exports_external.string(), PropertyDefinitionSchema).default({}),
185460
185478
  required: exports_external.array(exports_external.string()).optional(),
185461
185479
  rls: EntityRLSSchema.optional()
185462
185480
  });
@@ -186024,7 +186042,7 @@ async function handleUnauthorized(request, _options, response) {
186024
186042
  return;
186025
186043
  }
186026
186044
  retriedRequests.add(request);
186027
- return distribution_default(request, {
186045
+ return distribution_default(request.clone(), {
186028
186046
  headers: { Authorization: `Bearer ${newAccessToken}` }
186029
186047
  });
186030
186048
  }
@@ -186663,7 +186681,9 @@ var theme = {
186663
186681
  styles: {
186664
186682
  header: source_default.dim,
186665
186683
  bold: source_default.bold,
186666
- dim: source_default.dim
186684
+ dim: source_default.dim,
186685
+ error: source_default.red,
186686
+ warn: source_default.yellow
186667
186687
  },
186668
186688
  format: {
186669
186689
  errorContext(ctx) {
@@ -186765,12 +186785,12 @@ var BANNER_LINES = [
186765
186785
  "██████╔╝██║ ██║███████║███████╗ ██║ ██║",
186766
186786
  "╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
186767
186787
  ];
186768
- async function printBanner() {
186769
- if (process.stdout.isTTY) {
186770
- await printAnimatedLines(BANNER_LINES);
186771
- } else {
186788
+ async function printBanner(isNonInteractive) {
186789
+ if (isNonInteractive) {
186772
186790
  console.log(theme.colors.base44Orange(BANNER_LINES.join(`
186773
186791
  `)));
186792
+ } else {
186793
+ await printAnimatedLines(BANNER_LINES);
186774
186794
  }
186775
186795
  }
186776
186796
  // src/cli/errors.ts
@@ -193486,6 +193506,7 @@ var package_default = {
193486
193506
  "@types/bun": "^1.2.15",
193487
193507
  "@types/common-tags": "^1.8.4",
193488
193508
  "@types/cors": "^2.8.19",
193509
+ "@types/deno": "^2.5.0",
193489
193510
  "@types/ejs": "^3.1.5",
193490
193511
  "@types/express": "^5.0.6",
193491
193512
  "@types/json-schema": "^7.0.15",
@@ -193574,7 +193595,7 @@ async function printUpgradeNotificationIfAvailable() {
193574
193595
  async function runCommand(commandFn, options, context) {
193575
193596
  console.log();
193576
193597
  if (options?.fullBanner) {
193577
- await printBanner();
193598
+ await printBanner(context.isNonInteractive);
193578
193599
  Ie("");
193579
193600
  } else {
193580
193601
  Ie(theme.colors.base44OrangeBackground(" Base 44 "));
@@ -194504,7 +194525,7 @@ function printSummary(results, oauthOutcomes) {
194504
194525
  M2.error(`Failed: ${r2.type}${r2.error ? ` - ${r2.error}` : ""}`);
194505
194526
  }
194506
194527
  }
194507
- async function pushConnectorsAction() {
194528
+ async function pushConnectorsAction(isNonInteractive) {
194508
194529
  const { connectors } = await readProjectConfig();
194509
194530
  if (connectors.length === 0) {
194510
194531
  M2.info("No local connectors found - checking for remote connectors to remove");
@@ -194518,18 +194539,18 @@ async function pushConnectorsAction() {
194518
194539
  const needsOAuth = filterPendingOAuth(results);
194519
194540
  let outroMessage = "Connectors pushed to Base44";
194520
194541
  const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
194521
- skipPrompt: !!process.env.CI
194542
+ skipPrompt: isNonInteractive
194522
194543
  });
194523
194544
  const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
194524
194545
  if (needsOAuth.length > 0 && !allAuthorized) {
194525
- 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.";
194526
194547
  }
194527
194548
  printSummary(results, oauthOutcomes);
194528
194549
  return { outroMessage };
194529
194550
  }
194530
194551
  function getConnectorsPushCommand(context) {
194531
194552
  return new Command("push").description("Push local connectors to Base44 (overwrites connectors on Base44)").action(async () => {
194532
- await runCommand(pushConnectorsAction, { requireAuth: true }, context);
194553
+ await runCommand(() => pushConnectorsAction(context.isNonInteractive), { requireAuth: true }, context);
194533
194554
  });
194534
194555
  }
194535
194556
 
@@ -194539,16 +194560,16 @@ function getConnectorsCommand(context) {
194539
194560
  }
194540
194561
 
194541
194562
  // src/cli/commands/dashboard/open.ts
194542
- async function openDashboard() {
194563
+ async function openDashboard(isNonInteractive) {
194543
194564
  const dashboardUrl = getDashboardUrl();
194544
- if (!process.env.CI) {
194565
+ if (!isNonInteractive) {
194545
194566
  await open_default(dashboardUrl);
194546
194567
  }
194547
194568
  return { outroMessage: `Dashboard opened at ${dashboardUrl}` };
194548
194569
  }
194549
194570
  function getDashboardOpenCommand(context) {
194550
194571
  return new Command("open").description("Open the app dashboard in your browser").action(async () => {
194551
- await runCommand(openDashboard, { requireAuth: true }, context);
194572
+ await runCommand(() => openDashboard(context.isNonInteractive), { requireAuth: true }, context);
194552
194573
  });
194553
194574
  }
194554
194575
 
@@ -194854,7 +194875,7 @@ ${summaryLines.join(`
194854
194875
  const needsOAuth = filterPendingOAuth(result.connectorResults ?? []);
194855
194876
  if (needsOAuth.length > 0) {
194856
194877
  const oauthOutcomes = await promptOAuthFlows(needsOAuth, {
194857
- skipPrompt: options.yes || !!process.env.CI
194878
+ skipPrompt: options.yes || options.isNonInteractive
194858
194879
  });
194859
194880
  const allAuthorized = oauthOutcomes.size > 0 && [...oauthOutcomes.values()].every((s) => s === "ACTIVE");
194860
194881
  if (!allAuthorized) {
@@ -194869,7 +194890,10 @@ ${summaryLines.join(`
194869
194890
  }
194870
194891
  function getDeployCommand(context) {
194871
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) => {
194872
- await runCommand(() => deployAction(options), { requireAuth: true }, context);
194893
+ await runCommand(() => deployAction({
194894
+ ...options,
194895
+ isNonInteractive: context.isNonInteractive
194896
+ }), { requireAuth: true }, context);
194873
194897
  });
194874
194898
  }
194875
194899
 
@@ -195051,21 +195075,24 @@ async function deployAction2(options) {
195051
195075
  }
195052
195076
  function getSiteDeployCommand(context) {
195053
195077
  return new Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
195054
- await runCommand(() => deployAction2(options), { requireAuth: true }, context);
195078
+ await runCommand(() => deployAction2({
195079
+ ...options,
195080
+ isNonInteractive: context.isNonInteractive
195081
+ }), { requireAuth: true }, context);
195055
195082
  });
195056
195083
  }
195057
195084
 
195058
195085
  // src/cli/commands/site/open.ts
195059
- async function openAction() {
195086
+ async function openAction(isNonInteractive) {
195060
195087
  const siteUrl = await getSiteUrl();
195061
- if (!process.env.CI) {
195088
+ if (!isNonInteractive) {
195062
195089
  await open_default(siteUrl);
195063
195090
  }
195064
195091
  return { outroMessage: `Site opened at ${siteUrl}` };
195065
195092
  }
195066
195093
  function getSiteOpenCommand(context) {
195067
195094
  return new Command("open").description("Open the published site in your browser").action(async () => {
195068
- await runCommand(openAction, { requireAuth: true }, context);
195095
+ await runCommand(() => openAction(context.isNonInteractive), { requireAuth: true }, context);
195069
195096
  });
195070
195097
  }
195071
195098
 
@@ -195206,8 +195233,9 @@ function getTypesCommand(context) {
195206
195233
  }
195207
195234
 
195208
195235
  // src/cli/dev/dev-server/main.ts
195236
+ import { dirname as dirname12, join as join16 } from "node:path";
195209
195237
  var import_cors = __toESM(require_lib4(), 1);
195210
- var import_express = __toESM(require_express(), 1);
195238
+ var import_express2 = __toESM(require_express(), 1);
195211
195239
 
195212
195240
  // node_modules/get-port/index.js
195213
195241
  import net from "node:net";
@@ -195325,11 +195353,302 @@ async function getPorts(options8) {
195325
195353
 
195326
195354
  // src/cli/dev/dev-server/main.ts
195327
195355
  var import_http_proxy_middleware = __toESM(require_dist2(), 1);
195356
+
195357
+ // src/cli/dev/createDevLogger.ts
195358
+ var dateTimeFormat = new Intl.DateTimeFormat([], {
195359
+ hour: "2-digit",
195360
+ minute: "2-digit",
195361
+ second: "2-digit",
195362
+ hour12: false
195363
+ });
195364
+ var colorByType = {
195365
+ error: theme.styles.error,
195366
+ warn: theme.styles.warn,
195367
+ log: (text) => text
195368
+ };
195369
+ function createDevLogger(isPrefixed = true) {
195370
+ const print = (type, msg) => {
195371
+ const colorize = colorByType[type];
195372
+ switch (type) {
195373
+ case "error":
195374
+ console.error(colorize(msg));
195375
+ break;
195376
+ case "warn":
195377
+ console.warn(colorize(msg));
195378
+ break;
195379
+ default:
195380
+ console.log(msg);
195381
+ }
195382
+ };
195383
+ const prefixedLog = (type, msg) => {
195384
+ const timestamp = dateTimeFormat.format(new Date);
195385
+ const colorize = colorByType[type];
195386
+ console.log(`${theme.styles.dim(timestamp)} ${colorize(msg)}`);
195387
+ };
195388
+ return isPrefixed ? {
195389
+ log: (msg) => prefixedLog("log", msg),
195390
+ error: (msg, err) => {
195391
+ prefixedLog("error", msg);
195392
+ if (err) {
195393
+ prefixedLog("error", String(err));
195394
+ }
195395
+ },
195396
+ warn: (msg) => prefixedLog("warn", msg)
195397
+ } : {
195398
+ log: (msg) => print("log", msg),
195399
+ error: (msg, err) => {
195400
+ print("error", msg);
195401
+ if (err) {
195402
+ print("error", String(err));
195403
+ }
195404
+ },
195405
+ warn: (msg) => print("warn", msg)
195406
+ };
195407
+ }
195408
+
195409
+ // src/cli/dev/dev-server/function-manager.ts
195410
+ import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
195411
+ import { dirname as dirname11, join as join15 } from "node:path";
195412
+ import { fileURLToPath as fileURLToPath7 } from "node:url";
195413
+ var __dirname5 = dirname11(fileURLToPath7(import.meta.url));
195414
+ var WRAPPER_PATH = join15(__dirname5, "../deno-runtime/main.js");
195415
+ var READY_TIMEOUT = 30000;
195416
+
195417
+ class FunctionManager {
195418
+ functions;
195419
+ running = new Map;
195420
+ starting = new Map;
195421
+ logger;
195422
+ constructor(functions, logger) {
195423
+ this.functions = new Map(functions.map((f7) => [f7.name, f7]));
195424
+ this.logger = logger;
195425
+ }
195426
+ functionNames() {
195427
+ return Array.from(this.functions.keys());
195428
+ }
195429
+ getFunction(name2) {
195430
+ return this.functions.get(name2);
195431
+ }
195432
+ verifyDenoIsInstalled() {
195433
+ if (this.functions.size > 0) {
195434
+ const result = spawnSync2("deno", ["--version"]);
195435
+ if (result.error) {
195436
+ throw new DependencyNotFoundError("Deno is required to run functions", {
195437
+ hints: [{ message: "Install Deno from https://deno.com/download" }]
195438
+ });
195439
+ }
195440
+ }
195441
+ }
195442
+ async ensureRunning(name2) {
195443
+ const existing = this.running.get(name2);
195444
+ if (existing?.ready) {
195445
+ return existing.port;
195446
+ }
195447
+ const pending = this.starting.get(name2);
195448
+ if (pending) {
195449
+ return pending;
195450
+ }
195451
+ const backendFunction = this.functions.get(name2);
195452
+ if (!backendFunction) {
195453
+ throw new InvalidInputError(`Function "${name2}" not found`, {
195454
+ hints: [{ message: "Check available functions in your project" }]
195455
+ });
195456
+ }
195457
+ const promise2 = this.startFunction(name2, backendFunction);
195458
+ this.starting.set(name2, promise2);
195459
+ try {
195460
+ return await promise2;
195461
+ } finally {
195462
+ this.starting.delete(name2);
195463
+ }
195464
+ }
195465
+ async startFunction(name2, backendFunction) {
195466
+ const port = await this.allocatePort();
195467
+ const process21 = this.spawnFunction(backendFunction, port);
195468
+ const runningFunc = {
195469
+ process: process21,
195470
+ port,
195471
+ ready: false
195472
+ };
195473
+ this.running.set(name2, runningFunc);
195474
+ this.setupProcessHandlers(name2, process21);
195475
+ return this.waitForReady(name2, runningFunc);
195476
+ }
195477
+ getPort(name2) {
195478
+ const running = this.running.get(name2);
195479
+ return running?.ready ? running.port : undefined;
195480
+ }
195481
+ stopAll() {
195482
+ for (const [name2, { process: process21 }] of this.running) {
195483
+ this.logger.log(`[dev-server] Stopping function: ${name2}`);
195484
+ process21.kill();
195485
+ }
195486
+ this.running.clear();
195487
+ this.starting.clear();
195488
+ }
195489
+ stop(name2) {
195490
+ const running = this.running.get(name2);
195491
+ if (running) {
195492
+ this.logger.log(`Stopping function: ${name2}`);
195493
+ running.process.kill();
195494
+ this.running.delete(name2);
195495
+ }
195496
+ }
195497
+ async allocatePort() {
195498
+ const usedPorts = Array.from(this.running.values()).map((r5) => r5.port);
195499
+ return getPorts({ exclude: usedPorts });
195500
+ }
195501
+ spawnFunction(func, port) {
195502
+ this.logger.log(`[dev-server] Spawning function "${func.name}" on port ${port}`);
195503
+ const process21 = spawn2("deno", ["run", "--allow-all", WRAPPER_PATH], {
195504
+ env: {
195505
+ ...globalThis.process.env,
195506
+ FUNCTION_PATH: func.entryPath,
195507
+ FUNCTION_PORT: String(port),
195508
+ FUNCTION_NAME: func.name
195509
+ },
195510
+ stdio: ["pipe", "pipe", "pipe"]
195511
+ });
195512
+ return process21;
195513
+ }
195514
+ setupProcessHandlers(name2, process21) {
195515
+ process21.stdout?.on("data", (data) => {
195516
+ const lines = data.toString().trim().split(`
195517
+ `);
195518
+ for (const line3 of lines) {
195519
+ this.logger.log(line3);
195520
+ }
195521
+ });
195522
+ process21.stderr?.on("data", (data) => {
195523
+ const lines = data.toString().trim().split(`
195524
+ `);
195525
+ for (const line3 of lines) {
195526
+ this.logger.error(line3);
195527
+ }
195528
+ });
195529
+ process21.on("exit", (code2) => {
195530
+ this.logger.log(`[dev-server] Function "${name2}" exited with code ${code2}`);
195531
+ this.running.delete(name2);
195532
+ });
195533
+ process21.on("error", (error48) => {
195534
+ this.logger.error(`[dev-server] Function "${name2}" error:`, error48);
195535
+ this.running.delete(name2);
195536
+ });
195537
+ }
195538
+ waitForReady(name2, runningFunc) {
195539
+ return new Promise((resolve5, reject) => {
195540
+ const timeout3 = setTimeout(() => {
195541
+ runningFunc.process.kill();
195542
+ reject(new InternalError(`Function "${name2}" failed to start within ${READY_TIMEOUT / 1000}s timeout`, {
195543
+ hints: [
195544
+ { message: "Check the function code for startup errors" }
195545
+ ]
195546
+ }));
195547
+ }, READY_TIMEOUT);
195548
+ const onData = (data) => {
195549
+ const output = data.toString();
195550
+ if (output.includes("Listening on")) {
195551
+ runningFunc.ready = true;
195552
+ clearTimeout(timeout3);
195553
+ runningFunc.process.stdout?.off("data", onData);
195554
+ resolve5(runningFunc.port);
195555
+ }
195556
+ };
195557
+ runningFunc.process.stdout?.on("data", onData);
195558
+ runningFunc.process.on("exit", (code2) => {
195559
+ if (!runningFunc.ready) {
195560
+ clearTimeout(timeout3);
195561
+ reject(new InternalError(`Function "${name2}" exited with code ${code2}`, {
195562
+ hints: [{ message: "Check the function code for errors" }]
195563
+ }));
195564
+ }
195565
+ });
195566
+ });
195567
+ }
195568
+ }
195569
+
195570
+ // src/cli/dev/dev-server/routes/functions.ts
195571
+ var import_express = __toESM(require_express(), 1);
195572
+ import { request as httpRequest } from "node:http";
195573
+ function createFunctionRoutes(manager, logger) {
195574
+ const router = import_express.Router({ mergeParams: true });
195575
+ router.all("/:functionName", async (req, res) => {
195576
+ const { functionName } = req.params;
195577
+ try {
195578
+ const func = manager.getFunction(functionName);
195579
+ if (!func) {
195580
+ res.status(404).json({
195581
+ error: `Function "${functionName}" not found`
195582
+ });
195583
+ return;
195584
+ }
195585
+ const port = await manager.ensureRunning(functionName);
195586
+ await proxyRequest(req, res, port, logger);
195587
+ } catch (error48) {
195588
+ logger.error(`Function error:`, error48);
195589
+ const message = error48 instanceof Error ? error48.message : String(error48);
195590
+ res.status(500).json({ error: message });
195591
+ }
195592
+ });
195593
+ return router;
195594
+ }
195595
+ function proxyRequest(req, res, port, logger) {
195596
+ return new Promise((resolve5, reject) => {
195597
+ const headers = {
195598
+ ...req.headers
195599
+ };
195600
+ delete headers.host;
195601
+ if (headers["x-app-id"]) {
195602
+ headers["Base44-App-Id"] = headers["x-app-id"];
195603
+ }
195604
+ headers["Base44-Api-Url"] = `${req.protocol}://${req.get("host")}`;
195605
+ const options8 = {
195606
+ hostname: "localhost",
195607
+ port,
195608
+ path: req.url,
195609
+ method: req.method,
195610
+ headers
195611
+ };
195612
+ const proxyReq = httpRequest(options8, (proxyRes) => {
195613
+ res.status(proxyRes.statusCode || 200);
195614
+ for (const [key2, value] of Object.entries(proxyRes.headers)) {
195615
+ if (value !== undefined) {
195616
+ res.setHeader(key2, value);
195617
+ }
195618
+ }
195619
+ proxyRes.pipe(res);
195620
+ proxyRes.on("end", () => {
195621
+ resolve5();
195622
+ });
195623
+ proxyRes.on("error", (error48) => {
195624
+ reject(error48);
195625
+ });
195626
+ });
195627
+ proxyReq.on("error", (error48) => {
195628
+ logger.error(`Function proxy error:`, error48);
195629
+ if (!res.headersSent) {
195630
+ res.status(502).json({
195631
+ error: "Failed to proxy request to function",
195632
+ details: error48.message
195633
+ });
195634
+ res.once("finish", resolve5);
195635
+ } else {
195636
+ resolve5();
195637
+ }
195638
+ });
195639
+ req.pipe(proxyReq);
195640
+ });
195641
+ }
195642
+
195643
+ // src/cli/dev/dev-server/main.ts
195328
195644
  var DEFAULT_PORT = 4400;
195329
195645
  var BASE44_APP_URL = "https://base44.app";
195330
- async function createDevServer(options8 = {}) {
195331
- const port = options8.port ?? await getPorts({ port: DEFAULT_PORT });
195332
- const app = import_express.default();
195646
+ async function createDevServer(options8) {
195647
+ const { port: userPort } = options8;
195648
+ const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
195649
+ const { project: project2 } = await readProjectConfig();
195650
+ const configDir = dirname12(project2.configPath);
195651
+ const app = import_express2.default();
195333
195652
  const remoteProxy = import_http_proxy_middleware.createProxyMiddleware({
195334
195653
  target: BASE44_APP_URL,
195335
195654
  changeOrigin: true
@@ -195346,6 +195665,15 @@ async function createDevServer(options8 = {}) {
195346
195665
  }
195347
195666
  next();
195348
195667
  });
195668
+ const functions = await functionResource.readAll(join16(configDir, project2.functionsDir));
195669
+ const devLogger = createDevLogger(false);
195670
+ const functionManager = new FunctionManager(functions, devLogger);
195671
+ functionManager.verifyDenoIsInstalled();
195672
+ if (functionManager.functionNames().length > 0) {
195673
+ M2.info(`Loaded functions: ${functionManager.functionNames().join(", ")}`);
195674
+ }
195675
+ const functionRoutes = createFunctionRoutes(functionManager, devLogger);
195676
+ app.use("/api/apps/:appId/functions", functionRoutes);
195349
195677
  app.use((req, res, next) => {
195350
195678
  return remoteProxy(req, res, next);
195351
195679
  });
@@ -195358,6 +195686,12 @@ async function createDevServer(options8 = {}) {
195358
195686
  reject(err);
195359
195687
  }
195360
195688
  } else {
195689
+ const shutdown = () => {
195690
+ functionManager.stopAll();
195691
+ server.close();
195692
+ };
195693
+ process.on("SIGINT", shutdown);
195694
+ process.on("SIGTERM", shutdown);
195361
195695
  resolve5({
195362
195696
  port,
195363
195697
  server
@@ -195370,7 +195704,9 @@ async function createDevServer(options8 = {}) {
195370
195704
  // src/cli/commands/dev.ts
195371
195705
  async function devAction(options8) {
195372
195706
  const port = options8.port ? Number(options8.port) : undefined;
195373
- const { port: resolvedPort } = await createDevServer({ port });
195707
+ const { port: resolvedPort } = await createDevServer({
195708
+ port
195709
+ });
195374
195710
  return {
195375
195711
  outroMessage: `Dev server is available at ${theme.colors.links(`http://localhost:${resolvedPort}`)}`
195376
195712
  };
@@ -195468,7 +195804,7 @@ async function eject(options8) {
195468
195804
  }
195469
195805
  function getEjectCommand(context) {
195470
195806
  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) => {
195471
- await runCommand(() => eject(options8), { requireAuth: true, requireAppConfig: false }, context);
195807
+ await runCommand(() => eject({ ...options8, isNonInteractive: context.isNonInteractive }), { requireAuth: true, requireAppConfig: false }, context);
195472
195808
  });
195473
195809
  }
195474
195810
 
@@ -195532,7 +195868,7 @@ function nanoid3(size = 21) {
195532
195868
  }
195533
195869
 
195534
195870
  // node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
195535
- import { dirname as dirname11, posix, sep } from "path";
195871
+ import { dirname as dirname13, posix, sep } from "path";
195536
195872
  function createModulerModifier() {
195537
195873
  const getModuleFromFileName = createGetModuleFromFilename();
195538
195874
  return async (frames) => {
@@ -195541,7 +195877,7 @@ function createModulerModifier() {
195541
195877
  return frames;
195542
195878
  };
195543
195879
  }
195544
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname11(process.argv[1]) : process.cwd(), isWindows4 = sep === "\\") {
195880
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname13(process.argv[1]) : process.cwd(), isWindows4 = sep === "\\") {
195545
195881
  const normalizedBase = isWindows4 ? normalizeWindowsPath2(basePath) : basePath;
195546
195882
  return (filename) => {
195547
195883
  if (!filename)
@@ -199735,7 +200071,8 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
199735
200071
  async function runCLI() {
199736
200072
  const errorReporter = new ErrorReporter;
199737
200073
  errorReporter.registerProcessErrorHandlers();
199738
- const context = { errorReporter };
200074
+ const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
200075
+ const context = { errorReporter, isNonInteractive };
199739
200076
  const program2 = createProgram(context);
199740
200077
  try {
199741
200078
  const userInfo = await readAuth();
@@ -199760,4 +200097,4 @@ export {
199760
200097
  CLIExitError
199761
200098
  };
199762
200099
 
199763
- //# debugId=BE87F2C8EFF5B4AD64756E2164756E21
200100
+ //# debugId=2A5B2FACE1F5C10F64756E2164756E21