@base44-preview/cli 0.0.55-pr.541.ec65d32 → 0.0.55-pr.545.19bb665
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 +183 -165
- package/dist/cli/index.js.map +19 -19
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -218285,7 +218285,6 @@ 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";
|
|
218289
218288
|
var TYPES_OUTPUT_SUBDIR = ".types";
|
|
218290
218289
|
var TYPES_FILENAME = "types.d.ts";
|
|
218291
218290
|
var AUTH_CLIENT_ID = "base44_cli";
|
|
@@ -233981,7 +233980,7 @@ async function parseEnvFile(filePath) {
|
|
|
233981
233980
|
}
|
|
233982
233981
|
var STRIPE_ENV_PREFIX = "BASE44_PROJECTS_";
|
|
233983
233982
|
var BASE44_ENV_KEYS = [
|
|
233984
|
-
|
|
233983
|
+
"BASE44_APP_ID",
|
|
233985
233984
|
"BASE44_ACCESS_TOKEN",
|
|
233986
233985
|
"BASE44_REFRESH_TOKEN",
|
|
233987
233986
|
"BASE44_API_URL"
|
|
@@ -234018,7 +234017,7 @@ function normalizeBase44Env() {
|
|
|
234018
234017
|
loadProjectEnvFiles();
|
|
234019
234018
|
|
|
234020
234019
|
// src/cli/index.ts
|
|
234021
|
-
import { dirname as dirname23, join as
|
|
234020
|
+
import { dirname as dirname23, join as join28 } from "node:path";
|
|
234022
234021
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
234023
234022
|
|
|
234024
234023
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -241695,35 +241694,18 @@ function loadFromTestOverrides() {
|
|
|
241695
241694
|
}
|
|
241696
241695
|
return null;
|
|
241697
241696
|
}
|
|
241698
|
-
async function initAppContext(
|
|
241697
|
+
async function initAppContext() {
|
|
241699
241698
|
const testConfig = loadFromTestOverrides();
|
|
241700
241699
|
if (testConfig) {
|
|
241701
241700
|
cache2 = testConfig;
|
|
241702
241701
|
return cache2;
|
|
241703
241702
|
}
|
|
241704
|
-
const projectRoot = findProjectRoot();
|
|
241705
|
-
if (options.appId !== undefined) {
|
|
241706
|
-
const id = options.appId.trim();
|
|
241707
|
-
if (!id) {
|
|
241708
|
-
throw new InvalidInputError("App id cannot be empty.");
|
|
241709
|
-
}
|
|
241710
|
-
cache2 = { id, projectRoot: projectRoot?.root };
|
|
241711
|
-
return cache2;
|
|
241712
|
-
}
|
|
241713
241703
|
if (cache2) {
|
|
241714
241704
|
return cache2;
|
|
241715
241705
|
}
|
|
241706
|
+
const projectRoot = findProjectRoot();
|
|
241716
241707
|
if (!projectRoot) {
|
|
241717
|
-
throw new ConfigNotFoundError(
|
|
241718
|
-
hints: [
|
|
241719
|
-
{ message: "Pass an app ID explicitly with --app-id <id>" },
|
|
241720
|
-
{ message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` },
|
|
241721
|
-
{
|
|
241722
|
-
message: "Run from a linked Base44 project with base44/.app.jsonc, or run 'base44 link'",
|
|
241723
|
-
command: "base44 link"
|
|
241724
|
-
}
|
|
241725
|
-
]
|
|
241726
|
-
});
|
|
241708
|
+
throw new ConfigNotFoundError("No Base44 project found. Run this command from a project directory with a config.jsonc file.");
|
|
241727
241709
|
}
|
|
241728
241710
|
const config3 = await readAppConfig(projectRoot.root);
|
|
241729
241711
|
const appConfigPath = await findAppConfigPath(projectRoot.root);
|
|
@@ -244451,8 +244433,8 @@ async function ensureAuth(ctx) {
|
|
|
244451
244433
|
});
|
|
244452
244434
|
} catch {}
|
|
244453
244435
|
}
|
|
244454
|
-
async function ensureAppContext(ctx
|
|
244455
|
-
const appContext = await initAppContext(
|
|
244436
|
+
async function ensureAppContext(ctx) {
|
|
244437
|
+
const appContext = await initAppContext();
|
|
244456
244438
|
ctx.app = appContext;
|
|
244457
244439
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
244458
244440
|
}
|
|
@@ -251118,8 +251100,7 @@ class Base44Command extends Command {
|
|
|
251118
251100
|
await ensureAuth(this.context);
|
|
251119
251101
|
}
|
|
251120
251102
|
if (this._commandOptions.requireAppContext) {
|
|
251121
|
-
|
|
251122
|
-
await ensureAppContext(this.context, { appId });
|
|
251103
|
+
await ensureAppContext(this.context);
|
|
251123
251104
|
}
|
|
251124
251105
|
const result = await fn(this.context, ...args) ?? {};
|
|
251125
251106
|
if (!quiet) {
|
|
@@ -253088,11 +253069,7 @@ function printProjectSummary({ name: name2, dashboardUrl, appUrl }, log) {
|
|
|
253088
253069
|
}
|
|
253089
253070
|
|
|
253090
253071
|
// src/cli/commands/project/create.ts
|
|
253091
|
-
function
|
|
253092
|
-
const { appId } = command2.optsWithGlobals();
|
|
253093
|
-
if (appId !== undefined) {
|
|
253094
|
-
command2.error(`base44 create cannot be used with --app-id or ${BASE44_APP_ID_ENV_VAR}.`);
|
|
253095
|
-
}
|
|
253072
|
+
function validateNonInteractiveFlags(command2) {
|
|
253096
253073
|
const { path: path17 } = command2.opts();
|
|
253097
253074
|
if (path17 && !command2.args.length) {
|
|
253098
253075
|
command2.error("--path requires a project name argument. Usage: base44 create <name> --path <path>");
|
|
@@ -253209,7 +253186,7 @@ function getCreateCommand() {
|
|
|
253209
253186
|
Examples:
|
|
253210
253187
|
$ base44 create my-app Creates a base44 project at ./my-app
|
|
253211
253188
|
$ base44 create my-todo-app --template backend-and-client Creates a base44 backend-and-client project at ./my-todo-app
|
|
253212
|
-
$ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction",
|
|
253189
|
+
$ 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
253190
|
}
|
|
253214
253191
|
|
|
253215
253192
|
// src/cli/commands/project/deploy.ts
|
|
@@ -253305,32 +253282,11 @@ function printStripeResult(r, log) {
|
|
|
253305
253282
|
log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
253306
253283
|
}
|
|
253307
253284
|
|
|
253308
|
-
// src/cli/commands/project/app-id-options.ts
|
|
253309
|
-
function readExplicitAppId(command2) {
|
|
253310
|
-
const { appId } = command2.optsWithGlobals();
|
|
253311
|
-
const { projectId } = command2.opts();
|
|
253312
|
-
const explicitAppId = command2.getOptionValueSourceWithGlobals("appId") === "cli" ? appId : undefined;
|
|
253313
|
-
const legacyProjectId = command2.getOptionValueSource("projectId") === "cli" ? projectId : undefined;
|
|
253314
|
-
return {
|
|
253315
|
-
appId: explicitAppId,
|
|
253316
|
-
legacyProjectId,
|
|
253317
|
-
value: explicitAppId ?? legacyProjectId
|
|
253318
|
-
};
|
|
253319
|
-
}
|
|
253320
|
-
|
|
253321
253285
|
// src/cli/commands/project/link.ts
|
|
253322
|
-
function
|
|
253323
|
-
const { create: create4, name: name2 } = command2.opts();
|
|
253324
|
-
|
|
253325
|
-
|
|
253326
|
-
legacyProjectId,
|
|
253327
|
-
value: selectedAppId
|
|
253328
|
-
} = readExplicitAppId(command2);
|
|
253329
|
-
if (appId && legacyProjectId) {
|
|
253330
|
-
command2.error("--app-id and --project-id cannot be used together");
|
|
253331
|
-
}
|
|
253332
|
-
if (create4 && selectedAppId) {
|
|
253333
|
-
command2.error("--create and --app-id cannot be used together");
|
|
253286
|
+
function validateNonInteractiveFlags2(command2) {
|
|
253287
|
+
const { create: create4, name: name2, projectId } = command2.opts();
|
|
253288
|
+
if (create4 && projectId) {
|
|
253289
|
+
command2.error("--create and --projectId cannot be used together");
|
|
253334
253290
|
}
|
|
253335
253291
|
if (create4 && !name2) {
|
|
253336
253292
|
command2.error("--name is required when using --create");
|
|
@@ -253399,12 +253355,11 @@ async function promptForExistingProject(linkableProjects) {
|
|
|
253399
253355
|
}
|
|
253400
253356
|
return selectedProject;
|
|
253401
253357
|
}
|
|
253402
|
-
async function link(ctx, options
|
|
253358
|
+
async function link(ctx, options) {
|
|
253403
253359
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
253404
|
-
const
|
|
253405
|
-
const skipPrompts = !!options.create || !!appId;
|
|
253360
|
+
const skipPrompts = !!options.create || !!options.projectId;
|
|
253406
253361
|
if (!skipPrompts && isNonInteractive) {
|
|
253407
|
-
throw new InvalidInputError("--create with --name, or --
|
|
253362
|
+
throw new InvalidInputError("--create with --name, or --projectId, is required in non-interactive mode");
|
|
253408
253363
|
}
|
|
253409
253364
|
const projectRoot = findProjectRoot();
|
|
253410
253365
|
if (!projectRoot) {
|
|
@@ -253419,8 +253374,8 @@ async function link(ctx, options, command2) {
|
|
|
253419
253374
|
]
|
|
253420
253375
|
});
|
|
253421
253376
|
}
|
|
253422
|
-
let
|
|
253423
|
-
const action =
|
|
253377
|
+
let finalProjectId;
|
|
253378
|
+
const action = options.projectId ? "choose" : options.create ? "create" : await promptForLinkAction();
|
|
253424
253379
|
if (action === "choose") {
|
|
253425
253380
|
const projects = await runTask2("Fetching projects...", async () => listProjects(), {
|
|
253426
253381
|
successMessage: "Projects fetched",
|
|
@@ -253430,32 +253385,32 @@ async function link(ctx, options, command2) {
|
|
|
253430
253385
|
if (!linkableProjects.length) {
|
|
253431
253386
|
return { outroMessage: "No projects available for linking" };
|
|
253432
253387
|
}
|
|
253433
|
-
let
|
|
253434
|
-
if (
|
|
253435
|
-
const project2 = linkableProjects.find((p) => p.id ===
|
|
253388
|
+
let projectId;
|
|
253389
|
+
if (options.projectId) {
|
|
253390
|
+
const project2 = linkableProjects.find((p) => p.id === options.projectId);
|
|
253436
253391
|
if (!project2) {
|
|
253437
|
-
throw new InvalidInputError(`
|
|
253392
|
+
throw new InvalidInputError(`Project with ID "${options.projectId}" not found or not available for linking.`, {
|
|
253438
253393
|
hints: [
|
|
253439
|
-
{ message: "Check the
|
|
253394
|
+
{ message: "Check the project ID is correct" },
|
|
253440
253395
|
{
|
|
253441
|
-
message: "Use 'base44 link' without --
|
|
253396
|
+
message: "Use 'base44 link' without --projectId to see available projects"
|
|
253442
253397
|
}
|
|
253443
253398
|
]
|
|
253444
253399
|
});
|
|
253445
253400
|
}
|
|
253446
|
-
|
|
253401
|
+
projectId = options.projectId;
|
|
253447
253402
|
} else {
|
|
253448
253403
|
const selectedProject = await promptForExistingProject(linkableProjects);
|
|
253449
|
-
|
|
253404
|
+
projectId = selectedProject.id;
|
|
253450
253405
|
}
|
|
253451
253406
|
await runTask2("Linking project...", async () => {
|
|
253452
|
-
await writeAppConfig(projectRoot.root,
|
|
253453
|
-
setAppContext({ id:
|
|
253407
|
+
await writeAppConfig(projectRoot.root, projectId);
|
|
253408
|
+
setAppContext({ id: projectId, projectRoot: projectRoot.root });
|
|
253454
253409
|
}, {
|
|
253455
253410
|
successMessage: "Project linked successfully",
|
|
253456
253411
|
errorMessage: "Failed to link project"
|
|
253457
253412
|
});
|
|
253458
|
-
|
|
253413
|
+
finalProjectId = projectId;
|
|
253459
253414
|
}
|
|
253460
253415
|
if (action === "create") {
|
|
253461
253416
|
const { name: name2, description } = options.create ? { name: options.name.trim(), description: options.description?.trim() } : await promptForNewProjectDetails();
|
|
@@ -253467,15 +253422,13 @@ async function link(ctx, options, command2) {
|
|
|
253467
253422
|
});
|
|
253468
253423
|
await writeAppConfig(projectRoot.root, projectId);
|
|
253469
253424
|
setAppContext({ id: projectId, projectRoot: projectRoot.root });
|
|
253470
|
-
|
|
253425
|
+
finalProjectId = projectId;
|
|
253471
253426
|
}
|
|
253472
|
-
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(
|
|
253427
|
+
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(finalProjectId))}`);
|
|
253473
253428
|
return { outroMessage: "Project linked" };
|
|
253474
253429
|
}
|
|
253475
253430
|
function getLinkCommand() {
|
|
253476
|
-
return new Base44Command("link", {
|
|
253477
|
-
requireAppContext: false
|
|
253478
|
-
}).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);
|
|
253431
|
+
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);
|
|
253479
253432
|
}
|
|
253480
253433
|
|
|
253481
253434
|
// src/cli/commands/project/logs.ts
|
|
@@ -253565,12 +253518,8 @@ async function fetchLogsForFunctions(functionNames, options, availableFunctionNa
|
|
|
253565
253518
|
}
|
|
253566
253519
|
return allEntries;
|
|
253567
253520
|
}
|
|
253568
|
-
async function
|
|
253569
|
-
const { functions } = await readProjectConfig(
|
|
253570
|
-
return functions.map((fn) => fn.name);
|
|
253571
|
-
}
|
|
253572
|
-
async function getRemoteFunctionNames() {
|
|
253573
|
-
const { functions } = await listDeployedFunctions();
|
|
253521
|
+
async function getAllFunctionNames() {
|
|
253522
|
+
const { functions } = await readProjectConfig();
|
|
253574
253523
|
return functions.map((fn) => fn.name);
|
|
253575
253524
|
}
|
|
253576
253525
|
function validateLimit(limit) {
|
|
@@ -253581,18 +253530,15 @@ function validateLimit(limit) {
|
|
|
253581
253530
|
throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
|
|
253582
253531
|
}
|
|
253583
253532
|
}
|
|
253584
|
-
async function logsAction(
|
|
253533
|
+
async function logsAction(_ctx, options) {
|
|
253585
253534
|
validateLimit(options.limit);
|
|
253586
253535
|
const specifiedFunctions = parseFunctionNames(options.function);
|
|
253587
|
-
const
|
|
253588
|
-
const
|
|
253589
|
-
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : availableFunctionNames;
|
|
253536
|
+
const allProjectFunctions = await getAllFunctionNames();
|
|
253537
|
+
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
|
|
253590
253538
|
if (functionNames.length === 0) {
|
|
253591
|
-
return {
|
|
253592
|
-
outroMessage: localProjectRoot ? "No functions found in this project." : "No functions found in this app."
|
|
253593
|
-
};
|
|
253539
|
+
return { outroMessage: "No functions found in this project." };
|
|
253594
253540
|
}
|
|
253595
|
-
let entries = await fetchLogsForFunctions(functionNames, options,
|
|
253541
|
+
let entries = await fetchLogsForFunctions(functionNames, options, allProjectFunctions);
|
|
253596
253542
|
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
253597
253543
|
if (limit !== undefined && entries.length > limit) {
|
|
253598
253544
|
entries = entries.slice(0, limit);
|
|
@@ -253608,20 +253554,17 @@ function getLogsCommand() {
|
|
|
253608
253554
|
// src/cli/commands/project/scaffold.ts
|
|
253609
253555
|
import { basename as basename5, resolve as resolve6 } from "node:path";
|
|
253610
253556
|
function resolveAppId(options) {
|
|
253611
|
-
const appId = options.appId;
|
|
253557
|
+
const appId = options.appId ?? process.env.BASE44_APP_ID;
|
|
253612
253558
|
if (!appId) {
|
|
253613
253559
|
throw new InvalidInputError("No app ID found. `base44 scaffold` sets up a local project for an existing Base44 app.", {
|
|
253614
|
-
hints: [
|
|
253615
|
-
{ message: "Pass it explicitly with --app-id <id>" },
|
|
253616
|
-
{ message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` }
|
|
253617
|
-
]
|
|
253560
|
+
hints: [{ message: "Pass it explicitly with --app-id <id>" }]
|
|
253618
253561
|
});
|
|
253619
253562
|
}
|
|
253620
253563
|
return appId;
|
|
253621
253564
|
}
|
|
253622
|
-
async function scaffoldAction(ctx, name2, options
|
|
253565
|
+
async function scaffoldAction(ctx, name2, options) {
|
|
253623
253566
|
const { log, runTask: runTask2 } = ctx;
|
|
253624
|
-
const appId = resolveAppId(
|
|
253567
|
+
const appId = resolveAppId(options);
|
|
253625
253568
|
const resolvedPath = resolve6("./");
|
|
253626
253569
|
const projectName = (name2 ?? basename5(resolvedPath)).trim();
|
|
253627
253570
|
const template2 = await getTemplateById("backend-only");
|
|
@@ -253653,7 +253596,7 @@ function getScaffoldCommand() {
|
|
|
253653
253596
|
return new Base44Command("scaffold", {
|
|
253654
253597
|
requireAppContext: false,
|
|
253655
253598
|
fullBanner: true
|
|
253656
|
-
}).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", `
|
|
253599
|
+
}).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
253600
|
Examples:
|
|
253658
253601
|
$ base44 scaffold --app-id app_123 Scaffolds the current dir for the given app
|
|
253659
253602
|
$ base44 scaffold my-app --app-id app_123 Scaffolds the current dir, named "my-app"`).action(scaffoldAction);
|
|
@@ -253953,10 +253896,6 @@ function getTypesCommand() {
|
|
|
253953
253896
|
return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
253954
253897
|
}
|
|
253955
253898
|
|
|
253956
|
-
// src/cli/commands/dev.ts
|
|
253957
|
-
import { join as join28 } from "node:path";
|
|
253958
|
-
import process21 from "node:process";
|
|
253959
|
-
|
|
253960
253899
|
// src/cli/dev/dev-server/main.ts
|
|
253961
253900
|
var import_cors = __toESM(require_lib4(), 1);
|
|
253962
253901
|
var import_express6 = __toESM(require_express(), 1);
|
|
@@ -254112,12 +254051,11 @@ var stringify = (item) => {
|
|
|
254112
254051
|
return String(item);
|
|
254113
254052
|
}
|
|
254114
254053
|
};
|
|
254115
|
-
function createDevLogger() {
|
|
254054
|
+
function createDevLogger(label2, labelColor = theme.styles.dim) {
|
|
254055
|
+
const prefix = label2 ? `${labelColor(`[${label2}]`)} ` : "";
|
|
254116
254056
|
const print = (type, ...args) => {
|
|
254117
254057
|
const colorize = colorByType[type];
|
|
254118
|
-
console[type](
|
|
254119
|
-
return colorize(stringify(item));
|
|
254120
|
-
}));
|
|
254058
|
+
console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
|
|
254121
254059
|
};
|
|
254122
254060
|
return {
|
|
254123
254061
|
log: (...args) => print("log", ...args),
|
|
@@ -255484,6 +255422,92 @@ function createCustomIntegrationRoutes(remoteProxy, logger2) {
|
|
|
255484
255422
|
return router;
|
|
255485
255423
|
}
|
|
255486
255424
|
|
|
255425
|
+
// src/cli/dev/dev-server/serve-runner.ts
|
|
255426
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
255427
|
+
import process21 from "node:process";
|
|
255428
|
+
|
|
255429
|
+
class ServeRunner {
|
|
255430
|
+
command;
|
|
255431
|
+
cwd;
|
|
255432
|
+
env;
|
|
255433
|
+
logger;
|
|
255434
|
+
child;
|
|
255435
|
+
stopping = false;
|
|
255436
|
+
exitListeners = [];
|
|
255437
|
+
constructor(options8) {
|
|
255438
|
+
this.command = options8.command;
|
|
255439
|
+
this.cwd = options8.cwd;
|
|
255440
|
+
this.env = options8.env;
|
|
255441
|
+
this.logger = options8.logger;
|
|
255442
|
+
}
|
|
255443
|
+
start() {
|
|
255444
|
+
if (this.child) {
|
|
255445
|
+
return;
|
|
255446
|
+
}
|
|
255447
|
+
const child = spawn3(this.command, {
|
|
255448
|
+
cwd: this.cwd,
|
|
255449
|
+
shell: true,
|
|
255450
|
+
detached: process21.platform !== "win32",
|
|
255451
|
+
env: { ...process21.env, ...this.env },
|
|
255452
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
255453
|
+
});
|
|
255454
|
+
this.child = child;
|
|
255455
|
+
this.setupHandlers(child);
|
|
255456
|
+
}
|
|
255457
|
+
onExit(listener) {
|
|
255458
|
+
this.exitListeners.push(listener);
|
|
255459
|
+
}
|
|
255460
|
+
async stop() {
|
|
255461
|
+
const child = this.child;
|
|
255462
|
+
if (!child || child.exitCode !== null) {
|
|
255463
|
+
return;
|
|
255464
|
+
}
|
|
255465
|
+
this.stopping = true;
|
|
255466
|
+
const exited = new Promise((resolve10) => child.once("exit", () => resolve10()));
|
|
255467
|
+
if (process21.platform === "win32" && child.pid) {
|
|
255468
|
+
spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"]);
|
|
255469
|
+
} else if (child.pid) {
|
|
255470
|
+
try {
|
|
255471
|
+
process21.kill(-child.pid, "SIGTERM");
|
|
255472
|
+
} catch {
|
|
255473
|
+
child.kill();
|
|
255474
|
+
}
|
|
255475
|
+
}
|
|
255476
|
+
await exited;
|
|
255477
|
+
}
|
|
255478
|
+
setupHandlers(child) {
|
|
255479
|
+
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
255480
|
+
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
255481
|
+
child.on("error", (error48) => {
|
|
255482
|
+
this.logger.error("Frontend dev server failed to start:", error48);
|
|
255483
|
+
this.notifyExit(null);
|
|
255484
|
+
});
|
|
255485
|
+
child.on("exit", (code2) => {
|
|
255486
|
+
if (this.stopping) {
|
|
255487
|
+
return;
|
|
255488
|
+
}
|
|
255489
|
+
this.logger.error(`Frontend dev server exited with code ${code2}`);
|
|
255490
|
+
this.notifyExit(code2);
|
|
255491
|
+
});
|
|
255492
|
+
}
|
|
255493
|
+
notifyExit(code2) {
|
|
255494
|
+
for (const listener of this.exitListeners) {
|
|
255495
|
+
listener(code2);
|
|
255496
|
+
}
|
|
255497
|
+
}
|
|
255498
|
+
emitLines(data, type) {
|
|
255499
|
+
const lines = data.toString().trimEnd().split(`
|
|
255500
|
+
`);
|
|
255501
|
+
for (const line3 of lines) {
|
|
255502
|
+
if (type === "error") {
|
|
255503
|
+
this.logger.error(line3);
|
|
255504
|
+
} else {
|
|
255505
|
+
this.logger.log(line3);
|
|
255506
|
+
}
|
|
255507
|
+
}
|
|
255508
|
+
}
|
|
255509
|
+
}
|
|
255510
|
+
|
|
255487
255511
|
// src/cli/dev/dev-server/watcher.ts
|
|
255488
255512
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
255489
255513
|
import { relative as relative6 } from "node:path";
|
|
@@ -257207,17 +257231,17 @@ async function createDevServer(options8) {
|
|
|
257207
257231
|
}
|
|
257208
257232
|
next();
|
|
257209
257233
|
});
|
|
257210
|
-
const devLogger = createDevLogger();
|
|
257234
|
+
const devLogger = createDevLogger("backend", theme.styles.info);
|
|
257211
257235
|
const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
|
|
257212
257236
|
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
257213
257237
|
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
257214
257238
|
if (functionManager.getFunctionNames().length > 0) {
|
|
257215
|
-
|
|
257239
|
+
devLogger.log(`Loaded functions: ${functionManager.getFunctionNames().join(", ")}`);
|
|
257216
257240
|
}
|
|
257217
257241
|
const db2 = new Database;
|
|
257218
257242
|
await db2.load(entities);
|
|
257219
257243
|
if (db2.getCollectionNames().length > 0) {
|
|
257220
|
-
|
|
257244
|
+
devLogger.log(`Loaded entities: ${db2.getCollectionNames().join(", ")}`);
|
|
257221
257245
|
}
|
|
257222
257246
|
let emitEntityEvent = () => {};
|
|
257223
257247
|
const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
|
|
@@ -257305,14 +257329,34 @@ async function createDevServer(options8) {
|
|
|
257305
257329
|
}
|
|
257306
257330
|
});
|
|
257307
257331
|
await base44ConfigWatcher.start();
|
|
257332
|
+
let serveRunner;
|
|
257333
|
+
if (options8.serve) {
|
|
257334
|
+
serveRunner = new ServeRunner({
|
|
257335
|
+
command: options8.serve.command,
|
|
257336
|
+
cwd: options8.serve.cwd,
|
|
257337
|
+
env: {
|
|
257338
|
+
VITE_BASE44_APP_ID: options8.serve.appId,
|
|
257339
|
+
VITE_BASE44_APP_BASE_URL: baseUrl
|
|
257340
|
+
},
|
|
257341
|
+
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
257342
|
+
});
|
|
257343
|
+
}
|
|
257308
257344
|
const shutdown = async () => {
|
|
257309
257345
|
base44ConfigWatcher.close();
|
|
257310
257346
|
io6.close();
|
|
257311
257347
|
await functionManager.stopAll();
|
|
257348
|
+
await serveRunner?.stop();
|
|
257312
257349
|
server.close();
|
|
257313
257350
|
};
|
|
257314
257351
|
process.on("SIGINT", shutdown);
|
|
257315
257352
|
process.on("SIGTERM", shutdown);
|
|
257353
|
+
serveRunner?.onExit(() => {
|
|
257354
|
+
shutdown().finally(() => process.exit(1));
|
|
257355
|
+
});
|
|
257356
|
+
if (serveRunner) {
|
|
257357
|
+
devLogger.log(`Backend running on ${baseUrl}`);
|
|
257358
|
+
serveRunner.start();
|
|
257359
|
+
}
|
|
257316
257360
|
return { port, server };
|
|
257317
257361
|
}
|
|
257318
257362
|
|
|
@@ -257320,44 +257364,31 @@ async function createDevServer(options8) {
|
|
|
257320
257364
|
function localServerUrl(port) {
|
|
257321
257365
|
return `http://localhost:${port}`;
|
|
257322
257366
|
}
|
|
257323
|
-
async function writeEnvLocalIfMissing(projectRoot, port, log) {
|
|
257324
|
-
const envLocalPath = join28(projectRoot, ".env.local");
|
|
257325
|
-
if (await pathExists(envLocalPath)) {
|
|
257326
|
-
return;
|
|
257327
|
-
}
|
|
257328
|
-
const { id: appId } = await initAppContext();
|
|
257329
|
-
await writeFile(envLocalPath, `VITE_BASE44_APP_ID=${appId}
|
|
257330
|
-
VITE_BASE44_APP_BASE_URL=${localServerUrl(port)}
|
|
257331
|
-
`);
|
|
257332
|
-
log.info("Created .env.local with app ID and dev server URL");
|
|
257333
|
-
}
|
|
257334
257367
|
async function devAction({ log }, options8) {
|
|
257335
257368
|
const port = options8.port ? Number(options8.port) : undefined;
|
|
257336
|
-
|
|
257369
|
+
const { project: project2 } = await readProjectConfig();
|
|
257370
|
+
const serveCommand = project2.site?.serveCommand;
|
|
257371
|
+
const appId = serveCommand ? (await initAppContext()).id : undefined;
|
|
257372
|
+
const serve = serveCommand && appId ? { command: serveCommand, cwd: project2.root, appId } : undefined;
|
|
257337
257373
|
const { port: resolvedPort } = await createDevServer({
|
|
257338
257374
|
log,
|
|
257339
257375
|
port,
|
|
257340
|
-
cwd: process21.cwd(),
|
|
257341
257376
|
denoWrapperPath: getDenoWrapperPath(),
|
|
257377
|
+
serve,
|
|
257342
257378
|
loadResources: async () => {
|
|
257343
|
-
const { functions, entities, project:
|
|
257344
|
-
|
|
257345
|
-
return { functions, entities, project: project2 };
|
|
257379
|
+
const { functions, entities, project: project3 } = await readProjectConfig();
|
|
257380
|
+
return { functions, entities, project: project3 };
|
|
257346
257381
|
}
|
|
257347
257382
|
});
|
|
257348
|
-
|
|
257349
|
-
|
|
257350
|
-
}
|
|
257351
|
-
return {
|
|
257352
|
-
outroMessage: `Dev server is available at ${theme.colors.links(localServerUrl(resolvedPort))}`
|
|
257353
|
-
};
|
|
257383
|
+
const outroMessage = serveCommand ? "Open your app using the frontend dev server URL" : `Dev server is available at ${theme.colors.links(localServerUrl(resolvedPort))}`;
|
|
257384
|
+
return { outroMessage };
|
|
257354
257385
|
}
|
|
257355
257386
|
function getDevCommand() {
|
|
257356
257387
|
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").action(devAction);
|
|
257357
257388
|
}
|
|
257358
257389
|
|
|
257359
257390
|
// src/core/exec/run-script.ts
|
|
257360
|
-
import { spawn as
|
|
257391
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
257361
257392
|
import { copyFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
257362
257393
|
async function runScript(options8) {
|
|
257363
257394
|
const { appId, code: code2 } = options8;
|
|
@@ -257376,7 +257407,7 @@ async function runScript(options8) {
|
|
|
257376
257407
|
copyFileSync(getExecWrapperPath(), tempWrapper.path);
|
|
257377
257408
|
try {
|
|
257378
257409
|
const exitCode = await new Promise((resolvePromise) => {
|
|
257379
|
-
const child =
|
|
257410
|
+
const child = spawn4("deno", ["run", "--allow-all", "--node-modules-dir=auto", tempWrapper.path], {
|
|
257380
257411
|
env: {
|
|
257381
257412
|
...process.env,
|
|
257382
257413
|
SCRIPT_PATH: scriptPath,
|
|
@@ -257409,10 +257440,7 @@ function readStdin2() {
|
|
|
257409
257440
|
process.stdin.on("error", reject);
|
|
257410
257441
|
});
|
|
257411
257442
|
}
|
|
257412
|
-
async function execAction({
|
|
257413
|
-
app,
|
|
257414
|
-
isNonInteractive
|
|
257415
|
-
}) {
|
|
257443
|
+
async function execAction(isNonInteractive) {
|
|
257416
257444
|
const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
|
|
257417
257445
|
hints: [
|
|
257418
257446
|
{ message: "File: cat ./script.ts | base44 exec" },
|
|
@@ -257428,7 +257456,7 @@ async function execAction({
|
|
|
257428
257456
|
if (!code2.trim()) {
|
|
257429
257457
|
throw noInputError;
|
|
257430
257458
|
}
|
|
257431
|
-
const { exitCode } = await runScript({ appId:
|
|
257459
|
+
const { exitCode } = await runScript({ appId: getAppContext().id, code: code2 });
|
|
257432
257460
|
if (exitCode !== 0) {
|
|
257433
257461
|
process.exitCode = exitCode;
|
|
257434
257462
|
}
|
|
@@ -257441,26 +257469,18 @@ Examples:
|
|
|
257441
257469
|
$ cat ./script.ts | base44 exec
|
|
257442
257470
|
|
|
257443
257471
|
Inline script:
|
|
257444
|
-
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (
|
|
257445
|
-
return await execAction(
|
|
257472
|
+
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async ({ isNonInteractive }) => {
|
|
257473
|
+
return await execAction(isNonInteractive);
|
|
257446
257474
|
});
|
|
257447
257475
|
}
|
|
257448
257476
|
|
|
257449
257477
|
// src/cli/commands/project/eject.ts
|
|
257450
257478
|
import { resolve as resolve12 } from "node:path";
|
|
257451
257479
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
257452
|
-
async function eject(ctx, options8
|
|
257480
|
+
async function eject(ctx, options8) {
|
|
257453
257481
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
257454
|
-
|
|
257455
|
-
|
|
257456
|
-
legacyProjectId,
|
|
257457
|
-
value: selectedAppId
|
|
257458
|
-
} = readExplicitAppId(command2);
|
|
257459
|
-
if (appId && legacyProjectId) {
|
|
257460
|
-
throw new InvalidInputError("--app-id and --project-id cannot be used together");
|
|
257461
|
-
}
|
|
257462
|
-
if (isNonInteractive && !selectedAppId) {
|
|
257463
|
-
throw new InvalidInputError("--app-id is required in non-interactive mode");
|
|
257482
|
+
if (isNonInteractive && !options8.projectId) {
|
|
257483
|
+
throw new InvalidInputError("--project-id is required in non-interactive mode");
|
|
257464
257484
|
}
|
|
257465
257485
|
if (isNonInteractive && !options8.path) {
|
|
257466
257486
|
throw new InvalidInputError("--path is required in non-interactive mode");
|
|
@@ -257468,13 +257488,13 @@ async function eject(ctx, options8, command2) {
|
|
|
257468
257488
|
const projects = await listProjects();
|
|
257469
257489
|
const ejectableProjects = projects.filter((p4) => p4.isManagedSourceCode !== false);
|
|
257470
257490
|
let selectedProject;
|
|
257471
|
-
if (
|
|
257472
|
-
const foundProject = ejectableProjects.find((p4) => p4.id ===
|
|
257491
|
+
if (options8.projectId) {
|
|
257492
|
+
const foundProject = ejectableProjects.find((p4) => p4.id === options8.projectId);
|
|
257473
257493
|
if (!foundProject) {
|
|
257474
|
-
throw new InvalidInputError(`
|
|
257494
|
+
throw new InvalidInputError(`Project with ID "${options8.projectId}" not found or not ejectable`, {
|
|
257475
257495
|
hints: [
|
|
257476
257496
|
{
|
|
257477
|
-
message: "Run 'base44 eject' without --
|
|
257497
|
+
message: "Run 'base44 eject' without --project-id to see available projects"
|
|
257478
257498
|
}
|
|
257479
257499
|
]
|
|
257480
257500
|
});
|
|
@@ -257550,15 +257570,13 @@ async function eject(ctx, options8, command2) {
|
|
|
257550
257570
|
return { outroMessage: "Your new project is set and ready to use" };
|
|
257551
257571
|
}
|
|
257552
257572
|
function getEjectCommand() {
|
|
257553
|
-
return new Base44Command("eject", {
|
|
257554
|
-
requireAppContext: false
|
|
257555
|
-
}).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);
|
|
257573
|
+
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);
|
|
257556
257574
|
}
|
|
257557
257575
|
|
|
257558
257576
|
// src/cli/program.ts
|
|
257559
257577
|
function createProgram(context) {
|
|
257560
257578
|
const program2 = new Command;
|
|
257561
|
-
program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version)
|
|
257579
|
+
program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version);
|
|
257562
257580
|
program2.configureHelp({
|
|
257563
257581
|
sortSubcommands: true
|
|
257564
257582
|
});
|
|
@@ -261795,7 +261813,7 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
|
|
|
261795
261813
|
// src/cli/index.ts
|
|
261796
261814
|
var __dirname4 = dirname23(fileURLToPath6(import.meta.url));
|
|
261797
261815
|
async function runCLI(options8) {
|
|
261798
|
-
ensureNpmAssets(
|
|
261816
|
+
ensureNpmAssets(join28(__dirname4, "../assets"));
|
|
261799
261817
|
const errorReporter = new ErrorReporter;
|
|
261800
261818
|
errorReporter.registerProcessErrorHandlers();
|
|
261801
261819
|
const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
@@ -261832,4 +261850,4 @@ export {
|
|
|
261832
261850
|
CLIExitError
|
|
261833
261851
|
};
|
|
261834
261852
|
|
|
261835
|
-
//# debugId=
|
|
261853
|
+
//# debugId=A70B9CF8A0A7907664756E2164756E21
|