base44 0.0.6 → 0.0.8
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 +117 -69
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -12342,7 +12342,7 @@ var require_parse$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
12342
12342
|
if (opts$1.noglobstar === true) return star;
|
|
12343
12343
|
return `(${capture}(?:(?!${START_ANCHOR}${opts$1.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
|
|
12344
12344
|
};
|
|
12345
|
-
const create$
|
|
12345
|
+
const create$1 = (str) => {
|
|
12346
12346
|
switch (str) {
|
|
12347
12347
|
case "*": return `${nodot}${ONE_CHAR}${star}`;
|
|
12348
12348
|
case ".*": return `${DOT_LITERAL}${ONE_CHAR}${star}`;
|
|
@@ -12355,13 +12355,13 @@ var require_parse$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
12355
12355
|
default: {
|
|
12356
12356
|
const match = /^(.*?)\.(\w+)$/.exec(str);
|
|
12357
12357
|
if (!match) return;
|
|
12358
|
-
const source$1 = create$
|
|
12358
|
+
const source$1 = create$1(match[1]);
|
|
12359
12359
|
if (!source$1) return;
|
|
12360
12360
|
return source$1 + DOT_LITERAL + match[2];
|
|
12361
12361
|
}
|
|
12362
12362
|
}
|
|
12363
12363
|
};
|
|
12364
|
-
let source = create$
|
|
12364
|
+
let source = create$1(utils.removePrefix(input, state));
|
|
12365
12365
|
if (source && opts.strictSlashes !== true) source += `${SLASH_LITERAL}?`;
|
|
12366
12366
|
return source;
|
|
12367
12367
|
};
|
|
@@ -26260,14 +26260,12 @@ async function printAnimatedLines(lines) {
|
|
|
26260
26260
|
//#region src/cli/utils/banner.ts
|
|
26261
26261
|
const orange$1 = source_default.hex("#E86B3C");
|
|
26262
26262
|
const BANNER_LINES = [
|
|
26263
|
-
"",
|
|
26264
26263
|
"██████╗ █████╗ ███████╗███████╗ ██╗ ██╗██╗ ██╗",
|
|
26265
26264
|
"██╔══██╗██╔══██╗██╔════╝██╔════╝ ██║ ██║██║ ██║",
|
|
26266
26265
|
"██████╔╝███████║███████╗█████╗ ███████║███████║",
|
|
26267
26266
|
"██╔══██╗██╔══██║╚════██║██╔══╝ ╚════██║╚════██║",
|
|
26268
26267
|
"██████╔╝██║ ██║███████║███████╗ ██║ ██║",
|
|
26269
|
-
"╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
|
|
26270
|
-
""
|
|
26268
|
+
"╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
|
|
26271
26269
|
];
|
|
26272
26270
|
/**
|
|
26273
26271
|
* Print the Base44 banner with smooth animation if supported,
|
|
@@ -26282,30 +26280,49 @@ async function printBanner() {
|
|
|
26282
26280
|
//#region src/cli/utils/runCommand.ts
|
|
26283
26281
|
const base44Color = source_default.bgHex("#E86B3C");
|
|
26284
26282
|
/**
|
|
26285
|
-
* Wraps a command function with the Base44 intro
|
|
26283
|
+
* Wraps a command function with the Base44 intro/outro and error handling.
|
|
26286
26284
|
* All CLI commands should use this utility to ensure consistent branding.
|
|
26287
|
-
* Also loads .env.local from the project root if available.
|
|
26288
26285
|
*
|
|
26289
|
-
*
|
|
26286
|
+
* **Responsibilities**:
|
|
26287
|
+
* - Displays the intro (simple tag or full ASCII banner)
|
|
26288
|
+
* - Loads `.env.local` from the project root if available
|
|
26289
|
+
* - Checks authentication if `requireAuth` is set
|
|
26290
|
+
* - Runs the command function
|
|
26291
|
+
* - Displays the outro message returned by the command
|
|
26292
|
+
* - Handles errors and exits with code 1 on failure
|
|
26293
|
+
*
|
|
26294
|
+
* **Important**: Commands should NOT call `intro()` or `outro()` directly.
|
|
26295
|
+
* This function handles both. Commands can return an optional `outroMessage`
|
|
26296
|
+
* which will be displayed at the end.
|
|
26297
|
+
*
|
|
26298
|
+
* @param commandFn - The async function to execute. Returns `RunCommandResult` with optional `outroMessage`.
|
|
26290
26299
|
* @param options - Optional configuration for the command wrapper
|
|
26291
26300
|
*
|
|
26292
26301
|
* @example
|
|
26293
|
-
* // Standard command with
|
|
26302
|
+
* // Standard command with outro message
|
|
26303
|
+
* async function myAction(): Promise<RunCommandResult> {
|
|
26304
|
+
* // ... do work ...
|
|
26305
|
+
* return { outroMessage: "Done!" };
|
|
26306
|
+
* }
|
|
26307
|
+
*
|
|
26294
26308
|
* export const myCommand = new Command("my-command")
|
|
26295
26309
|
* .action(async () => {
|
|
26296
26310
|
* await runCommand(myAction);
|
|
26297
26311
|
* });
|
|
26298
26312
|
*
|
|
26299
26313
|
* @example
|
|
26300
|
-
* // Command requiring authentication
|
|
26314
|
+
* // Command requiring authentication with full banner
|
|
26301
26315
|
* export const myCommand = new Command("my-command")
|
|
26302
26316
|
* .action(async () => {
|
|
26303
|
-
* await runCommand(myAction, { requireAuth: true });
|
|
26317
|
+
* await runCommand(myAction, { requireAuth: true, fullBanner: true });
|
|
26304
26318
|
* });
|
|
26305
26319
|
*/
|
|
26306
26320
|
async function runCommand(commandFn, options) {
|
|
26307
|
-
|
|
26308
|
-
|
|
26321
|
+
console.log();
|
|
26322
|
+
if (options?.fullBanner) {
|
|
26323
|
+
await printBanner();
|
|
26324
|
+
Ie("");
|
|
26325
|
+
} else Ie(base44Color(" Base 44 "));
|
|
26309
26326
|
await loadProjectEnv();
|
|
26310
26327
|
try {
|
|
26311
26328
|
if (options?.requireAuth) {
|
|
@@ -26314,7 +26331,8 @@ async function runCommand(commandFn, options) {
|
|
|
26314
26331
|
await login();
|
|
26315
26332
|
}
|
|
26316
26333
|
}
|
|
26317
|
-
await commandFn();
|
|
26334
|
+
const { outroMessage } = await commandFn();
|
|
26335
|
+
Se(outroMessage || "");
|
|
26318
26336
|
} catch (e$1) {
|
|
26319
26337
|
if (e$1 instanceof Error) M.error(e$1.stack ?? e$1.message);
|
|
26320
26338
|
else M.error(String(e$1));
|
|
@@ -26440,7 +26458,7 @@ async function login() {
|
|
|
26440
26458
|
const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval);
|
|
26441
26459
|
const userInfo = await getUserInfo(token.accessToken);
|
|
26442
26460
|
await saveAuthData(token, userInfo);
|
|
26443
|
-
|
|
26461
|
+
return { outroMessage: `Successfully logged in as ${source_default.bold(userInfo.email)}` };
|
|
26444
26462
|
}
|
|
26445
26463
|
const loginCommand = new Command("login").description("Authenticate with Base44").action(async () => {
|
|
26446
26464
|
await runCommand(login);
|
|
@@ -26450,7 +26468,7 @@ const loginCommand = new Command("login").description("Authenticate with Base44"
|
|
|
26450
26468
|
//#region src/cli/commands/auth/whoami.ts
|
|
26451
26469
|
async function whoami() {
|
|
26452
26470
|
const auth = await readAuth();
|
|
26453
|
-
|
|
26471
|
+
return { outroMessage: `Logged in as: ${source_default.bold(auth.email)}` };
|
|
26454
26472
|
}
|
|
26455
26473
|
const whoamiCommand = new Command("whoami").description("Display current authenticated user").action(async () => {
|
|
26456
26474
|
await runCommand(whoami, { requireAuth: true });
|
|
@@ -26460,10 +26478,10 @@ const whoamiCommand = new Command("whoami").description("Display current authent
|
|
|
26460
26478
|
//#region src/cli/commands/auth/logout.ts
|
|
26461
26479
|
async function logout() {
|
|
26462
26480
|
await deleteAuth();
|
|
26463
|
-
|
|
26481
|
+
return { outroMessage: "Logged out successfully" };
|
|
26464
26482
|
}
|
|
26465
26483
|
const logoutCommand = new Command("logout").description("Logout from current device").action(async () => {
|
|
26466
|
-
await runCommand(logout
|
|
26484
|
+
await runCommand(logout);
|
|
26467
26485
|
});
|
|
26468
26486
|
|
|
26469
26487
|
//#endregion
|
|
@@ -26471,14 +26489,7 @@ const logoutCommand = new Command("logout").description("Logout from current dev
|
|
|
26471
26489
|
/**
|
|
26472
26490
|
* Response from the deploy API endpoint.
|
|
26473
26491
|
*/
|
|
26474
|
-
const DeployResponseSchema = object({
|
|
26475
|
-
success: boolean(),
|
|
26476
|
-
app_id: string(),
|
|
26477
|
-
files_count: number(),
|
|
26478
|
-
total_size_bytes: number(),
|
|
26479
|
-
deployed_at: string(),
|
|
26480
|
-
app_url: string().url()
|
|
26481
|
-
});
|
|
26492
|
+
const DeployResponseSchema = object({ app_url: url() }).transform((data) => ({ appUrl: data.app_url }));
|
|
26482
26493
|
|
|
26483
26494
|
//#endregion
|
|
26484
26495
|
//#region src/core/site/config.ts
|
|
@@ -30307,7 +30318,7 @@ const createAsync = (opt, files) => {
|
|
|
30307
30318
|
addFilesAsync$1(p$1, files);
|
|
30308
30319
|
return p$1;
|
|
30309
30320
|
};
|
|
30310
|
-
const create
|
|
30321
|
+
const create = makeCommand(createFileSync, createFile, createSync, createAsync, (_opt, files) => {
|
|
30311
30322
|
if (!files?.length) throw new TypeError("no paths specified to add to archive");
|
|
30312
30323
|
});
|
|
30313
30324
|
|
|
@@ -31443,7 +31454,7 @@ async function deploySite(siteOutputDir) {
|
|
|
31443
31454
|
}
|
|
31444
31455
|
}
|
|
31445
31456
|
async function createArchive(pathToArchive, targetArchivePath) {
|
|
31446
|
-
await create
|
|
31457
|
+
await create({
|
|
31447
31458
|
gzip: true,
|
|
31448
31459
|
file: targetArchivePath,
|
|
31449
31460
|
cwd: pathToArchive
|
|
@@ -31454,10 +31465,7 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
31454
31465
|
//#region src/cli/commands/entities/push.ts
|
|
31455
31466
|
async function pushEntitiesAction() {
|
|
31456
31467
|
const { entities } = await readProjectConfig();
|
|
31457
|
-
if (entities.length === 0) {
|
|
31458
|
-
M.warn("No entities found in project");
|
|
31459
|
-
return;
|
|
31460
|
-
}
|
|
31468
|
+
if (entities.length === 0) return { outroMessage: "No entities found in project" };
|
|
31461
31469
|
M.info(`Found ${entities.length} entities to push`);
|
|
31462
31470
|
const result = await runTask("Pushing entities to Base44", async () => {
|
|
31463
31471
|
return await pushEntities(entities);
|
|
@@ -31468,7 +31476,7 @@ async function pushEntitiesAction() {
|
|
|
31468
31476
|
if (result.created.length > 0) M.success(`Created: ${result.created.join(", ")}`);
|
|
31469
31477
|
if (result.updated.length > 0) M.success(`Updated: ${result.updated.join(", ")}`);
|
|
31470
31478
|
if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
|
|
31471
|
-
|
|
31479
|
+
return {};
|
|
31472
31480
|
}
|
|
31473
31481
|
const entitiesPushCommand = new Command("entities").description("Manage project entities").addCommand(new Command("push").description("Push local entities to Base44").action(async () => {
|
|
31474
31482
|
await runCommand(pushEntitiesAction, { requireAuth: true });
|
|
@@ -38144,14 +38152,31 @@ var require_lodash = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
38144
38152
|
var import_lodash = /* @__PURE__ */ __toESM(require_lodash(), 1);
|
|
38145
38153
|
const orange = source_default.hex("#E86B3C");
|
|
38146
38154
|
const cyan = source_default.hex("#00D4FF");
|
|
38147
|
-
|
|
38148
|
-
|
|
38155
|
+
const DEFAULT_TEMPLATE_ID = "backend-only";
|
|
38156
|
+
async function getDefaultTemplate() {
|
|
38157
|
+
const template = (await listTemplates()).find((t) => t.id === DEFAULT_TEMPLATE_ID);
|
|
38158
|
+
if (!template) throw new Error(`Default template "${DEFAULT_TEMPLATE_ID}" not found`);
|
|
38159
|
+
return template;
|
|
38160
|
+
}
|
|
38161
|
+
function validateNonInteractiveFlags(command) {
|
|
38162
|
+
const { name: name$1, path: path$17 } = command.opts();
|
|
38163
|
+
const providedCount = [name$1, path$17].filter(Boolean).length;
|
|
38164
|
+
if (providedCount > 0 && providedCount < 2) command.error("Non-interactive mode requires all flags: --name, --path");
|
|
38165
|
+
}
|
|
38166
|
+
async function chooseCreate(options) {
|
|
38167
|
+
if (!!(options.name && options.path)) await runCommand(() => createNonInteractive(options), { requireAuth: true });
|
|
38168
|
+
else await runCommand(() => createInteractive(options), {
|
|
38169
|
+
fullBanner: true,
|
|
38170
|
+
requireAuth: true
|
|
38171
|
+
});
|
|
38172
|
+
}
|
|
38173
|
+
async function createInteractive(options) {
|
|
38149
38174
|
const templateOptions = (await listTemplates()).map((t) => ({
|
|
38150
38175
|
value: t,
|
|
38151
38176
|
label: t.name,
|
|
38152
38177
|
hint: t.description
|
|
38153
38178
|
}));
|
|
38154
|
-
const
|
|
38179
|
+
const result = await Ce({
|
|
38155
38180
|
template: () => ve({
|
|
38156
38181
|
message: "Pick a template",
|
|
38157
38182
|
options: templateOptions
|
|
@@ -38176,11 +38201,32 @@ async function create() {
|
|
|
38176
38201
|
});
|
|
38177
38202
|
}
|
|
38178
38203
|
}, { onCancel: onPromptCancel });
|
|
38204
|
+
return await executeCreate({
|
|
38205
|
+
template: result.template,
|
|
38206
|
+
name: result.name,
|
|
38207
|
+
description: result.description || void 0,
|
|
38208
|
+
projectPath: result.projectPath,
|
|
38209
|
+
deploy: options.deploy,
|
|
38210
|
+
isInteractive: true
|
|
38211
|
+
});
|
|
38212
|
+
}
|
|
38213
|
+
async function createNonInteractive(options) {
|
|
38214
|
+
return await executeCreate({
|
|
38215
|
+
template: await getDefaultTemplate(),
|
|
38216
|
+
name: options.name,
|
|
38217
|
+
description: options.description,
|
|
38218
|
+
projectPath: options.path,
|
|
38219
|
+
deploy: options.deploy,
|
|
38220
|
+
isInteractive: false
|
|
38221
|
+
});
|
|
38222
|
+
}
|
|
38223
|
+
async function executeCreate({ template, name: rawName, description, projectPath, deploy, isInteractive }) {
|
|
38224
|
+
const name$1 = rawName.trim();
|
|
38179
38225
|
const resolvedPath = resolve(projectPath);
|
|
38180
38226
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
38181
38227
|
return await createProjectFiles({
|
|
38182
|
-
name: name$1
|
|
38183
|
-
description: description
|
|
38228
|
+
name: name$1,
|
|
38229
|
+
description: description?.trim(),
|
|
38184
38230
|
path: resolvedPath,
|
|
38185
38231
|
template
|
|
38186
38232
|
});
|
|
@@ -38188,12 +38234,16 @@ async function create() {
|
|
|
38188
38234
|
successMessage: orange("Project created successfully"),
|
|
38189
38235
|
errorMessage: "Failed to create project"
|
|
38190
38236
|
});
|
|
38191
|
-
await loadProjectEnv();
|
|
38237
|
+
await loadProjectEnv(resolvedPath);
|
|
38192
38238
|
const { project, entities } = await readProjectConfig(resolvedPath);
|
|
38193
|
-
let
|
|
38239
|
+
let finalAppUrl;
|
|
38194
38240
|
if (entities.length > 0) {
|
|
38195
|
-
|
|
38196
|
-
if (
|
|
38241
|
+
let shouldPushEntities;
|
|
38242
|
+
if (isInteractive) {
|
|
38243
|
+
const result = await ye({ message: "Would you like to push entities now?" });
|
|
38244
|
+
shouldPushEntities = !pD(result) && result;
|
|
38245
|
+
} else shouldPushEntities = !!deploy;
|
|
38246
|
+
if (shouldPushEntities) await runTask(`Pushing ${entities.length} entities to Base44...`, async () => {
|
|
38197
38247
|
await pushEntities(entities);
|
|
38198
38248
|
}, {
|
|
38199
38249
|
successMessage: orange("Entities pushed successfully"),
|
|
@@ -38201,11 +38251,14 @@ async function create() {
|
|
|
38201
38251
|
});
|
|
38202
38252
|
}
|
|
38203
38253
|
if (project.site) {
|
|
38204
|
-
const installCommand = project.site
|
|
38205
|
-
|
|
38206
|
-
|
|
38207
|
-
|
|
38208
|
-
|
|
38254
|
+
const { installCommand, buildCommand, outputDirectory } = project.site;
|
|
38255
|
+
let shouldDeploy;
|
|
38256
|
+
if (isInteractive) {
|
|
38257
|
+
const result = await ye({ message: "Would you like to deploy the site now?" });
|
|
38258
|
+
shouldDeploy = !pD(result) && result;
|
|
38259
|
+
} else shouldDeploy = !!deploy;
|
|
38260
|
+
if (shouldDeploy && installCommand && buildCommand && outputDirectory) {
|
|
38261
|
+
const { appUrl } = await runTask("Installing dependencies...", async (updateMessage) => {
|
|
38209
38262
|
await execa({
|
|
38210
38263
|
cwd: resolvedPath,
|
|
38211
38264
|
shell: true
|
|
@@ -38216,53 +38269,48 @@ async function create() {
|
|
|
38216
38269
|
shell: true
|
|
38217
38270
|
})`${buildCommand}`;
|
|
38218
38271
|
updateMessage("Deploying site...");
|
|
38219
|
-
return await deploySite(join(resolvedPath,
|
|
38272
|
+
return await deploySite(join(resolvedPath, outputDirectory));
|
|
38220
38273
|
}, {
|
|
38221
38274
|
successMessage: orange("Site deployed successfully"),
|
|
38222
38275
|
errorMessage: "Failed to deploy site"
|
|
38223
38276
|
});
|
|
38224
|
-
|
|
38277
|
+
finalAppUrl = appUrl;
|
|
38225
38278
|
}
|
|
38226
38279
|
}
|
|
38227
38280
|
const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/preview`;
|
|
38228
|
-
M.message(`${source_default.dim("Project")}: ${orange(name$1
|
|
38281
|
+
M.message(`${source_default.dim("Project")}: ${orange(name$1)}`);
|
|
38229
38282
|
M.message(`${source_default.dim("Dashboard")}: ${cyan(dashboardUrl)}`);
|
|
38230
|
-
if (
|
|
38231
|
-
|
|
38283
|
+
if (finalAppUrl) M.message(`${source_default.dim("Site")}: ${cyan(finalAppUrl)}`);
|
|
38284
|
+
return { outroMessage: "Your project is set and ready to use" };
|
|
38232
38285
|
}
|
|
38233
|
-
const createCommand = new Command("create").description("Create a new Base44 project").action(async () => {
|
|
38234
|
-
await
|
|
38235
|
-
fullBanner: true,
|
|
38236
|
-
requireAuth: true
|
|
38237
|
-
});
|
|
38286
|
+
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).action(async (options) => {
|
|
38287
|
+
await chooseCreate(options);
|
|
38238
38288
|
});
|
|
38239
38289
|
|
|
38240
38290
|
//#endregion
|
|
38241
38291
|
//#region src/cli/commands/site/deploy.ts
|
|
38242
|
-
async function deployAction() {
|
|
38292
|
+
async function deployAction(options) {
|
|
38243
38293
|
const { project } = await readProjectConfig();
|
|
38244
38294
|
if (!project.site?.outputDirectory) throw new Error("No site configuration found. Please add 'site.outputDirectory' to your config.jsonc");
|
|
38245
38295
|
const outputDir = resolve(project.root, project.site.outputDirectory);
|
|
38246
|
-
|
|
38247
|
-
|
|
38248
|
-
|
|
38249
|
-
return;
|
|
38296
|
+
if (!options.yes) {
|
|
38297
|
+
const shouldDeploy = await ye({ message: `Deploy site from ${project.site.outputDirectory}?` });
|
|
38298
|
+
if (pD(shouldDeploy) || !shouldDeploy) return { outroMessage: "Deployment cancelled" };
|
|
38250
38299
|
}
|
|
38251
|
-
|
|
38300
|
+
return { outroMessage: `Visit your site at: ${(await runTask("Creating archive and deploying site...", async () => {
|
|
38252
38301
|
return await deploySite(outputDir);
|
|
38253
38302
|
}, {
|
|
38254
38303
|
successMessage: "Site deployed successfully",
|
|
38255
38304
|
errorMessage: "Deployment failed"
|
|
38256
|
-
});
|
|
38257
|
-
M.success(`Site deployed to: ${result.app_url}`);
|
|
38305
|
+
})).appUrl}` };
|
|
38258
38306
|
}
|
|
38259
|
-
const siteDeployCommand = new Command("site").description("Manage site deployments").addCommand(new Command("deploy").description("Deploy built site files to Base44 hosting").action(async () => {
|
|
38260
|
-
await runCommand(deployAction, { requireAuth: true });
|
|
38307
|
+
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) => {
|
|
38308
|
+
await runCommand(() => deployAction(options), { requireAuth: true });
|
|
38261
38309
|
}));
|
|
38262
38310
|
|
|
38263
38311
|
//#endregion
|
|
38264
38312
|
//#region package.json
|
|
38265
|
-
var version = "0.0.
|
|
38313
|
+
var version = "0.0.8";
|
|
38266
38314
|
|
|
38267
38315
|
//#endregion
|
|
38268
38316
|
//#region src/cli/index.ts
|