@base44-preview/cli 0.0.15-pr.19.d9072f9 → 0.0.15-pr.87.46d28c7
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/{program.js → cli/index.js} +258 -113
- package/package.json +8 -14
- package/bin/dev.cmd +0 -2
- package/bin/dev.js +0 -20
- package/bin/run.cmd +0 -2
- package/bin/run.js +0 -20
- /package/dist/{templates → cli/templates}/backend-and-client/.nvmrc +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/README.md +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/base44/app.jsonc.ejs +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/base44/config.jsonc.ejs +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/base44/entities/task.jsonc +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/components.json +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/index.html +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/jsconfig.json +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/package.json +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/postcss.config.js +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/App.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/api/base44Client.js.ejs +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/components/Base44Logo.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/components/ui/button.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/components/ui/checkbox.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/components/ui/input.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/index.css +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/src/main.jsx +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/tailwind.config.js +0 -0
- /package/dist/{templates → cli/templates}/backend-and-client/vite.config.js +0 -0
- /package/dist/{templates → cli/templates}/backend-only/base44/app.jsonc.ejs +0 -0
- /package/dist/{templates → cli/templates}/backend-only/base44/config.jsonc.ejs +0 -0
- /package/dist/{templates → cli/templates}/templates.json +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
import { EventEmitter, addAbortListener, on, once, setMaxListeners } from "node:events";
|
|
3
4
|
import childProcess, { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
@@ -30351,31 +30352,11 @@ async function deployAll(projectData) {
|
|
|
30351
30352
|
//#region src/core/project/app-config.ts
|
|
30352
30353
|
let cache = null;
|
|
30353
30354
|
/**
|
|
30354
|
-
* Load app config from BASE44_CLI_TEST_OVERRIDES env var.
|
|
30355
|
-
* @returns true if override was applied, false otherwise
|
|
30356
|
-
*/
|
|
30357
|
-
function loadFromTestOverrides() {
|
|
30358
|
-
const overrides = process.env.BASE44_CLI_TEST_OVERRIDES;
|
|
30359
|
-
if (!overrides) return false;
|
|
30360
|
-
try {
|
|
30361
|
-
const data = JSON.parse(overrides);
|
|
30362
|
-
if (data.appConfig?.id && data.appConfig?.projectRoot) {
|
|
30363
|
-
cache = {
|
|
30364
|
-
id: data.appConfig.id,
|
|
30365
|
-
projectRoot: data.appConfig.projectRoot
|
|
30366
|
-
};
|
|
30367
|
-
return true;
|
|
30368
|
-
}
|
|
30369
|
-
} catch {}
|
|
30370
|
-
return false;
|
|
30371
|
-
}
|
|
30372
|
-
/**
|
|
30373
30355
|
* Initialize app config by reading from .app.jsonc.
|
|
30374
30356
|
* Must be called before using getAppConfig().
|
|
30375
30357
|
* @throws Error if no project found or .app.jsonc missing
|
|
30376
30358
|
*/
|
|
30377
30359
|
async function initAppConfig() {
|
|
30378
|
-
if (loadFromTestOverrides()) return;
|
|
30379
30360
|
if (cache) return;
|
|
30380
30361
|
const projectRoot = await findProjectRoot();
|
|
30381
30362
|
if (!projectRoot) throw new Error("No Base44 project found. Run this command from a project directory with a config.jsonc file.");
|
|
@@ -31069,6 +31050,58 @@ async function printBanner() {
|
|
|
31069
31050
|
else console.log(theme.colors.base44Orange(BANNER_LINES.join("\n")));
|
|
31070
31051
|
}
|
|
31071
31052
|
|
|
31053
|
+
//#endregion
|
|
31054
|
+
//#region src/cli/utils/json.ts
|
|
31055
|
+
/**
|
|
31056
|
+
* JSON output utilities for CLI commands.
|
|
31057
|
+
*
|
|
31058
|
+
* These utilities support the `--json` flag which outputs machine-readable JSON
|
|
31059
|
+
* instead of human-friendly formatted output.
|
|
31060
|
+
*/
|
|
31061
|
+
let jsonModeEnabled = false;
|
|
31062
|
+
/**
|
|
31063
|
+
* Enable JSON output mode. Called by runCommand when --json flag is detected.
|
|
31064
|
+
*/
|
|
31065
|
+
function setJsonMode(enabled) {
|
|
31066
|
+
jsonModeEnabled = enabled;
|
|
31067
|
+
}
|
|
31068
|
+
/**
|
|
31069
|
+
* Check if JSON output mode is currently active.
|
|
31070
|
+
*/
|
|
31071
|
+
function isJsonMode() {
|
|
31072
|
+
return jsonModeEnabled;
|
|
31073
|
+
}
|
|
31074
|
+
/**
|
|
31075
|
+
* Output a success JSON response to stdout.
|
|
31076
|
+
* Only outputs if JSON mode is enabled.
|
|
31077
|
+
*/
|
|
31078
|
+
function outputJson(data) {
|
|
31079
|
+
if (!jsonModeEnabled) return;
|
|
31080
|
+
const response = {
|
|
31081
|
+
success: true,
|
|
31082
|
+
data
|
|
31083
|
+
};
|
|
31084
|
+
console.log(JSON.stringify(response, null, 2));
|
|
31085
|
+
}
|
|
31086
|
+
/**
|
|
31087
|
+
* Output an error JSON response to stderr.
|
|
31088
|
+
* Only outputs if JSON mode is enabled.
|
|
31089
|
+
*
|
|
31090
|
+
* @param error - The error to output
|
|
31091
|
+
* @param code - Optional error code
|
|
31092
|
+
*/
|
|
31093
|
+
function outputJsonError(error, code$1) {
|
|
31094
|
+
if (!jsonModeEnabled) return;
|
|
31095
|
+
const response = {
|
|
31096
|
+
success: false,
|
|
31097
|
+
error: {
|
|
31098
|
+
message: error instanceof Error ? error.message : error,
|
|
31099
|
+
...code$1 && { code: code$1 }
|
|
31100
|
+
}
|
|
31101
|
+
};
|
|
31102
|
+
console.error(JSON.stringify(response, null, 2));
|
|
31103
|
+
}
|
|
31104
|
+
|
|
31072
31105
|
//#endregion
|
|
31073
31106
|
//#region src/cli/utils/runCommand.ts
|
|
31074
31107
|
/**
|
|
@@ -31102,25 +31135,35 @@ async function printBanner() {
|
|
|
31102
31135
|
* });
|
|
31103
31136
|
*/
|
|
31104
31137
|
async function runCommand(commandFn, options) {
|
|
31105
|
-
|
|
31106
|
-
if (
|
|
31107
|
-
|
|
31108
|
-
|
|
31109
|
-
|
|
31138
|
+
const jsonMode = isJsonMode();
|
|
31139
|
+
if (!jsonMode) {
|
|
31140
|
+
console.log();
|
|
31141
|
+
if (options?.fullBanner) {
|
|
31142
|
+
await printBanner();
|
|
31143
|
+
Ie("");
|
|
31144
|
+
} else Ie(theme.colors.base44OrangeBackground(" Base 44 "));
|
|
31145
|
+
}
|
|
31110
31146
|
try {
|
|
31111
31147
|
if (options?.requireAuth) {
|
|
31112
31148
|
if (!await isLoggedIn()) {
|
|
31149
|
+
if (jsonMode) throw new Error("Authentication required. Please run 'base44 login' first.");
|
|
31113
31150
|
M.info("You need to login first to continue.");
|
|
31114
31151
|
await login();
|
|
31115
31152
|
}
|
|
31116
31153
|
}
|
|
31117
31154
|
if (options?.requireAppConfig !== false) await initAppConfig();
|
|
31118
|
-
const { outroMessage } = await commandFn();
|
|
31119
|
-
|
|
31155
|
+
const { outroMessage, data } = await commandFn();
|
|
31156
|
+
if (jsonMode) outputJson(data ?? {});
|
|
31157
|
+
else Se(outroMessage || "");
|
|
31120
31158
|
} catch (e$1) {
|
|
31121
|
-
if (
|
|
31122
|
-
|
|
31123
|
-
|
|
31159
|
+
if (jsonMode) {
|
|
31160
|
+
outputJsonError(e$1 instanceof Error ? e$1 : String(e$1));
|
|
31161
|
+
process.exit(1);
|
|
31162
|
+
} else {
|
|
31163
|
+
if (e$1 instanceof Error) M.error(e$1.stack ?? e$1.message);
|
|
31164
|
+
else M.error(String(e$1));
|
|
31165
|
+
process.exit(1);
|
|
31166
|
+
}
|
|
31124
31167
|
}
|
|
31125
31168
|
}
|
|
31126
31169
|
|
|
@@ -31130,6 +31173,8 @@ async function runCommand(commandFn, options) {
|
|
|
31130
31173
|
* Wraps an async operation with automatic spinner management.
|
|
31131
31174
|
* The spinner is automatically started, and stopped on both success and error.
|
|
31132
31175
|
*
|
|
31176
|
+
* In JSON mode, the spinner is suppressed and the operation runs silently.
|
|
31177
|
+
*
|
|
31133
31178
|
* @param startMessage - Message to show when spinner starts
|
|
31134
31179
|
* @param operation - The async operation to execute. Receives an updateMessage function
|
|
31135
31180
|
* to update the spinner text during long-running operations.
|
|
@@ -31165,6 +31210,10 @@ async function runCommand(commandFn, options) {
|
|
|
31165
31210
|
* );
|
|
31166
31211
|
*/
|
|
31167
31212
|
async function runTask(startMessage, operation, options) {
|
|
31213
|
+
if (isJsonMode()) {
|
|
31214
|
+
const noopUpdateMessage = () => {};
|
|
31215
|
+
return await operation(noopUpdateMessage);
|
|
31216
|
+
}
|
|
31168
31217
|
const s = Y();
|
|
31169
31218
|
s.start(startMessage);
|
|
31170
31219
|
const updateMessage = (message) => s.message(message);
|
|
@@ -31205,6 +31254,10 @@ function getDashboardUrl(projectId) {
|
|
|
31205
31254
|
|
|
31206
31255
|
//#endregion
|
|
31207
31256
|
//#region src/cli/commands/auth/login.ts
|
|
31257
|
+
/**
|
|
31258
|
+
* Login command does not support --json output.
|
|
31259
|
+
* It requires interactive browser authentication via device code flow.
|
|
31260
|
+
*/
|
|
31208
31261
|
async function generateAndDisplayDeviceCode() {
|
|
31209
31262
|
const deviceCodeResponse = await runTask("Generating device code...", async () => {
|
|
31210
31263
|
return await generateDeviceCode();
|
|
@@ -31266,7 +31319,13 @@ const loginCommand = new Command("login").description("Authenticate with Base44"
|
|
|
31266
31319
|
//#region src/cli/commands/auth/whoami.ts
|
|
31267
31320
|
async function whoami() {
|
|
31268
31321
|
const auth = await readAuth();
|
|
31269
|
-
return {
|
|
31322
|
+
return {
|
|
31323
|
+
outroMessage: `Logged in as: ${theme.styles.bold(auth.email)}`,
|
|
31324
|
+
data: {
|
|
31325
|
+
email: auth.email,
|
|
31326
|
+
name: auth.name
|
|
31327
|
+
}
|
|
31328
|
+
};
|
|
31270
31329
|
}
|
|
31271
31330
|
const whoamiCommand = new Command("whoami").description("Display current authenticated user").action(async () => {
|
|
31272
31331
|
await runCommand(whoami, {
|
|
@@ -31277,6 +31336,10 @@ const whoamiCommand = new Command("whoami").description("Display current authent
|
|
|
31277
31336
|
|
|
31278
31337
|
//#endregion
|
|
31279
31338
|
//#region src/cli/commands/auth/logout.ts
|
|
31339
|
+
/**
|
|
31340
|
+
* Logout command does not support --json output.
|
|
31341
|
+
* It is a user-facing auth command that is rarely scripted.
|
|
31342
|
+
*/
|
|
31280
31343
|
async function logout() {
|
|
31281
31344
|
await deleteAuth();
|
|
31282
31345
|
return { outroMessage: "Logged out successfully" };
|
|
@@ -31289,19 +31352,31 @@ const logoutCommand = new Command("logout").description("Logout from current dev
|
|
|
31289
31352
|
//#region src/cli/commands/entities/push.ts
|
|
31290
31353
|
async function pushEntitiesAction() {
|
|
31291
31354
|
const { entities } = await readProjectConfig();
|
|
31292
|
-
if (entities.length === 0) return {
|
|
31293
|
-
|
|
31294
|
-
|
|
31355
|
+
if (entities.length === 0) return {
|
|
31356
|
+
outroMessage: "No entities found in project",
|
|
31357
|
+
data: {
|
|
31358
|
+
created: [],
|
|
31359
|
+
updated: [],
|
|
31360
|
+
deleted: []
|
|
31361
|
+
}
|
|
31362
|
+
};
|
|
31363
|
+
if (!isJsonMode()) M.info(`Found ${entities.length} entities to push`);
|
|
31295
31364
|
const result = await runTask("Pushing entities to Base44", async () => {
|
|
31296
31365
|
return await pushEntities(entities);
|
|
31297
31366
|
}, {
|
|
31298
31367
|
successMessage: "Entities pushed successfully",
|
|
31299
31368
|
errorMessage: "Failed to push entities"
|
|
31300
31369
|
});
|
|
31301
|
-
if (
|
|
31302
|
-
|
|
31303
|
-
|
|
31304
|
-
|
|
31370
|
+
if (!isJsonMode()) {
|
|
31371
|
+
if (result.created.length > 0) M.success(`Created: ${result.created.join(", ")}`);
|
|
31372
|
+
if (result.updated.length > 0) M.success(`Updated: ${result.updated.join(", ")}`);
|
|
31373
|
+
if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
31374
|
+
}
|
|
31375
|
+
return { data: {
|
|
31376
|
+
created: result.created,
|
|
31377
|
+
updated: result.updated,
|
|
31378
|
+
deleted: result.deleted
|
|
31379
|
+
} };
|
|
31305
31380
|
}
|
|
31306
31381
|
const entitiesPushCommand = new Command("entities").description("Manage project entities").addCommand(new Command("push").description("Push local entities to Base44").action(async () => {
|
|
31307
31382
|
await runCommand(pushEntitiesAction, { requireAuth: true });
|
|
@@ -31311,21 +31386,32 @@ const entitiesPushCommand = new Command("entities").description("Manage project
|
|
|
31311
31386
|
//#region src/cli/commands/functions/deploy.ts
|
|
31312
31387
|
async function deployFunctionsAction() {
|
|
31313
31388
|
const { functions } = await readProjectConfig();
|
|
31314
|
-
if (functions.length === 0) return {
|
|
31315
|
-
|
|
31389
|
+
if (functions.length === 0) return {
|
|
31390
|
+
outroMessage: "No functions found. Create functions in the 'functions' directory.",
|
|
31391
|
+
data: {
|
|
31392
|
+
deployed: [],
|
|
31393
|
+
deleted: []
|
|
31394
|
+
}
|
|
31395
|
+
};
|
|
31396
|
+
if (!isJsonMode()) M.info(`Found ${functions.length} ${functions.length === 1 ? "function" : "functions"} to deploy`);
|
|
31316
31397
|
const result = await runTask("Deploying functions to Base44", async () => {
|
|
31317
31398
|
return await pushFunctions(functions);
|
|
31318
31399
|
}, {
|
|
31319
31400
|
successMessage: "Functions deployed successfully",
|
|
31320
31401
|
errorMessage: "Failed to deploy functions"
|
|
31321
31402
|
});
|
|
31322
|
-
if (
|
|
31323
|
-
|
|
31403
|
+
if (!isJsonMode()) {
|
|
31404
|
+
if (result.deployed.length > 0) M.success(`Deployed: ${result.deployed.join(", ")}`);
|
|
31405
|
+
if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
31406
|
+
}
|
|
31324
31407
|
if (result.errors && result.errors.length > 0) {
|
|
31325
31408
|
const errorMessages = result.errors.map((e$1) => `'${e$1.name}' function: ${e$1.message}`).join("\n");
|
|
31326
31409
|
throw new Error(`Function deployment errors:\n${errorMessages}`);
|
|
31327
31410
|
}
|
|
31328
|
-
return {
|
|
31411
|
+
return { data: {
|
|
31412
|
+
deployed: result.deployed,
|
|
31413
|
+
deleted: result.deleted
|
|
31414
|
+
} };
|
|
31329
31415
|
}
|
|
31330
31416
|
const functionsDeployCommand = new Command("functions").description("Manage project functions").addCommand(new Command("deploy").description("Deploy local functions to Base44").action(async () => {
|
|
31331
31417
|
await runCommand(deployFunctionsAction, { requireAuth: true });
|
|
@@ -38009,10 +38095,11 @@ async function getTemplateById(templateId) {
|
|
|
38009
38095
|
}
|
|
38010
38096
|
return template;
|
|
38011
38097
|
}
|
|
38012
|
-
function validateNonInteractiveFlags$
|
|
38013
|
-
const { name: name$1, path: path$16 } = command.
|
|
38098
|
+
function validateNonInteractiveFlags$2(command) {
|
|
38099
|
+
const { name: name$1, path: path$16, json } = command.optsWithGlobals();
|
|
38014
38100
|
const providedCount = [name$1, path$16].filter(Boolean).length;
|
|
38015
|
-
if (
|
|
38101
|
+
if (json && providedCount < 2) throw new Error("JSON mode requires all flags: --name, --path");
|
|
38102
|
+
if (providedCount > 0 && providedCount < 2) throw new Error("Non-interactive mode requires all flags: --name, --path");
|
|
38016
38103
|
}
|
|
38017
38104
|
async function chooseCreate(options) {
|
|
38018
38105
|
if (!!(options.name && options.path)) await runCommand(() => createNonInteractive(options), {
|
|
@@ -38135,12 +38222,23 @@ async function executeCreate({ template, name: rawName, description, projectPath
|
|
|
38135
38222
|
finalAppUrl = appUrl;
|
|
38136
38223
|
}
|
|
38137
38224
|
}
|
|
38138
|
-
|
|
38139
|
-
|
|
38140
|
-
|
|
38141
|
-
|
|
38225
|
+
const dashboardUrl = getDashboardUrl(projectId);
|
|
38226
|
+
if (!isJsonMode()) {
|
|
38227
|
+
M.message(`${theme.styles.header("Project")}: ${theme.colors.base44Orange(name$1)}`);
|
|
38228
|
+
M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
38229
|
+
if (finalAppUrl) M.message(`${theme.styles.header("Site")}: ${theme.colors.links(finalAppUrl)}`);
|
|
38230
|
+
}
|
|
38231
|
+
return {
|
|
38232
|
+
outroMessage: "Your project is set up and ready to use",
|
|
38233
|
+
data: {
|
|
38234
|
+
projectId,
|
|
38235
|
+
path: resolvedPath,
|
|
38236
|
+
dashboardUrl,
|
|
38237
|
+
...finalAppUrl && { appUrl: finalAppUrl }
|
|
38238
|
+
}
|
|
38239
|
+
};
|
|
38142
38240
|
}
|
|
38143
|
-
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("-t, --template <id>", "Template ID (e.g., backend-only, backend-and-client)").option("--deploy", "Build and deploy the site").hook("preAction", validateNonInteractiveFlags$
|
|
38241
|
+
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("-t, --template <id>", "Template ID (e.g., backend-only, backend-and-client)").option("--deploy", "Build and deploy the site").hook("preAction", validateNonInteractiveFlags$2).action(async (options) => {
|
|
38144
38242
|
await chooseCreate(options);
|
|
38145
38243
|
});
|
|
38146
38244
|
|
|
@@ -38685,20 +38783,36 @@ var open_default = open;
|
|
|
38685
38783
|
|
|
38686
38784
|
//#endregion
|
|
38687
38785
|
//#region src/cli/commands/project/dashboard.ts
|
|
38688
|
-
async function openDashboard() {
|
|
38786
|
+
async function openDashboard(options) {
|
|
38689
38787
|
const dashboardUrl = getDashboardUrl();
|
|
38690
|
-
|
|
38691
|
-
|
|
38788
|
+
const shouldOpen = !isJsonMode() && options.open !== false;
|
|
38789
|
+
if (shouldOpen) await open_default(dashboardUrl);
|
|
38790
|
+
return {
|
|
38791
|
+
outroMessage: shouldOpen ? `Dashboard opened at ${dashboardUrl}` : `Dashboard URL: ${dashboardUrl}`,
|
|
38792
|
+
data: { dashboardUrl }
|
|
38793
|
+
};
|
|
38692
38794
|
}
|
|
38693
|
-
const dashboardCommand = new Command("dashboard").description("Open the app dashboard in your browser").action(async () => {
|
|
38694
|
-
await runCommand(openDashboard, { requireAuth: true });
|
|
38795
|
+
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) => {
|
|
38796
|
+
await runCommand(() => openDashboard(options), { requireAuth: true });
|
|
38695
38797
|
});
|
|
38696
38798
|
|
|
38697
38799
|
//#endregion
|
|
38698
38800
|
//#region src/cli/commands/project/deploy.ts
|
|
38801
|
+
function validateNonInteractiveFlags$1(command) {
|
|
38802
|
+
const opts = command.optsWithGlobals();
|
|
38803
|
+
if (opts.json && !opts.yes) throw new Error("JSON mode requires: --yes (-y) to skip confirmation");
|
|
38804
|
+
}
|
|
38699
38805
|
async function deployAction$1(options) {
|
|
38700
38806
|
const projectData = await readProjectConfig();
|
|
38701
|
-
if (!hasResourcesToDeploy(projectData)) return {
|
|
38807
|
+
if (!hasResourcesToDeploy(projectData)) return {
|
|
38808
|
+
outroMessage: "No resources found to deploy",
|
|
38809
|
+
data: {
|
|
38810
|
+
dashboardUrl: getDashboardUrl(),
|
|
38811
|
+
entitiesCount: 0,
|
|
38812
|
+
functionsCount: 0,
|
|
38813
|
+
siteDeployed: false
|
|
38814
|
+
}
|
|
38815
|
+
};
|
|
38702
38816
|
const { project, entities, functions } = projectData;
|
|
38703
38817
|
const summaryLines = [];
|
|
38704
38818
|
if (entities.length > 0) summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
|
|
@@ -38707,27 +38821,49 @@ async function deployAction$1(options) {
|
|
|
38707
38821
|
if (!options.yes) {
|
|
38708
38822
|
M.warn(`This will update your Base44 app with:\n${summaryLines.join("\n")}`);
|
|
38709
38823
|
const shouldDeploy = await ye({ message: "Are you sure you want to continue?" });
|
|
38710
|
-
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
38711
|
-
|
|
38824
|
+
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
38825
|
+
outroMessage: "Deployment cancelled",
|
|
38826
|
+
data: {
|
|
38827
|
+
dashboardUrl: getDashboardUrl(),
|
|
38828
|
+
entitiesCount: entities.length,
|
|
38829
|
+
functionsCount: functions.length,
|
|
38830
|
+
siteDeployed: false,
|
|
38831
|
+
cancelled: true
|
|
38832
|
+
}
|
|
38833
|
+
};
|
|
38834
|
+
} else if (!isJsonMode()) M.info(`Deploying:\n${summaryLines.join("\n")}`);
|
|
38712
38835
|
const result = await runTask("Deploying your app...", async () => {
|
|
38713
38836
|
return await deployAll(projectData);
|
|
38714
38837
|
}, {
|
|
38715
38838
|
successMessage: theme.colors.base44Orange("Deployment completed"),
|
|
38716
38839
|
errorMessage: "Deployment failed"
|
|
38717
38840
|
});
|
|
38718
|
-
|
|
38719
|
-
if (
|
|
38720
|
-
|
|
38841
|
+
const dashboardUrl = getDashboardUrl();
|
|
38842
|
+
if (!isJsonMode()) {
|
|
38843
|
+
M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
38844
|
+
if (result.appUrl) M.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
|
|
38845
|
+
}
|
|
38846
|
+
return {
|
|
38847
|
+
outroMessage: "App deployed successfully",
|
|
38848
|
+
data: {
|
|
38849
|
+
dashboardUrl,
|
|
38850
|
+
appUrl: result.appUrl,
|
|
38851
|
+
entitiesCount: entities.length,
|
|
38852
|
+
functionsCount: functions.length,
|
|
38853
|
+
siteDeployed: !!project.site?.outputDirectory
|
|
38854
|
+
}
|
|
38855
|
+
};
|
|
38721
38856
|
}
|
|
38722
|
-
const deployCommand = new Command("deploy").description("Deploy all project resources (entities, functions, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
38857
|
+
const deployCommand = new Command("deploy").description("Deploy all project resources (entities, functions, and site)").option("-y, --yes", "Skip confirmation prompt").hook("preAction", validateNonInteractiveFlags$1).action(async (options) => {
|
|
38723
38858
|
await runCommand(() => deployAction$1(options), { requireAuth: true });
|
|
38724
38859
|
});
|
|
38725
38860
|
|
|
38726
38861
|
//#endregion
|
|
38727
38862
|
//#region src/cli/commands/project/link.ts
|
|
38728
38863
|
function validateNonInteractiveFlags(command) {
|
|
38729
|
-
const { create: create$1, name: name$1 } = command.
|
|
38730
|
-
if (create$1
|
|
38864
|
+
const { create: create$1, name: name$1, json } = command.optsWithGlobals();
|
|
38865
|
+
if (json && (!create$1 || !name$1)) throw new Error("JSON mode requires flags: --create, --name");
|
|
38866
|
+
if (create$1 && !name$1) throw new Error("--name is required when using --create");
|
|
38731
38867
|
}
|
|
38732
38868
|
async function promptForProjectDetails() {
|
|
38733
38869
|
const actionOptions = [{
|
|
@@ -38778,8 +38914,15 @@ async function link(options) {
|
|
|
38778
38914
|
id: projectId,
|
|
38779
38915
|
projectRoot: projectRoot.root
|
|
38780
38916
|
});
|
|
38781
|
-
|
|
38782
|
-
|
|
38917
|
+
const dashboardUrl = getDashboardUrl(projectId);
|
|
38918
|
+
if (!isJsonMode()) M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
|
|
38919
|
+
return {
|
|
38920
|
+
outroMessage: "Project linked",
|
|
38921
|
+
data: {
|
|
38922
|
+
projectId,
|
|
38923
|
+
dashboardUrl
|
|
38924
|
+
}
|
|
38925
|
+
};
|
|
38783
38926
|
}
|
|
38784
38927
|
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) => {
|
|
38785
38928
|
await runCommand(() => link(options), {
|
|
@@ -38794,16 +38937,23 @@ async function deployAction(options) {
|
|
|
38794
38937
|
const { project } = await readProjectConfig();
|
|
38795
38938
|
if (!project.site?.outputDirectory) throw new Error("No site configuration found. Please add 'site.outputDirectory' to your config.jsonc");
|
|
38796
38939
|
const outputDir = resolve(project.root, project.site.outputDirectory);
|
|
38797
|
-
if (!options.yes) {
|
|
38940
|
+
if (!options.yes && !isJsonMode()) {
|
|
38798
38941
|
const shouldDeploy = await ye({ message: `Deploy site from ${project.site.outputDirectory}?` });
|
|
38799
|
-
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
38942
|
+
if (pD(shouldDeploy) || !shouldDeploy) return {
|
|
38943
|
+
outroMessage: "Deployment cancelled",
|
|
38944
|
+
data: { cancelled: true }
|
|
38945
|
+
};
|
|
38800
38946
|
}
|
|
38801
|
-
|
|
38947
|
+
const result = await runTask("Creating archive and deploying site...", async () => {
|
|
38802
38948
|
return await deploySite(outputDir);
|
|
38803
38949
|
}, {
|
|
38804
38950
|
successMessage: "Site deployed successfully",
|
|
38805
38951
|
errorMessage: "Deployment failed"
|
|
38806
|
-
})
|
|
38952
|
+
});
|
|
38953
|
+
return {
|
|
38954
|
+
outroMessage: `Visit your site at: ${result.appUrl}`,
|
|
38955
|
+
data: { appUrl: result.appUrl }
|
|
38956
|
+
};
|
|
38807
38957
|
}
|
|
38808
38958
|
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) => {
|
|
38809
38959
|
await runCommand(() => deployAction(options), { requireAuth: true });
|
|
@@ -38814,47 +38964,42 @@ const siteDeployCommand = new Command("site").description("Manage site deploymen
|
|
|
38814
38964
|
var version = "0.0.15";
|
|
38815
38965
|
|
|
38816
38966
|
//#endregion
|
|
38817
|
-
//#region src/cli/
|
|
38818
|
-
|
|
38819
|
-
|
|
38820
|
-
|
|
38821
|
-
|
|
38822
|
-
|
|
38823
|
-
|
|
38824
|
-
|
|
38825
|
-
|
|
38826
|
-
|
|
38827
|
-
|
|
38828
|
-
|
|
38829
|
-
};
|
|
38830
|
-
|
|
38831
|
-
|
|
38832
|
-
|
|
38833
|
-
|
|
38834
|
-
|
|
38835
|
-
|
|
38836
|
-
|
|
38837
|
-
|
|
38838
|
-
|
|
38839
|
-
|
|
38840
|
-
|
|
38841
|
-
|
|
38842
|
-
|
|
38843
|
-
|
|
38844
|
-
}
|
|
38845
|
-
|
|
38846
|
-
|
|
38847
|
-
|
|
38848
|
-
|
|
38849
|
-
|
|
38850
|
-
|
|
38851
|
-
|
|
38852
|
-
|
|
38853
|
-
program$2.addCommand(functionsDeployCommand);
|
|
38854
|
-
program$2.addCommand(siteDeployCommand);
|
|
38855
|
-
return program$2;
|
|
38856
|
-
}
|
|
38857
|
-
const program = createProgram();
|
|
38967
|
+
//#region src/cli/index.ts
|
|
38968
|
+
if (process.argv.includes("--json")) setJsonMode(true);
|
|
38969
|
+
const program = new Command();
|
|
38970
|
+
program.exitOverride();
|
|
38971
|
+
program.configureOutput({ outputError: (str, write) => {
|
|
38972
|
+
if (isJsonMode()) return;
|
|
38973
|
+
write(str);
|
|
38974
|
+
} });
|
|
38975
|
+
program.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(version).option("--json", "Output results as JSON (for scripting)");
|
|
38976
|
+
program.hook("preAction", (thisCommand) => {
|
|
38977
|
+
if (thisCommand.optsWithGlobals().json) setJsonMode(true);
|
|
38978
|
+
});
|
|
38979
|
+
program.configureHelp({ sortSubcommands: true });
|
|
38980
|
+
program.addCommand(loginCommand);
|
|
38981
|
+
program.addCommand(whoamiCommand);
|
|
38982
|
+
program.addCommand(logoutCommand);
|
|
38983
|
+
program.addCommand(createCommand);
|
|
38984
|
+
program.addCommand(dashboardCommand);
|
|
38985
|
+
program.addCommand(deployCommand);
|
|
38986
|
+
program.addCommand(linkCommand);
|
|
38987
|
+
program.addCommand(entitiesPushCommand);
|
|
38988
|
+
program.addCommand(functionsDeployCommand);
|
|
38989
|
+
program.addCommand(siteDeployCommand);
|
|
38990
|
+
program.parseAsync().catch((err) => {
|
|
38991
|
+
if (err instanceof CommanderError) {
|
|
38992
|
+
if (isJsonMode()) outputJsonError(err.message, err.code);
|
|
38993
|
+
process.exit(err.exitCode);
|
|
38994
|
+
}
|
|
38995
|
+
if (isJsonMode()) {
|
|
38996
|
+
outputJsonError(err instanceof Error ? err : String(err));
|
|
38997
|
+
process.exit(1);
|
|
38998
|
+
}
|
|
38999
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
39000
|
+
console.error(`error: ${message}`);
|
|
39001
|
+
process.exit(1);
|
|
39002
|
+
});
|
|
38858
39003
|
|
|
38859
39004
|
//#endregion
|
|
38860
|
-
export {
|
|
39005
|
+
export { };
|
package/package.json
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@base44-preview/cli",
|
|
3
|
-
"version": "0.0.15-pr.
|
|
3
|
+
"version": "0.0.15-pr.87.46d28c7",
|
|
4
4
|
"description": "Base44 CLI - Unified interface for managing Base44 applications",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/
|
|
7
|
-
"bin":
|
|
8
|
-
"base44": "./bin/run.js"
|
|
9
|
-
},
|
|
6
|
+
"main": "./dist/cli/index.js",
|
|
7
|
+
"bin": "./dist/cli/index.js",
|
|
10
8
|
"exports": {
|
|
11
|
-
".": "./dist/
|
|
9
|
+
".": "./dist/cli/index.js"
|
|
12
10
|
},
|
|
13
11
|
"files": [
|
|
14
|
-
"dist"
|
|
15
|
-
"bin"
|
|
12
|
+
"dist"
|
|
16
13
|
],
|
|
17
14
|
"scripts": {
|
|
18
15
|
"build": "tsdown",
|
|
19
16
|
"typecheck": "tsc --noEmit",
|
|
20
|
-
"dev": "
|
|
21
|
-
"start": "
|
|
17
|
+
"dev": "tsx src/cli/index.ts",
|
|
18
|
+
"start": "node dist/cli/index.js",
|
|
22
19
|
"clean": "rm -rf dist",
|
|
23
|
-
"lint": "eslint src
|
|
20
|
+
"lint": "eslint src",
|
|
24
21
|
"test": "vitest run",
|
|
25
22
|
"test:watch": "vitest"
|
|
26
23
|
},
|
|
@@ -56,12 +53,9 @@
|
|
|
56
53
|
"json5": "^2.2.3",
|
|
57
54
|
"ky": "^1.14.2",
|
|
58
55
|
"lodash.kebabcase": "^4.1.1",
|
|
59
|
-
"msw": "^2.12.7",
|
|
60
56
|
"open": "^11.0.0",
|
|
61
57
|
"p-wait-for": "^6.0.0",
|
|
62
|
-
"strip-ansi": "^7.1.2",
|
|
63
58
|
"tar": "^7.5.4",
|
|
64
|
-
"tmp-promise": "^3.0.3",
|
|
65
59
|
"tsdown": "^0.12.4",
|
|
66
60
|
"tsx": "^4.19.2",
|
|
67
61
|
"typescript": "^5.7.2",
|
package/bin/dev.cmd
DELETED
package/bin/dev.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
import { program, CLIExitError } from '../src/cli/program.ts';
|
|
3
|
-
|
|
4
|
-
try {
|
|
5
|
-
await program.parseAsync();
|
|
6
|
-
} catch (e) {
|
|
7
|
-
if (e instanceof CLIExitError) {
|
|
8
|
-
process.exit(e.code); // Clean exit, no stack trace
|
|
9
|
-
}
|
|
10
|
-
// Commander throws for --help and --version with exitCode 0
|
|
11
|
-
if (e?.code === 'commander.helpDisplayed' || e?.code === 'commander.version') {
|
|
12
|
-
process.exit(0);
|
|
13
|
-
}
|
|
14
|
-
// For other Commander errors, exit with the provided code
|
|
15
|
-
if (e?.exitCode !== undefined) {
|
|
16
|
-
process.exit(e.exitCode);
|
|
17
|
-
}
|
|
18
|
-
console.error(e);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
package/bin/run.cmd
DELETED
package/bin/run.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { program, CLIExitError } from '../dist/program.js';
|
|
3
|
-
|
|
4
|
-
try {
|
|
5
|
-
await program.parseAsync();
|
|
6
|
-
} catch (e) {
|
|
7
|
-
if (e instanceof CLIExitError) {
|
|
8
|
-
process.exit(e.code); // Clean exit, no stack trace
|
|
9
|
-
}
|
|
10
|
-
// Commander throws for --help and --version with exitCode 0
|
|
11
|
-
if (e?.code === 'commander.helpDisplayed' || e?.code === 'commander.version') {
|
|
12
|
-
process.exit(0);
|
|
13
|
-
}
|
|
14
|
-
// For other Commander errors, exit with the provided code
|
|
15
|
-
if (e?.exitCode !== undefined) {
|
|
16
|
-
process.exit(e.exitCode);
|
|
17
|
-
}
|
|
18
|
-
console.error(e);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|