@base44-preview/cli 0.0.13-pr.86.f208957 → 0.0.13-pr.87.2565e16
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 +180 -51
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -26329,6 +26329,58 @@ async function printBanner() {
|
|
|
26329
26329
|
else console.log(theme.colors.base44Orange(BANNER_LINES.join("\n")));
|
|
26330
26330
|
}
|
|
26331
26331
|
|
|
26332
|
+
//#endregion
|
|
26333
|
+
//#region src/cli/utils/json.ts
|
|
26334
|
+
/**
|
|
26335
|
+
* JSON output utilities for CLI commands.
|
|
26336
|
+
*
|
|
26337
|
+
* These utilities support the `--json` flag which outputs machine-readable JSON
|
|
26338
|
+
* instead of human-friendly formatted output.
|
|
26339
|
+
*/
|
|
26340
|
+
let jsonModeEnabled = false;
|
|
26341
|
+
/**
|
|
26342
|
+
* Enable JSON output mode. Called by runCommand when --json flag is detected.
|
|
26343
|
+
*/
|
|
26344
|
+
function setJsonMode(enabled) {
|
|
26345
|
+
jsonModeEnabled = enabled;
|
|
26346
|
+
}
|
|
26347
|
+
/**
|
|
26348
|
+
* Check if JSON output mode is currently active.
|
|
26349
|
+
*/
|
|
26350
|
+
function isJsonMode() {
|
|
26351
|
+
return jsonModeEnabled;
|
|
26352
|
+
}
|
|
26353
|
+
/**
|
|
26354
|
+
* Output a success JSON response to stdout.
|
|
26355
|
+
* Only outputs if JSON mode is enabled.
|
|
26356
|
+
*/
|
|
26357
|
+
function outputJson(data) {
|
|
26358
|
+
if (!jsonModeEnabled) return;
|
|
26359
|
+
const response = {
|
|
26360
|
+
success: true,
|
|
26361
|
+
data
|
|
26362
|
+
};
|
|
26363
|
+
console.log(JSON.stringify(response, null, 2));
|
|
26364
|
+
}
|
|
26365
|
+
/**
|
|
26366
|
+
* Output an error JSON response to stderr.
|
|
26367
|
+
* Only outputs if JSON mode is enabled.
|
|
26368
|
+
*
|
|
26369
|
+
* @param error - The error to output
|
|
26370
|
+
* @param code - Optional error code
|
|
26371
|
+
*/
|
|
26372
|
+
function outputJsonError(error, code$1) {
|
|
26373
|
+
if (!jsonModeEnabled) return;
|
|
26374
|
+
const response = {
|
|
26375
|
+
success: false,
|
|
26376
|
+
error: {
|
|
26377
|
+
message: error instanceof Error ? error.message : error,
|
|
26378
|
+
...code$1 && { code: code$1 }
|
|
26379
|
+
}
|
|
26380
|
+
};
|
|
26381
|
+
console.error(JSON.stringify(response, null, 2));
|
|
26382
|
+
}
|
|
26383
|
+
|
|
26332
26384
|
//#endregion
|
|
26333
26385
|
//#region src/cli/utils/runCommand.ts
|
|
26334
26386
|
/**
|
|
@@ -26370,25 +26422,35 @@ async function printBanner() {
|
|
|
26370
26422
|
* });
|
|
26371
26423
|
*/
|
|
26372
26424
|
async function runCommand(commandFn, options) {
|
|
26373
|
-
|
|
26374
|
-
if (
|
|
26375
|
-
|
|
26376
|
-
|
|
26377
|
-
|
|
26425
|
+
const jsonMode = isJsonMode();
|
|
26426
|
+
if (!jsonMode) {
|
|
26427
|
+
console.log();
|
|
26428
|
+
if (options?.fullBanner) {
|
|
26429
|
+
await printBanner();
|
|
26430
|
+
Ie("");
|
|
26431
|
+
} else Ie(theme.colors.base44OrangeBackground(" Base 44 "));
|
|
26432
|
+
}
|
|
26378
26433
|
await loadProjectEnv();
|
|
26379
26434
|
try {
|
|
26380
26435
|
if (options?.requireAuth) {
|
|
26381
26436
|
if (!await isLoggedIn()) {
|
|
26437
|
+
if (jsonMode) throw new Error("Authentication required. Please run 'base44 login' first.");
|
|
26382
26438
|
M.info("You need to login first to continue.");
|
|
26383
26439
|
await login();
|
|
26384
26440
|
}
|
|
26385
26441
|
}
|
|
26386
|
-
const { outroMessage } = await commandFn();
|
|
26387
|
-
|
|
26442
|
+
const { outroMessage, data } = await commandFn();
|
|
26443
|
+
if (jsonMode) outputJson(data ?? {});
|
|
26444
|
+
else Se(outroMessage || "");
|
|
26388
26445
|
} catch (e$1) {
|
|
26389
|
-
if (
|
|
26390
|
-
|
|
26391
|
-
|
|
26446
|
+
if (jsonMode) {
|
|
26447
|
+
outputJsonError(e$1 instanceof Error ? e$1 : String(e$1));
|
|
26448
|
+
process.exit(1);
|
|
26449
|
+
} else {
|
|
26450
|
+
if (e$1 instanceof Error) M.error(e$1.stack ?? e$1.message);
|
|
26451
|
+
else M.error(String(e$1));
|
|
26452
|
+
process.exit(1);
|
|
26453
|
+
}
|
|
26392
26454
|
}
|
|
26393
26455
|
}
|
|
26394
26456
|
|
|
@@ -26398,6 +26460,8 @@ async function runCommand(commandFn, options) {
|
|
|
26398
26460
|
* Wraps an async operation with automatic spinner management.
|
|
26399
26461
|
* The spinner is automatically started, and stopped on both success and error.
|
|
26400
26462
|
*
|
|
26463
|
+
* In JSON mode, the spinner is suppressed and the operation runs silently.
|
|
26464
|
+
*
|
|
26401
26465
|
* @param startMessage - Message to show when spinner starts
|
|
26402
26466
|
* @param operation - The async operation to execute. Receives an updateMessage function
|
|
26403
26467
|
* to update the spinner text during long-running operations.
|
|
@@ -26433,6 +26497,10 @@ async function runCommand(commandFn, options) {
|
|
|
26433
26497
|
* );
|
|
26434
26498
|
*/
|
|
26435
26499
|
async function runTask(startMessage, operation, options) {
|
|
26500
|
+
if (isJsonMode()) {
|
|
26501
|
+
const noopUpdateMessage = () => {};
|
|
26502
|
+
return await operation(noopUpdateMessage);
|
|
26503
|
+
}
|
|
26436
26504
|
const s = Y();
|
|
26437
26505
|
s.start(startMessage);
|
|
26438
26506
|
const updateMessage = (message) => s.message(message);
|
|
@@ -26459,6 +26527,10 @@ const onPromptCancel = () => {
|
|
|
26459
26527
|
|
|
26460
26528
|
//#endregion
|
|
26461
26529
|
//#region src/cli/commands/auth/login.ts
|
|
26530
|
+
/**
|
|
26531
|
+
* Login command does not support --json output.
|
|
26532
|
+
* It requires interactive browser authentication via device code flow.
|
|
26533
|
+
*/
|
|
26462
26534
|
async function generateAndDisplayDeviceCode() {
|
|
26463
26535
|
const deviceCodeResponse = await runTask("Generating device code...", async () => {
|
|
26464
26536
|
return await generateDeviceCode();
|
|
@@ -26520,7 +26592,13 @@ const loginCommand = new Command("login").description("Authenticate with Base44"
|
|
|
26520
26592
|
//#region src/cli/commands/auth/whoami.ts
|
|
26521
26593
|
async function whoami() {
|
|
26522
26594
|
const auth = await readAuth();
|
|
26523
|
-
return {
|
|
26595
|
+
return {
|
|
26596
|
+
outroMessage: `Logged in as: ${theme.styles.bold(auth.email)}`,
|
|
26597
|
+
data: {
|
|
26598
|
+
email: auth.email,
|
|
26599
|
+
name: auth.name
|
|
26600
|
+
}
|
|
26601
|
+
};
|
|
26524
26602
|
}
|
|
26525
26603
|
const whoamiCommand = new Command("whoami").description("Display current authenticated user").action(async () => {
|
|
26526
26604
|
await runCommand(whoami, { requireAuth: true });
|
|
@@ -26528,6 +26606,10 @@ const whoamiCommand = new Command("whoami").description("Display current authent
|
|
|
26528
26606
|
|
|
26529
26607
|
//#endregion
|
|
26530
26608
|
//#region src/cli/commands/auth/logout.ts
|
|
26609
|
+
/**
|
|
26610
|
+
* Logout command does not support --json output.
|
|
26611
|
+
* It is a user-facing auth command that is rarely scripted.
|
|
26612
|
+
*/
|
|
26531
26613
|
async function logout() {
|
|
26532
26614
|
await deleteAuth();
|
|
26533
26615
|
return { outroMessage: "Logged out successfully" };
|
|
@@ -31523,18 +31605,31 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
31523
31605
|
//#region src/cli/commands/entities/push.ts
|
|
31524
31606
|
async function pushEntitiesAction() {
|
|
31525
31607
|
const { entities } = await readProjectConfig();
|
|
31526
|
-
if (entities.length === 0) return {
|
|
31527
|
-
|
|
31608
|
+
if (entities.length === 0) return {
|
|
31609
|
+
outroMessage: "No entities found in project",
|
|
31610
|
+
data: {
|
|
31611
|
+
created: [],
|
|
31612
|
+
updated: [],
|
|
31613
|
+
deleted: []
|
|
31614
|
+
}
|
|
31615
|
+
};
|
|
31616
|
+
if (!isJsonMode()) M.info(`Found ${entities.length} entities to push`);
|
|
31528
31617
|
const result = await runTask("Pushing entities to Base44", async () => {
|
|
31529
31618
|
return await pushEntities(entities);
|
|
31530
31619
|
}, {
|
|
31531
31620
|
successMessage: "Entities pushed successfully",
|
|
31532
31621
|
errorMessage: "Failed to push entities"
|
|
31533
31622
|
});
|
|
31534
|
-
if (
|
|
31535
|
-
|
|
31536
|
-
|
|
31537
|
-
|
|
31623
|
+
if (!isJsonMode()) {
|
|
31624
|
+
if (result.created.length > 0) M.success(`Created: ${result.created.join(", ")}`);
|
|
31625
|
+
if (result.updated.length > 0) M.success(`Updated: ${result.updated.join(", ")}`);
|
|
31626
|
+
if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
31627
|
+
}
|
|
31628
|
+
return { data: {
|
|
31629
|
+
created: result.created,
|
|
31630
|
+
updated: result.updated,
|
|
31631
|
+
deleted: result.deleted
|
|
31632
|
+
} };
|
|
31538
31633
|
}
|
|
31539
31634
|
const entitiesPushCommand = new Command("entities").description("Manage project entities").addCommand(new Command("push").description("Push local entities to Base44").action(async () => {
|
|
31540
31635
|
await runCommand(pushEntitiesAction, { requireAuth: true });
|
|
@@ -31544,21 +31639,32 @@ const entitiesPushCommand = new Command("entities").description("Manage project
|
|
|
31544
31639
|
//#region src/cli/commands/functions/deploy.ts
|
|
31545
31640
|
async function deployFunctionsAction() {
|
|
31546
31641
|
const { functions } = await readProjectConfig();
|
|
31547
|
-
if (functions.length === 0) return {
|
|
31548
|
-
|
|
31642
|
+
if (functions.length === 0) return {
|
|
31643
|
+
outroMessage: "No functions found. Create functions in the 'functions' directory.",
|
|
31644
|
+
data: {
|
|
31645
|
+
deployed: [],
|
|
31646
|
+
deleted: []
|
|
31647
|
+
}
|
|
31648
|
+
};
|
|
31649
|
+
if (!isJsonMode()) M.info(`Found ${functions.length} ${functions.length === 1 ? "function" : "functions"} to deploy`);
|
|
31549
31650
|
const result = await runTask("Deploying functions to Base44", async () => {
|
|
31550
31651
|
return await pushFunctions(functions);
|
|
31551
31652
|
}, {
|
|
31552
31653
|
successMessage: "Functions deployed successfully",
|
|
31553
31654
|
errorMessage: "Failed to deploy functions"
|
|
31554
31655
|
});
|
|
31555
|
-
if (
|
|
31556
|
-
|
|
31656
|
+
if (!isJsonMode()) {
|
|
31657
|
+
if (result.deployed.length > 0) M.success(`Deployed: ${result.deployed.join(", ")}`);
|
|
31658
|
+
if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
31659
|
+
}
|
|
31557
31660
|
if (result.errors && result.errors.length > 0) {
|
|
31558
31661
|
const errorMessages = result.errors.map((e$1) => `'${e$1.name}' function: ${e$1.message}`).join("\n");
|
|
31559
31662
|
throw new Error(`Function deployment errors:\n${errorMessages}`);
|
|
31560
31663
|
}
|
|
31561
|
-
return {
|
|
31664
|
+
return { data: {
|
|
31665
|
+
deployed: result.deployed,
|
|
31666
|
+
deleted: result.deleted
|
|
31667
|
+
} };
|
|
31562
31668
|
}
|
|
31563
31669
|
const functionsDeployCommand = new Command("functions").description("Manage project functions").addCommand(new Command("deploy").description("Deploy local functions to Base44").action(async () => {
|
|
31564
31670
|
await runCommand(deployFunctionsAction, { requireAuth: true });
|
|
@@ -38238,18 +38344,10 @@ async function getDefaultTemplate() {
|
|
|
38238
38344
|
if (!template) throw new Error(`Default template "${DEFAULT_TEMPLATE_ID}" not found`);
|
|
38239
38345
|
return template;
|
|
38240
38346
|
}
|
|
38241
|
-
async function getTemplateById(templateId) {
|
|
38242
|
-
const templates = await listTemplates();
|
|
38243
|
-
const template = templates.find((t) => t.id === templateId);
|
|
38244
|
-
if (!template) {
|
|
38245
|
-
const validIds = templates.map((t) => t.id).join(", ");
|
|
38246
|
-
throw new Error(`Template "${templateId}" not found. Available templates: ${validIds}`);
|
|
38247
|
-
}
|
|
38248
|
-
return template;
|
|
38249
|
-
}
|
|
38250
38347
|
function validateNonInteractiveFlags$1(command) {
|
|
38251
|
-
const { name: name$1, path: path$17 } = command.
|
|
38348
|
+
const { name: name$1, path: path$17, json } = command.optsWithGlobals();
|
|
38252
38349
|
const providedCount = [name$1, path$17].filter(Boolean).length;
|
|
38350
|
+
if (json && providedCount < 2) command.error("JSON mode requires all flags: --name, --path");
|
|
38253
38351
|
if (providedCount > 0 && providedCount < 2) command.error("Non-interactive mode requires all flags: --name, --path");
|
|
38254
38352
|
}
|
|
38255
38353
|
async function chooseCreate(options) {
|
|
@@ -38301,7 +38399,7 @@ async function createInteractive(options) {
|
|
|
38301
38399
|
}
|
|
38302
38400
|
async function createNonInteractive(options) {
|
|
38303
38401
|
return await executeCreate({
|
|
38304
|
-
template:
|
|
38402
|
+
template: await getDefaultTemplate(),
|
|
38305
38403
|
name: options.name,
|
|
38306
38404
|
description: options.description,
|
|
38307
38405
|
projectPath: options.path,
|
|
@@ -38367,12 +38465,22 @@ async function executeCreate({ template, name: rawName, description, projectPath
|
|
|
38367
38465
|
}
|
|
38368
38466
|
}
|
|
38369
38467
|
const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/preview`;
|
|
38370
|
-
|
|
38371
|
-
|
|
38372
|
-
|
|
38373
|
-
|
|
38468
|
+
if (!isJsonMode()) {
|
|
38469
|
+
M.message(`${theme.styles.header("Project")}: ${theme.colors.base44Orange(name$1)}`);
|
|
38470
|
+
M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
38471
|
+
if (finalAppUrl) M.message(`${theme.styles.header("Site")}: ${theme.colors.links(finalAppUrl)}`);
|
|
38472
|
+
}
|
|
38473
|
+
return {
|
|
38474
|
+
outroMessage: "Your project is set up and ready to use",
|
|
38475
|
+
data: {
|
|
38476
|
+
projectId,
|
|
38477
|
+
path: resolvedPath,
|
|
38478
|
+
dashboardUrl,
|
|
38479
|
+
...finalAppUrl && { appUrl: finalAppUrl }
|
|
38480
|
+
}
|
|
38481
|
+
};
|
|
38374
38482
|
}
|
|
38375
|
-
const createCommand = new Command("create").description("Create a new Base44 project").option("-n, --name <name>", "Project name").option("-d, --description <description>", "Project description").option("-p, --path <path>", "Path where to create the project").option("
|
|
38483
|
+
const createCommand = new Command("create").description("Create a new Base44 project").option("-n, --name <name>", "Project name").option("-d, --description <description>", "Project description").option("-p, --path <path>", "Path where to create the project").option("--deploy", "Build and deploy the site").hook("preAction", validateNonInteractiveFlags$1).action(async (options) => {
|
|
38376
38484
|
await chooseCreate(options);
|
|
38377
38485
|
});
|
|
38378
38486
|
|
|
@@ -38917,22 +39025,27 @@ var open_default = open;
|
|
|
38917
39025
|
|
|
38918
39026
|
//#endregion
|
|
38919
39027
|
//#region src/cli/commands/project/dashboard.ts
|
|
38920
|
-
async function openDashboard() {
|
|
39028
|
+
async function openDashboard(options) {
|
|
38921
39029
|
await loadProjectEnv();
|
|
38922
39030
|
const projectId = getBase44ClientId();
|
|
38923
39031
|
if (!projectId) throw new Error("App not configured. BASE44_CLIENT_ID environment variable is required. Set it in your .env.local file.");
|
|
38924
39032
|
const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/workspace/overview`;
|
|
38925
|
-
|
|
38926
|
-
|
|
39033
|
+
const shouldOpen = !isJsonMode() && !options.noOpen;
|
|
39034
|
+
if (shouldOpen) await open_default(dashboardUrl);
|
|
39035
|
+
return {
|
|
39036
|
+
outroMessage: shouldOpen ? `Dashboard opened at ${dashboardUrl}` : `Dashboard URL: ${dashboardUrl}`,
|
|
39037
|
+
data: { dashboardUrl }
|
|
39038
|
+
};
|
|
38927
39039
|
}
|
|
38928
|
-
const dashboardCommand = new Command("dashboard").description("Open the app dashboard in your browser").action(async () => {
|
|
38929
|
-
await runCommand(openDashboard, { requireAuth: true });
|
|
39040
|
+
const dashboardCommand = new Command("dashboard").description("Open the app dashboard in your browser").option("--no-open", "Print the URL without opening the browser").action(async (options) => {
|
|
39041
|
+
await runCommand(() => openDashboard(options), { requireAuth: true });
|
|
38930
39042
|
});
|
|
38931
39043
|
|
|
38932
39044
|
//#endregion
|
|
38933
39045
|
//#region src/cli/commands/project/link.ts
|
|
38934
39046
|
function validateNonInteractiveFlags(command) {
|
|
38935
|
-
const { create: create$1, name: name$1 } = command.
|
|
39047
|
+
const { create: create$1, name: name$1, json } = command.optsWithGlobals();
|
|
39048
|
+
if (json && (!create$1 || !name$1)) command.error("JSON mode requires flags: --create, --name");
|
|
38936
39049
|
if (create$1 && !name$1) command.error("--name is required when using --create");
|
|
38937
39050
|
}
|
|
38938
39051
|
async function promptForProjectDetails() {
|
|
@@ -38981,8 +39094,14 @@ async function link(options) {
|
|
|
38981
39094
|
});
|
|
38982
39095
|
await writeEnvLocal(projectRoot.root, projectId);
|
|
38983
39096
|
const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/workspace/overview`;
|
|
38984
|
-
M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
38985
|
-
return {
|
|
39097
|
+
if (!isJsonMode()) M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
39098
|
+
return {
|
|
39099
|
+
outroMessage: "Project linked",
|
|
39100
|
+
data: {
|
|
39101
|
+
projectId,
|
|
39102
|
+
dashboardUrl
|
|
39103
|
+
}
|
|
39104
|
+
};
|
|
38986
39105
|
}
|
|
38987
39106
|
const linkCommand = new Command("link").description("Link a local project to a Base44 project").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").hook("preAction", validateNonInteractiveFlags).action(async (options) => {
|
|
38988
39107
|
await runCommand(() => link(options), { requireAuth: true });
|
|
@@ -38994,16 +39113,23 @@ async function deployAction(options) {
|
|
|
38994
39113
|
const { project } = await readProjectConfig();
|
|
38995
39114
|
if (!project.site?.outputDirectory) throw new Error("No site configuration found. Please add 'site.outputDirectory' to your config.jsonc");
|
|
38996
39115
|
const outputDir = resolve(project.root, project.site.outputDirectory);
|
|
38997
|
-
if (!options.yes) {
|
|
39116
|
+
if (!options.yes && !isJsonMode()) {
|
|
38998
39117
|
const shouldDeploy = await ye({ message: `Deploy site from ${project.site.outputDirectory}?` });
|
|
38999
|
-
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
39118
|
+
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
39119
|
+
outroMessage: "Deployment cancelled",
|
|
39120
|
+
data: { cancelled: true }
|
|
39121
|
+
};
|
|
39000
39122
|
}
|
|
39001
|
-
|
|
39123
|
+
const result = await runTask("Creating archive and deploying site...", async () => {
|
|
39002
39124
|
return await deploySite(outputDir);
|
|
39003
39125
|
}, {
|
|
39004
39126
|
successMessage: "Site deployed successfully",
|
|
39005
39127
|
errorMessage: "Deployment failed"
|
|
39006
|
-
})
|
|
39128
|
+
});
|
|
39129
|
+
return {
|
|
39130
|
+
outroMessage: `Visit your site at: ${result.appUrl}`,
|
|
39131
|
+
data: { appUrl: result.appUrl }
|
|
39132
|
+
};
|
|
39007
39133
|
}
|
|
39008
39134
|
const siteDeployCommand = new Command("site").description("Manage site deployments").addCommand(new Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
39009
39135
|
await runCommand(() => deployAction(options), { requireAuth: true });
|
|
@@ -39016,7 +39142,10 @@ var version = "0.0.13";
|
|
|
39016
39142
|
//#endregion
|
|
39017
39143
|
//#region src/cli/index.ts
|
|
39018
39144
|
const program = new Command();
|
|
39019
|
-
program.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(version);
|
|
39145
|
+
program.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(version).option("--json", "Output results as JSON (for scripting)");
|
|
39146
|
+
program.hook("preAction", (thisCommand) => {
|
|
39147
|
+
if (thisCommand.optsWithGlobals().json) setJsonMode(true);
|
|
39148
|
+
});
|
|
39020
39149
|
program.configureHelp({ sortSubcommands: true });
|
|
39021
39150
|
program.addCommand(loginCommand);
|
|
39022
39151
|
program.addCommand(whoamiCommand);
|
package/package.json
CHANGED