@base44-preview/cli 0.0.55-pr.540.d15d29c → 0.0.55-pr.541.427af2d

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
@@ -218285,6 +218285,7 @@ var PROJECT_CONFIG_PATTERNS = [
218285
218285
  `${PROJECT_SUBDIR}/config.${CONFIG_FILE_EXTENSION_GLOB}`,
218286
218286
  `config.${CONFIG_FILE_EXTENSION_GLOB}`
218287
218287
  ];
218288
+ var BASE44_APP_ID_ENV_VAR = "BASE44_APP_ID";
218288
218289
  var TYPES_OUTPUT_SUBDIR = ".types";
218289
218290
  var TYPES_FILENAME = "types.d.ts";
218290
218291
  var AUTH_CLIENT_ID = "base44_cli";
@@ -233980,7 +233981,7 @@ async function parseEnvFile(filePath) {
233980
233981
  }
233981
233982
  var STRIPE_ENV_PREFIX = "BASE44_PROJECTS_";
233982
233983
  var BASE44_ENV_KEYS = [
233983
- "BASE44_APP_ID",
233984
+ BASE44_APP_ID_ENV_VAR,
233984
233985
  "BASE44_ACCESS_TOKEN",
233985
233986
  "BASE44_REFRESH_TOKEN",
233986
233987
  "BASE44_API_URL"
@@ -241695,18 +241696,35 @@ function loadFromTestOverrides() {
241695
241696
  }
241696
241697
  return null;
241697
241698
  }
241698
- async function initAppContext() {
241699
+ async function initAppContext(options = {}) {
241699
241700
  const testConfig = loadFromTestOverrides();
241700
241701
  if (testConfig) {
241701
241702
  cache2 = testConfig;
241702
241703
  return cache2;
241703
241704
  }
241705
+ const projectRoot = findProjectRoot();
241706
+ if (options.appId !== undefined) {
241707
+ const id = options.appId.trim();
241708
+ if (!id) {
241709
+ throw new InvalidInputError("App id cannot be empty.");
241710
+ }
241711
+ cache2 = { id, projectRoot: projectRoot?.root };
241712
+ return cache2;
241713
+ }
241704
241714
  if (cache2) {
241705
241715
  return cache2;
241706
241716
  }
241707
- const projectRoot = findProjectRoot();
241708
241717
  if (!projectRoot) {
241709
- throw new ConfigNotFoundError("No Base44 project found. Run this command from a project directory with a config.jsonc file.");
241718
+ throw new ConfigNotFoundError(`No Base44 app ID found. Pass --app-id, set ${BASE44_APP_ID_ENV_VAR}, or run this command from a linked project with base44/.app.jsonc.`, {
241719
+ hints: [
241720
+ { message: "Pass an app ID explicitly with --app-id <id>" },
241721
+ { message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` },
241722
+ {
241723
+ message: "Run from a linked Base44 project with base44/.app.jsonc, or run 'base44 link'",
241724
+ command: "base44 link"
241725
+ }
241726
+ ]
241727
+ });
241710
241728
  }
241711
241729
  const config3 = await readAppConfig(projectRoot.root);
241712
241730
  const appConfigPath = await findAppConfigPath(projectRoot.root);
@@ -244434,8 +244452,8 @@ async function ensureAuth(ctx) {
244434
244452
  });
244435
244453
  } catch {}
244436
244454
  }
244437
- async function ensureAppContext(ctx) {
244438
- const appContext = await initAppContext();
244455
+ async function ensureAppContext(ctx, options = {}) {
244456
+ const appContext = await initAppContext(options);
244439
244457
  ctx.app = appContext;
244440
244458
  ctx.errorReporter.setContext({ appId: appContext.id });
244441
244459
  }
@@ -251101,7 +251119,8 @@ class Base44Command extends Command {
251101
251119
  await ensureAuth(this.context);
251102
251120
  }
251103
251121
  if (this._commandOptions.requireAppContext) {
251104
- await ensureAppContext(this.context);
251122
+ const { appId } = this.optsWithGlobals();
251123
+ await ensureAppContext(this.context, { appId });
251105
251124
  }
251106
251125
  const result = await fn(this.context, ...args) ?? {};
251107
251126
  if (!quiet) {
@@ -253070,7 +253089,11 @@ function printProjectSummary({ name: name2, dashboardUrl, appUrl }, log) {
253070
253089
  }
253071
253090
 
253072
253091
  // src/cli/commands/project/create.ts
253073
- function validateNonInteractiveFlags(command2) {
253092
+ function validateCreateOptions(command2) {
253093
+ const { appId } = command2.optsWithGlobals();
253094
+ if (appId !== undefined) {
253095
+ command2.error(`base44 create cannot be used with --app-id or ${BASE44_APP_ID_ENV_VAR}.`);
253096
+ }
253074
253097
  const { path: path17 } = command2.opts();
253075
253098
  if (path17 && !command2.args.length) {
253076
253099
  command2.error("--path requires a project name argument. Usage: base44 create <name> --path <path>");
@@ -253187,7 +253210,7 @@ function getCreateCommand() {
253187
253210
  Examples:
253188
253211
  $ base44 create my-app Creates a base44 project at ./my-app
253189
253212
  $ base44 create my-todo-app --template backend-and-client Creates a base44 backend-and-client project at ./my-todo-app
253190
- $ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction", validateNonInteractiveFlags).action(createAction);
253213
+ $ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction", validateCreateOptions).action(createAction);
253191
253214
  }
253192
253215
 
253193
253216
  // src/cli/commands/project/deploy.ts
@@ -253283,11 +253306,32 @@ function printStripeResult(r, log) {
253283
253306
  log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
253284
253307
  }
253285
253308
 
253309
+ // src/cli/commands/project/app-id-options.ts
253310
+ function readExplicitAppId(command2) {
253311
+ const { appId } = command2.optsWithGlobals();
253312
+ const { projectId } = command2.opts();
253313
+ const explicitAppId = command2.getOptionValueSourceWithGlobals("appId") === "cli" ? appId : undefined;
253314
+ const legacyProjectId = command2.getOptionValueSource("projectId") === "cli" ? projectId : undefined;
253315
+ return {
253316
+ appId: explicitAppId,
253317
+ legacyProjectId,
253318
+ value: explicitAppId ?? legacyProjectId
253319
+ };
253320
+ }
253321
+
253286
253322
  // src/cli/commands/project/link.ts
253287
- function validateNonInteractiveFlags2(command2) {
253288
- const { create: create4, name: name2, projectId } = command2.opts();
253289
- if (create4 && projectId) {
253290
- command2.error("--create and --projectId cannot be used together");
253323
+ function validateNonInteractiveFlags(command2) {
253324
+ const { create: create4, name: name2 } = command2.opts();
253325
+ const {
253326
+ appId,
253327
+ legacyProjectId,
253328
+ value: selectedAppId
253329
+ } = readExplicitAppId(command2);
253330
+ if (appId && legacyProjectId) {
253331
+ command2.error("--app-id and --project-id cannot be used together");
253332
+ }
253333
+ if (create4 && selectedAppId) {
253334
+ command2.error("--create and --app-id cannot be used together");
253291
253335
  }
253292
253336
  if (create4 && !name2) {
253293
253337
  command2.error("--name is required when using --create");
@@ -253356,11 +253400,12 @@ async function promptForExistingProject(linkableProjects) {
253356
253400
  }
253357
253401
  return selectedProject;
253358
253402
  }
253359
- async function link(ctx, options) {
253403
+ async function link(ctx, options, command2) {
253360
253404
  const { log, runTask: runTask2, isNonInteractive } = ctx;
253361
- const skipPrompts = !!options.create || !!options.projectId;
253405
+ const appId = readExplicitAppId(command2).value;
253406
+ const skipPrompts = !!options.create || !!appId;
253362
253407
  if (!skipPrompts && isNonInteractive) {
253363
- throw new InvalidInputError("--create with --name, or --projectId, is required in non-interactive mode");
253408
+ throw new InvalidInputError("--create with --name, or --app-id, is required in non-interactive mode");
253364
253409
  }
253365
253410
  const projectRoot = findProjectRoot();
253366
253411
  if (!projectRoot) {
@@ -253375,8 +253420,8 @@ async function link(ctx, options) {
253375
253420
  ]
253376
253421
  });
253377
253422
  }
253378
- let finalProjectId;
253379
- const action = options.projectId ? "choose" : options.create ? "create" : await promptForLinkAction();
253423
+ let finalAppId;
253424
+ const action = appId ? "choose" : options.create ? "create" : await promptForLinkAction();
253380
253425
  if (action === "choose") {
253381
253426
  const projects = await runTask2("Fetching projects...", async () => listProjects(), {
253382
253427
  successMessage: "Projects fetched",
@@ -253386,32 +253431,32 @@ async function link(ctx, options) {
253386
253431
  if (!linkableProjects.length) {
253387
253432
  return { outroMessage: "No projects available for linking" };
253388
253433
  }
253389
- let projectId;
253390
- if (options.projectId) {
253391
- const project2 = linkableProjects.find((p) => p.id === options.projectId);
253434
+ let linkedAppId;
253435
+ if (appId) {
253436
+ const project2 = linkableProjects.find((p) => p.id === appId);
253392
253437
  if (!project2) {
253393
- throw new InvalidInputError(`Project with ID "${options.projectId}" not found or not available for linking.`, {
253438
+ throw new InvalidInputError(`App with ID "${appId}" not found or not available for linking.`, {
253394
253439
  hints: [
253395
- { message: "Check the project ID is correct" },
253440
+ { message: "Check the app ID is correct" },
253396
253441
  {
253397
- message: "Use 'base44 link' without --projectId to see available projects"
253442
+ message: "Use 'base44 link' without --app-id to see available projects"
253398
253443
  }
253399
253444
  ]
253400
253445
  });
253401
253446
  }
253402
- projectId = options.projectId;
253447
+ linkedAppId = appId;
253403
253448
  } else {
253404
253449
  const selectedProject = await promptForExistingProject(linkableProjects);
253405
- projectId = selectedProject.id;
253450
+ linkedAppId = selectedProject.id;
253406
253451
  }
253407
253452
  await runTask2("Linking project...", async () => {
253408
- await writeAppConfig(projectRoot.root, projectId);
253409
- setAppContext({ id: projectId, projectRoot: projectRoot.root });
253453
+ await writeAppConfig(projectRoot.root, linkedAppId);
253454
+ setAppContext({ id: linkedAppId, projectRoot: projectRoot.root });
253410
253455
  }, {
253411
253456
  successMessage: "Project linked successfully",
253412
253457
  errorMessage: "Failed to link project"
253413
253458
  });
253414
- finalProjectId = projectId;
253459
+ finalAppId = linkedAppId;
253415
253460
  }
253416
253461
  if (action === "create") {
253417
253462
  const { name: name2, description } = options.create ? { name: options.name.trim(), description: options.description?.trim() } : await promptForNewProjectDetails();
@@ -253423,13 +253468,15 @@ async function link(ctx, options) {
253423
253468
  });
253424
253469
  await writeAppConfig(projectRoot.root, projectId);
253425
253470
  setAppContext({ id: projectId, projectRoot: projectRoot.root });
253426
- finalProjectId = projectId;
253471
+ finalAppId = projectId;
253427
253472
  }
253428
- log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(finalProjectId))}`);
253473
+ log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(finalAppId))}`);
253429
253474
  return { outroMessage: "Project linked" };
253430
253475
  }
253431
253476
  function getLinkCommand() {
253432
- return new Base44Command("link", { requireAppContext: false }).description("Link a local project to a Base44 project (create new or link existing)").option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").option("-p, --projectId <id>", "Project ID to link to an existing project (skips selection prompt)").hook("preAction", validateNonInteractiveFlags2).action(link);
253477
+ return new Base44Command("link", {
253478
+ requireAppContext: false
253479
+ }).description("Link a local project to a Base44 project (create new or link existing)").configureHelp({ showGlobalOptions: true }).option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").addOption(new Option("-p, --project-id <id>", "Project ID to link to an existing project").hideHelp()).addOption(new Option("--projectId <id>", "Project ID to link to an existing project").hideHelp()).hook("preAction", validateNonInteractiveFlags).action(link);
253433
253480
  }
253434
253481
 
253435
253482
  // src/cli/commands/project/logs.ts
@@ -253519,8 +253566,12 @@ async function fetchLogsForFunctions(functionNames, options, availableFunctionNa
253519
253566
  }
253520
253567
  return allEntries;
253521
253568
  }
253522
- async function getAllFunctionNames() {
253523
- const { functions } = await readProjectConfig();
253569
+ async function getProjectFunctionNames(projectRoot) {
253570
+ const { functions } = await readProjectConfig(projectRoot);
253571
+ return functions.map((fn) => fn.name);
253572
+ }
253573
+ async function getRemoteFunctionNames() {
253574
+ const { functions } = await listDeployedFunctions();
253524
253575
  return functions.map((fn) => fn.name);
253525
253576
  }
253526
253577
  function validateLimit(limit) {
@@ -253531,15 +253582,18 @@ function validateLimit(limit) {
253531
253582
  throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
253532
253583
  }
253533
253584
  }
253534
- async function logsAction(_ctx, options) {
253585
+ async function logsAction(ctx, options) {
253535
253586
  validateLimit(options.limit);
253536
253587
  const specifiedFunctions = parseFunctionNames(options.function);
253537
- const allProjectFunctions = await getAllFunctionNames();
253538
- const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
253588
+ const localProjectRoot = ctx.app?.projectRoot;
253589
+ const availableFunctionNames = localProjectRoot ? await getProjectFunctionNames(localProjectRoot) : await getRemoteFunctionNames();
253590
+ const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : availableFunctionNames;
253539
253591
  if (functionNames.length === 0) {
253540
- return { outroMessage: "No functions found in this project." };
253592
+ return {
253593
+ outroMessage: localProjectRoot ? "No functions found in this project." : "No functions found in this app."
253594
+ };
253541
253595
  }
253542
- let entries = await fetchLogsForFunctions(functionNames, options, allProjectFunctions);
253596
+ let entries = await fetchLogsForFunctions(functionNames, options, availableFunctionNames);
253543
253597
  const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
253544
253598
  if (limit !== undefined && entries.length > limit) {
253545
253599
  entries = entries.slice(0, limit);
@@ -253555,17 +253609,20 @@ function getLogsCommand() {
253555
253609
  // src/cli/commands/project/scaffold.ts
253556
253610
  import { basename as basename5, resolve as resolve6 } from "node:path";
253557
253611
  function resolveAppId(options) {
253558
- const appId = options.appId ?? process.env.BASE44_APP_ID;
253612
+ const appId = options.appId;
253559
253613
  if (!appId) {
253560
253614
  throw new InvalidInputError("No app ID found. `base44 scaffold` sets up a local project for an existing Base44 app.", {
253561
- hints: [{ message: "Pass it explicitly with --app-id <id>" }]
253615
+ hints: [
253616
+ { message: "Pass it explicitly with --app-id <id>" },
253617
+ { message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` }
253618
+ ]
253562
253619
  });
253563
253620
  }
253564
253621
  return appId;
253565
253622
  }
253566
- async function scaffoldAction(ctx, name2, options) {
253623
+ async function scaffoldAction(ctx, name2, options, command2) {
253567
253624
  const { log, runTask: runTask2 } = ctx;
253568
- const appId = resolveAppId(options);
253625
+ const appId = resolveAppId(command2.optsWithGlobals());
253569
253626
  const resolvedPath = resolve6("./");
253570
253627
  const projectName = (name2 ?? basename5(resolvedPath)).trim();
253571
253628
  const template2 = await getTemplateById("backend-only");
@@ -253597,7 +253654,7 @@ function getScaffoldCommand() {
253597
253654
  return new Base44Command("scaffold", {
253598
253655
  requireAppContext: false,
253599
253656
  fullBanner: true
253600
- }).description("Scaffold a local project for an existing Base44 app").addArgument(new Argument("name", "Project name").argOptional()).option("--app-id <id>", "Existing Base44 app ID").option("--no-skills", "Skip AI agent skills installation").addHelpText("after", `
253657
+ }).description("Scaffold a local project for an existing Base44 app").addArgument(new Argument("name", "Project name").argOptional()).option("--no-skills", "Skip AI agent skills installation").addHelpText("after", `
253601
253658
  Examples:
253602
253659
  $ base44 scaffold --app-id app_123 Scaffolds the current dir for the given app
253603
253660
  $ base44 scaffold my-app --app-id app_123 Scaffolds the current dir, named "my-app"`).action(scaffoldAction);
@@ -257353,7 +257410,10 @@ function readStdin2() {
257353
257410
  process.stdin.on("error", reject);
257354
257411
  });
257355
257412
  }
257356
- async function execAction(isNonInteractive) {
257413
+ async function execAction({
257414
+ app,
257415
+ isNonInteractive
257416
+ }) {
257357
257417
  const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
257358
257418
  hints: [
257359
257419
  { message: "File: cat ./script.ts | base44 exec" },
@@ -257369,7 +257429,7 @@ async function execAction(isNonInteractive) {
257369
257429
  if (!code2.trim()) {
257370
257430
  throw noInputError;
257371
257431
  }
257372
- const { exitCode } = await runScript({ appId: getAppContext().id, code: code2 });
257432
+ const { exitCode } = await runScript({ appId: app.id, code: code2 });
257373
257433
  if (exitCode !== 0) {
257374
257434
  process.exitCode = exitCode;
257375
257435
  }
@@ -257382,18 +257442,26 @@ Examples:
257382
257442
  $ cat ./script.ts | base44 exec
257383
257443
 
257384
257444
  Inline script:
257385
- $ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async ({ isNonInteractive }) => {
257386
- return await execAction(isNonInteractive);
257445
+ $ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (ctx) => {
257446
+ return await execAction(ctx);
257387
257447
  });
257388
257448
  }
257389
257449
 
257390
257450
  // src/cli/commands/project/eject.ts
257391
257451
  import { resolve as resolve12 } from "node:path";
257392
257452
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
257393
- async function eject(ctx, options8) {
257453
+ async function eject(ctx, options8, command2) {
257394
257454
  const { log, runTask: runTask2, isNonInteractive } = ctx;
257395
- if (isNonInteractive && !options8.projectId) {
257396
- throw new InvalidInputError("--project-id is required in non-interactive mode");
257455
+ const {
257456
+ appId,
257457
+ legacyProjectId,
257458
+ value: selectedAppId
257459
+ } = readExplicitAppId(command2);
257460
+ if (appId && legacyProjectId) {
257461
+ throw new InvalidInputError("--app-id and --project-id cannot be used together");
257462
+ }
257463
+ if (isNonInteractive && !selectedAppId) {
257464
+ throw new InvalidInputError("--app-id is required in non-interactive mode");
257397
257465
  }
257398
257466
  if (isNonInteractive && !options8.path) {
257399
257467
  throw new InvalidInputError("--path is required in non-interactive mode");
@@ -257401,13 +257469,13 @@ async function eject(ctx, options8) {
257401
257469
  const projects = await listProjects();
257402
257470
  const ejectableProjects = projects.filter((p4) => p4.isManagedSourceCode !== false);
257403
257471
  let selectedProject;
257404
- if (options8.projectId) {
257405
- const foundProject = ejectableProjects.find((p4) => p4.id === options8.projectId);
257472
+ if (selectedAppId) {
257473
+ const foundProject = ejectableProjects.find((p4) => p4.id === selectedAppId);
257406
257474
  if (!foundProject) {
257407
- throw new InvalidInputError(`Project with ID "${options8.projectId}" not found or not ejectable`, {
257475
+ throw new InvalidInputError(`App with ID "${selectedAppId}" not found or not ejectable`, {
257408
257476
  hints: [
257409
257477
  {
257410
- message: "Run 'base44 eject' without --project-id to see available projects"
257478
+ message: "Run 'base44 eject' without --app-id to see available projects"
257411
257479
  }
257412
257480
  ]
257413
257481
  });
@@ -257483,13 +257551,15 @@ async function eject(ctx, options8) {
257483
257551
  return { outroMessage: "Your new project is set and ready to use" };
257484
257552
  }
257485
257553
  function getEjectCommand() {
257486
- return new Base44Command("eject", { requireAppContext: false }).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(eject);
257554
+ return new Base44Command("eject", {
257555
+ requireAppContext: false
257556
+ }).description("Download the code for an existing Base44 project").configureHelp({ showGlobalOptions: true }).option("-p, --path <path>", "Path where to write the project").option("-y, --yes", "Skip confirmation prompts").addOption(new Option("--project-id <id>", "Project ID to eject (skips interactive selection)").hideHelp()).action(eject);
257487
257557
  }
257488
257558
 
257489
257559
  // src/cli/program.ts
257490
257560
  function createProgram(context) {
257491
257561
  const program2 = new Command;
257492
- program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version);
257562
+ program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version).addOption(new Option("--app-id <id>", "Base44 app ID to use").env(BASE44_APP_ID_ENV_VAR));
257493
257563
  program2.configureHelp({
257494
257564
  sortSubcommands: true
257495
257565
  });
@@ -261763,4 +261833,4 @@ export {
261763
261833
  CLIExitError
261764
261834
  };
261765
261835
 
261766
- //# debugId=3970718286C2C0E164756E2164756E21
261836
+ //# debugId=1AFC96DD14EFBB4A64756E2164756E21