@base44-preview/cli 0.0.55-pr.545.cb11f3a → 0.0.55-pr.546.2cca7dc
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 +163 -180
- package/dist/cli/index.js.map +19 -19
- package/package.json +1 -1
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
|
-
|
|
233984
|
+
BASE44_APP_ID_ENV_VAR,
|
|
233984
233985
|
"BASE44_ACCESS_TOKEN",
|
|
233985
233986
|
"BASE44_REFRESH_TOKEN",
|
|
233986
233987
|
"BASE44_API_URL"
|
|
@@ -234017,7 +234018,7 @@ function normalizeBase44Env() {
|
|
|
234017
234018
|
loadProjectEnvFiles();
|
|
234018
234019
|
|
|
234019
234020
|
// src/cli/index.ts
|
|
234020
|
-
import { dirname as dirname23, join as
|
|
234021
|
+
import { dirname as dirname23, join as join29 } from "node:path";
|
|
234021
234022
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
234022
234023
|
|
|
234023
234024
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -241694,18 +241695,35 @@ function loadFromTestOverrides() {
|
|
|
241694
241695
|
}
|
|
241695
241696
|
return null;
|
|
241696
241697
|
}
|
|
241697
|
-
async function initAppContext() {
|
|
241698
|
+
async function initAppContext(options = {}) {
|
|
241698
241699
|
const testConfig = loadFromTestOverrides();
|
|
241699
241700
|
if (testConfig) {
|
|
241700
241701
|
cache2 = testConfig;
|
|
241701
241702
|
return cache2;
|
|
241702
241703
|
}
|
|
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 };
|
|
241711
|
+
return cache2;
|
|
241712
|
+
}
|
|
241703
241713
|
if (cache2) {
|
|
241704
241714
|
return cache2;
|
|
241705
241715
|
}
|
|
241706
|
-
const projectRoot = findProjectRoot();
|
|
241707
241716
|
if (!projectRoot) {
|
|
241708
|
-
throw new ConfigNotFoundError(
|
|
241717
|
+
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.`, {
|
|
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
|
+
});
|
|
241709
241727
|
}
|
|
241710
241728
|
const config3 = await readAppConfig(projectRoot.root);
|
|
241711
241729
|
const appConfigPath = await findAppConfigPath(projectRoot.root);
|
|
@@ -244433,8 +244451,8 @@ async function ensureAuth(ctx) {
|
|
|
244433
244451
|
});
|
|
244434
244452
|
} catch {}
|
|
244435
244453
|
}
|
|
244436
|
-
async function ensureAppContext(ctx) {
|
|
244437
|
-
const appContext = await initAppContext();
|
|
244454
|
+
async function ensureAppContext(ctx, options = {}) {
|
|
244455
|
+
const appContext = await initAppContext(options);
|
|
244438
244456
|
ctx.app = appContext;
|
|
244439
244457
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
244440
244458
|
}
|
|
@@ -251100,7 +251118,8 @@ class Base44Command extends Command {
|
|
|
251100
251118
|
await ensureAuth(this.context);
|
|
251101
251119
|
}
|
|
251102
251120
|
if (this._commandOptions.requireAppContext) {
|
|
251103
|
-
|
|
251121
|
+
const { appId } = this.optsWithGlobals();
|
|
251122
|
+
await ensureAppContext(this.context, { appId });
|
|
251104
251123
|
}
|
|
251105
251124
|
const result = await fn(this.context, ...args) ?? {};
|
|
251106
251125
|
if (!quiet) {
|
|
@@ -253069,7 +253088,11 @@ function printProjectSummary({ name: name2, dashboardUrl, appUrl }, log) {
|
|
|
253069
253088
|
}
|
|
253070
253089
|
|
|
253071
253090
|
// src/cli/commands/project/create.ts
|
|
253072
|
-
function
|
|
253091
|
+
function validateCreateOptions(command2) {
|
|
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
|
+
}
|
|
253073
253096
|
const { path: path17 } = command2.opts();
|
|
253074
253097
|
if (path17 && !command2.args.length) {
|
|
253075
253098
|
command2.error("--path requires a project name argument. Usage: base44 create <name> --path <path>");
|
|
@@ -253186,7 +253209,7 @@ function getCreateCommand() {
|
|
|
253186
253209
|
Examples:
|
|
253187
253210
|
$ base44 create my-app Creates a base44 project at ./my-app
|
|
253188
253211
|
$ base44 create my-todo-app --template backend-and-client Creates a base44 backend-and-client project at ./my-todo-app
|
|
253189
|
-
$ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction",
|
|
253212
|
+
$ 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);
|
|
253190
253213
|
}
|
|
253191
253214
|
|
|
253192
253215
|
// src/cli/commands/project/deploy.ts
|
|
@@ -253282,11 +253305,32 @@ function printStripeResult(r, log) {
|
|
|
253282
253305
|
log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
253283
253306
|
}
|
|
253284
253307
|
|
|
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
|
+
|
|
253285
253321
|
// src/cli/commands/project/link.ts
|
|
253286
|
-
function
|
|
253287
|
-
const { create: create4, name: name2
|
|
253288
|
-
|
|
253289
|
-
|
|
253322
|
+
function validateNonInteractiveFlags(command2) {
|
|
253323
|
+
const { create: create4, name: name2 } = command2.opts();
|
|
253324
|
+
const {
|
|
253325
|
+
appId,
|
|
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");
|
|
253290
253334
|
}
|
|
253291
253335
|
if (create4 && !name2) {
|
|
253292
253336
|
command2.error("--name is required when using --create");
|
|
@@ -253355,11 +253399,12 @@ async function promptForExistingProject(linkableProjects) {
|
|
|
253355
253399
|
}
|
|
253356
253400
|
return selectedProject;
|
|
253357
253401
|
}
|
|
253358
|
-
async function link(ctx, options) {
|
|
253402
|
+
async function link(ctx, options, command2) {
|
|
253359
253403
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
253360
|
-
const
|
|
253404
|
+
const appId = readExplicitAppId(command2).value;
|
|
253405
|
+
const skipPrompts = !!options.create || !!appId;
|
|
253361
253406
|
if (!skipPrompts && isNonInteractive) {
|
|
253362
|
-
throw new InvalidInputError("--create with --name, or --
|
|
253407
|
+
throw new InvalidInputError("--create with --name, or --app-id, is required in non-interactive mode");
|
|
253363
253408
|
}
|
|
253364
253409
|
const projectRoot = findProjectRoot();
|
|
253365
253410
|
if (!projectRoot) {
|
|
@@ -253374,8 +253419,8 @@ async function link(ctx, options) {
|
|
|
253374
253419
|
]
|
|
253375
253420
|
});
|
|
253376
253421
|
}
|
|
253377
|
-
let
|
|
253378
|
-
const action =
|
|
253422
|
+
let finalAppId;
|
|
253423
|
+
const action = appId ? "choose" : options.create ? "create" : await promptForLinkAction();
|
|
253379
253424
|
if (action === "choose") {
|
|
253380
253425
|
const projects = await runTask2("Fetching projects...", async () => listProjects(), {
|
|
253381
253426
|
successMessage: "Projects fetched",
|
|
@@ -253385,32 +253430,32 @@ async function link(ctx, options) {
|
|
|
253385
253430
|
if (!linkableProjects.length) {
|
|
253386
253431
|
return { outroMessage: "No projects available for linking" };
|
|
253387
253432
|
}
|
|
253388
|
-
let
|
|
253389
|
-
if (
|
|
253390
|
-
const project2 = linkableProjects.find((p) => p.id ===
|
|
253433
|
+
let linkedAppId;
|
|
253434
|
+
if (appId) {
|
|
253435
|
+
const project2 = linkableProjects.find((p) => p.id === appId);
|
|
253391
253436
|
if (!project2) {
|
|
253392
|
-
throw new InvalidInputError(`
|
|
253437
|
+
throw new InvalidInputError(`App with ID "${appId}" not found or not available for linking.`, {
|
|
253393
253438
|
hints: [
|
|
253394
|
-
{ message: "Check the
|
|
253439
|
+
{ message: "Check the app ID is correct" },
|
|
253395
253440
|
{
|
|
253396
|
-
message: "Use 'base44 link' without --
|
|
253441
|
+
message: "Use 'base44 link' without --app-id to see available projects"
|
|
253397
253442
|
}
|
|
253398
253443
|
]
|
|
253399
253444
|
});
|
|
253400
253445
|
}
|
|
253401
|
-
|
|
253446
|
+
linkedAppId = appId;
|
|
253402
253447
|
} else {
|
|
253403
253448
|
const selectedProject = await promptForExistingProject(linkableProjects);
|
|
253404
|
-
|
|
253449
|
+
linkedAppId = selectedProject.id;
|
|
253405
253450
|
}
|
|
253406
253451
|
await runTask2("Linking project...", async () => {
|
|
253407
|
-
await writeAppConfig(projectRoot.root,
|
|
253408
|
-
setAppContext({ id:
|
|
253452
|
+
await writeAppConfig(projectRoot.root, linkedAppId);
|
|
253453
|
+
setAppContext({ id: linkedAppId, projectRoot: projectRoot.root });
|
|
253409
253454
|
}, {
|
|
253410
253455
|
successMessage: "Project linked successfully",
|
|
253411
253456
|
errorMessage: "Failed to link project"
|
|
253412
253457
|
});
|
|
253413
|
-
|
|
253458
|
+
finalAppId = linkedAppId;
|
|
253414
253459
|
}
|
|
253415
253460
|
if (action === "create") {
|
|
253416
253461
|
const { name: name2, description } = options.create ? { name: options.name.trim(), description: options.description?.trim() } : await promptForNewProjectDetails();
|
|
@@ -253422,13 +253467,15 @@ async function link(ctx, options) {
|
|
|
253422
253467
|
});
|
|
253423
253468
|
await writeAppConfig(projectRoot.root, projectId);
|
|
253424
253469
|
setAppContext({ id: projectId, projectRoot: projectRoot.root });
|
|
253425
|
-
|
|
253470
|
+
finalAppId = projectId;
|
|
253426
253471
|
}
|
|
253427
|
-
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(
|
|
253472
|
+
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(finalAppId))}`);
|
|
253428
253473
|
return { outroMessage: "Project linked" };
|
|
253429
253474
|
}
|
|
253430
253475
|
function getLinkCommand() {
|
|
253431
|
-
return new Base44Command("link", {
|
|
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);
|
|
253432
253479
|
}
|
|
253433
253480
|
|
|
253434
253481
|
// src/cli/commands/project/logs.ts
|
|
@@ -253518,8 +253565,12 @@ async function fetchLogsForFunctions(functionNames, options, availableFunctionNa
|
|
|
253518
253565
|
}
|
|
253519
253566
|
return allEntries;
|
|
253520
253567
|
}
|
|
253521
|
-
async function
|
|
253522
|
-
const { functions } = await readProjectConfig();
|
|
253568
|
+
async function getProjectFunctionNames(projectRoot) {
|
|
253569
|
+
const { functions } = await readProjectConfig(projectRoot);
|
|
253570
|
+
return functions.map((fn) => fn.name);
|
|
253571
|
+
}
|
|
253572
|
+
async function getRemoteFunctionNames() {
|
|
253573
|
+
const { functions } = await listDeployedFunctions();
|
|
253523
253574
|
return functions.map((fn) => fn.name);
|
|
253524
253575
|
}
|
|
253525
253576
|
function validateLimit(limit) {
|
|
@@ -253530,15 +253581,18 @@ function validateLimit(limit) {
|
|
|
253530
253581
|
throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
|
|
253531
253582
|
}
|
|
253532
253583
|
}
|
|
253533
|
-
async function logsAction(
|
|
253584
|
+
async function logsAction(ctx, options) {
|
|
253534
253585
|
validateLimit(options.limit);
|
|
253535
253586
|
const specifiedFunctions = parseFunctionNames(options.function);
|
|
253536
|
-
const
|
|
253537
|
-
const
|
|
253587
|
+
const localProjectRoot = ctx.app?.projectRoot;
|
|
253588
|
+
const availableFunctionNames = localProjectRoot ? await getProjectFunctionNames(localProjectRoot) : await getRemoteFunctionNames();
|
|
253589
|
+
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : availableFunctionNames;
|
|
253538
253590
|
if (functionNames.length === 0) {
|
|
253539
|
-
return {
|
|
253591
|
+
return {
|
|
253592
|
+
outroMessage: localProjectRoot ? "No functions found in this project." : "No functions found in this app."
|
|
253593
|
+
};
|
|
253540
253594
|
}
|
|
253541
|
-
let entries = await fetchLogsForFunctions(functionNames, options,
|
|
253595
|
+
let entries = await fetchLogsForFunctions(functionNames, options, availableFunctionNames);
|
|
253542
253596
|
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
253543
253597
|
if (limit !== undefined && entries.length > limit) {
|
|
253544
253598
|
entries = entries.slice(0, limit);
|
|
@@ -253554,17 +253608,20 @@ function getLogsCommand() {
|
|
|
253554
253608
|
// src/cli/commands/project/scaffold.ts
|
|
253555
253609
|
import { basename as basename5, resolve as resolve6 } from "node:path";
|
|
253556
253610
|
function resolveAppId(options) {
|
|
253557
|
-
const appId = options.appId
|
|
253611
|
+
const appId = options.appId;
|
|
253558
253612
|
if (!appId) {
|
|
253559
253613
|
throw new InvalidInputError("No app ID found. `base44 scaffold` sets up a local project for an existing Base44 app.", {
|
|
253560
|
-
hints: [
|
|
253614
|
+
hints: [
|
|
253615
|
+
{ message: "Pass it explicitly with --app-id <id>" },
|
|
253616
|
+
{ message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` }
|
|
253617
|
+
]
|
|
253561
253618
|
});
|
|
253562
253619
|
}
|
|
253563
253620
|
return appId;
|
|
253564
253621
|
}
|
|
253565
|
-
async function scaffoldAction(ctx, name2, options) {
|
|
253622
|
+
async function scaffoldAction(ctx, name2, options, command2) {
|
|
253566
253623
|
const { log, runTask: runTask2 } = ctx;
|
|
253567
|
-
const appId = resolveAppId(
|
|
253624
|
+
const appId = resolveAppId(command2.optsWithGlobals());
|
|
253568
253625
|
const resolvedPath = resolve6("./");
|
|
253569
253626
|
const projectName = (name2 ?? basename5(resolvedPath)).trim();
|
|
253570
253627
|
const template2 = await getTemplateById("backend-only");
|
|
@@ -253596,7 +253653,7 @@ function getScaffoldCommand() {
|
|
|
253596
253653
|
return new Base44Command("scaffold", {
|
|
253597
253654
|
requireAppContext: false,
|
|
253598
253655
|
fullBanner: true
|
|
253599
|
-
}).description("Scaffold a local project for an existing Base44 app").addArgument(new Argument("name", "Project name").argOptional()).option("--
|
|
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", `
|
|
253600
253657
|
Examples:
|
|
253601
253658
|
$ base44 scaffold --app-id app_123 Scaffolds the current dir for the given app
|
|
253602
253659
|
$ base44 scaffold my-app --app-id app_123 Scaffolds the current dir, named "my-app"`).action(scaffoldAction);
|
|
@@ -253896,6 +253953,10 @@ function getTypesCommand() {
|
|
|
253896
253953
|
return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
253897
253954
|
}
|
|
253898
253955
|
|
|
253956
|
+
// src/cli/commands/dev.ts
|
|
253957
|
+
import { join as join28 } from "node:path";
|
|
253958
|
+
import process21 from "node:process";
|
|
253959
|
+
|
|
253899
253960
|
// src/cli/dev/dev-server/main.ts
|
|
253900
253961
|
var import_cors = __toESM(require_lib4(), 1);
|
|
253901
253962
|
var import_express6 = __toESM(require_express(), 1);
|
|
@@ -254051,11 +254112,12 @@ var stringify = (item) => {
|
|
|
254051
254112
|
return String(item);
|
|
254052
254113
|
}
|
|
254053
254114
|
};
|
|
254054
|
-
function createDevLogger(
|
|
254055
|
-
const prefix = label2 ? `${labelColor(`[${label2}]`)} ` : "";
|
|
254115
|
+
function createDevLogger() {
|
|
254056
254116
|
const print = (type, ...args) => {
|
|
254057
254117
|
const colorize = colorByType[type];
|
|
254058
|
-
console[type](
|
|
254118
|
+
console[type](...args.map((item) => {
|
|
254119
|
+
return colorize(stringify(item));
|
|
254120
|
+
}));
|
|
254059
254121
|
};
|
|
254060
254122
|
return {
|
|
254061
254123
|
log: (...args) => print("log", ...args),
|
|
@@ -255422,92 +255484,6 @@ function createCustomIntegrationRoutes(remoteProxy, logger2) {
|
|
|
255422
255484
|
return router;
|
|
255423
255485
|
}
|
|
255424
255486
|
|
|
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
|
-
|
|
255511
255487
|
// src/cli/dev/dev-server/watcher.ts
|
|
255512
255488
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
255513
255489
|
import { relative as relative6 } from "node:path";
|
|
@@ -257231,7 +257207,7 @@ async function createDevServer(options8) {
|
|
|
257231
257207
|
}
|
|
257232
257208
|
next();
|
|
257233
257209
|
});
|
|
257234
|
-
const devLogger = createDevLogger(
|
|
257210
|
+
const devLogger = createDevLogger();
|
|
257235
257211
|
const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
|
|
257236
257212
|
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
257237
257213
|
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
@@ -257329,34 +257305,14 @@ async function createDevServer(options8) {
|
|
|
257329
257305
|
}
|
|
257330
257306
|
});
|
|
257331
257307
|
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
|
-
}
|
|
257344
257308
|
const shutdown = async () => {
|
|
257345
257309
|
base44ConfigWatcher.close();
|
|
257346
257310
|
io6.close();
|
|
257347
257311
|
await functionManager.stopAll();
|
|
257348
|
-
await serveRunner?.stop();
|
|
257349
257312
|
server.close();
|
|
257350
257313
|
};
|
|
257351
257314
|
process.on("SIGINT", shutdown);
|
|
257352
257315
|
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
|
-
}
|
|
257360
257316
|
return { port, server };
|
|
257361
257317
|
}
|
|
257362
257318
|
|
|
@@ -257364,30 +257320,44 @@ async function createDevServer(options8) {
|
|
|
257364
257320
|
function localServerUrl(port) {
|
|
257365
257321
|
return `http://localhost:${port}`;
|
|
257366
257322
|
}
|
|
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
|
+
}
|
|
257367
257334
|
async function devAction({ log }, options8) {
|
|
257368
257335
|
const port = options8.port ? Number(options8.port) : undefined;
|
|
257369
|
-
|
|
257370
|
-
const serveCommand = project2.site?.serveCommand;
|
|
257371
|
-
const appId = serveCommand ? (await initAppContext()).id : undefined;
|
|
257336
|
+
let projectRoot;
|
|
257372
257337
|
const { port: resolvedPort } = await createDevServer({
|
|
257373
257338
|
log,
|
|
257374
257339
|
port,
|
|
257340
|
+
cwd: process21.cwd(),
|
|
257375
257341
|
denoWrapperPath: getDenoWrapperPath(),
|
|
257376
|
-
serve: serveCommand && appId ? { command: serveCommand, cwd: project2.root, appId } : undefined,
|
|
257377
257342
|
loadResources: async () => {
|
|
257378
|
-
const { functions, entities, project:
|
|
257379
|
-
|
|
257343
|
+
const { functions, entities, project: project2 } = await readProjectConfig();
|
|
257344
|
+
projectRoot = project2.root;
|
|
257345
|
+
return { functions, entities, project: project2 };
|
|
257380
257346
|
}
|
|
257381
257347
|
});
|
|
257382
|
-
|
|
257383
|
-
|
|
257348
|
+
if (projectRoot) {
|
|
257349
|
+
await writeEnvLocalIfMissing(projectRoot, resolvedPort, log);
|
|
257350
|
+
}
|
|
257351
|
+
return {
|
|
257352
|
+
outroMessage: `Dev server is available at ${theme.colors.links(localServerUrl(resolvedPort))}`
|
|
257353
|
+
};
|
|
257384
257354
|
}
|
|
257385
257355
|
function getDevCommand() {
|
|
257386
257356
|
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").action(devAction);
|
|
257387
257357
|
}
|
|
257388
257358
|
|
|
257389
257359
|
// src/core/exec/run-script.ts
|
|
257390
|
-
import { spawn as
|
|
257360
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
257391
257361
|
import { copyFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
257392
257362
|
async function runScript(options8) {
|
|
257393
257363
|
const { appId, code: code2 } = options8;
|
|
@@ -257406,7 +257376,7 @@ async function runScript(options8) {
|
|
|
257406
257376
|
copyFileSync(getExecWrapperPath(), tempWrapper.path);
|
|
257407
257377
|
try {
|
|
257408
257378
|
const exitCode = await new Promise((resolvePromise) => {
|
|
257409
|
-
const child =
|
|
257379
|
+
const child = spawn3("deno", ["run", "--allow-all", "--node-modules-dir=auto", tempWrapper.path], {
|
|
257410
257380
|
env: {
|
|
257411
257381
|
...process.env,
|
|
257412
257382
|
SCRIPT_PATH: scriptPath,
|
|
@@ -257439,7 +257409,10 @@ function readStdin2() {
|
|
|
257439
257409
|
process.stdin.on("error", reject);
|
|
257440
257410
|
});
|
|
257441
257411
|
}
|
|
257442
|
-
async function execAction(
|
|
257412
|
+
async function execAction({
|
|
257413
|
+
app,
|
|
257414
|
+
isNonInteractive
|
|
257415
|
+
}) {
|
|
257443
257416
|
const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
|
|
257444
257417
|
hints: [
|
|
257445
257418
|
{ message: "File: cat ./script.ts | base44 exec" },
|
|
@@ -257455,7 +257428,7 @@ async function execAction(isNonInteractive) {
|
|
|
257455
257428
|
if (!code2.trim()) {
|
|
257456
257429
|
throw noInputError;
|
|
257457
257430
|
}
|
|
257458
|
-
const { exitCode } = await runScript({ appId:
|
|
257431
|
+
const { exitCode } = await runScript({ appId: app.id, code: code2 });
|
|
257459
257432
|
if (exitCode !== 0) {
|
|
257460
257433
|
process.exitCode = exitCode;
|
|
257461
257434
|
}
|
|
@@ -257468,18 +257441,26 @@ Examples:
|
|
|
257468
257441
|
$ cat ./script.ts | base44 exec
|
|
257469
257442
|
|
|
257470
257443
|
Inline script:
|
|
257471
|
-
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (
|
|
257472
|
-
return await execAction(
|
|
257444
|
+
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (ctx) => {
|
|
257445
|
+
return await execAction(ctx);
|
|
257473
257446
|
});
|
|
257474
257447
|
}
|
|
257475
257448
|
|
|
257476
257449
|
// src/cli/commands/project/eject.ts
|
|
257477
257450
|
import { resolve as resolve12 } from "node:path";
|
|
257478
257451
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
257479
|
-
async function eject(ctx, options8) {
|
|
257452
|
+
async function eject(ctx, options8, command2) {
|
|
257480
257453
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
257481
|
-
|
|
257482
|
-
|
|
257454
|
+
const {
|
|
257455
|
+
appId,
|
|
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");
|
|
257483
257464
|
}
|
|
257484
257465
|
if (isNonInteractive && !options8.path) {
|
|
257485
257466
|
throw new InvalidInputError("--path is required in non-interactive mode");
|
|
@@ -257487,13 +257468,13 @@ async function eject(ctx, options8) {
|
|
|
257487
257468
|
const projects = await listProjects();
|
|
257488
257469
|
const ejectableProjects = projects.filter((p4) => p4.isManagedSourceCode !== false);
|
|
257489
257470
|
let selectedProject;
|
|
257490
|
-
if (
|
|
257491
|
-
const foundProject = ejectableProjects.find((p4) => p4.id ===
|
|
257471
|
+
if (selectedAppId) {
|
|
257472
|
+
const foundProject = ejectableProjects.find((p4) => p4.id === selectedAppId);
|
|
257492
257473
|
if (!foundProject) {
|
|
257493
|
-
throw new InvalidInputError(`
|
|
257474
|
+
throw new InvalidInputError(`App with ID "${selectedAppId}" not found or not ejectable`, {
|
|
257494
257475
|
hints: [
|
|
257495
257476
|
{
|
|
257496
|
-
message: "Run 'base44 eject' without --
|
|
257477
|
+
message: "Run 'base44 eject' without --app-id to see available projects"
|
|
257497
257478
|
}
|
|
257498
257479
|
]
|
|
257499
257480
|
});
|
|
@@ -257569,13 +257550,15 @@ async function eject(ctx, options8) {
|
|
|
257569
257550
|
return { outroMessage: "Your new project is set and ready to use" };
|
|
257570
257551
|
}
|
|
257571
257552
|
function getEjectCommand() {
|
|
257572
|
-
return new Base44Command("eject", {
|
|
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
257556
|
}
|
|
257574
257557
|
|
|
257575
257558
|
// src/cli/program.ts
|
|
257576
257559
|
function createProgram(context) {
|
|
257577
257560
|
const program2 = new Command;
|
|
257578
|
-
program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version);
|
|
257561
|
+
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));
|
|
257579
257562
|
program2.configureHelp({
|
|
257580
257563
|
sortSubcommands: true
|
|
257581
257564
|
});
|
|
@@ -261812,7 +261795,7 @@ function addCommandInfoToErrorReporter(program2, errorReporter) {
|
|
|
261812
261795
|
// src/cli/index.ts
|
|
261813
261796
|
var __dirname4 = dirname23(fileURLToPath6(import.meta.url));
|
|
261814
261797
|
async function runCLI(options8) {
|
|
261815
|
-
ensureNpmAssets(
|
|
261798
|
+
ensureNpmAssets(join29(__dirname4, "../assets"));
|
|
261816
261799
|
const errorReporter = new ErrorReporter;
|
|
261817
261800
|
errorReporter.registerProcessErrorHandlers();
|
|
261818
261801
|
const isNonInteractive = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
@@ -261849,4 +261832,4 @@ export {
|
|
|
261849
261832
|
CLIExitError
|
|
261850
261833
|
};
|
|
261851
261834
|
|
|
261852
|
-
//# debugId=
|
|
261835
|
+
//# debugId=01B7F20ACA5BBEAF64756E2164756E21
|