@base44-preview/cli 0.0.55-pr.546.2cca7dc → 0.0.55-pr.547.7e43787
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/README.md +7 -0
- package/dist/cli/index.js +367 -134
- package/dist/cli/index.js.map +28 -18
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -120878,7 +120878,7 @@ function parse42(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
|
|
|
120878
120878
|
}
|
|
120879
120879
|
return res;
|
|
120880
120880
|
}
|
|
120881
|
-
async function
|
|
120881
|
+
async function readFile3(file2) {
|
|
120882
120882
|
if (isUrlString(file2)) {
|
|
120883
120883
|
file2 = new URL(file2);
|
|
120884
120884
|
}
|
|
@@ -134672,7 +134672,7 @@ ${codeblock}`, options8);
|
|
|
134672
134672
|
"\\": "\\"
|
|
134673
134673
|
};
|
|
134674
134674
|
KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
|
|
134675
|
-
read_file_default =
|
|
134675
|
+
read_file_default = readFile3;
|
|
134676
134676
|
loadConfigFromPackageJson = process.versions.bun ? async function loadConfigFromBunPackageJson(file2) {
|
|
134677
134677
|
const { prettier } = await readBunPackageJson(file2);
|
|
134678
134678
|
return prettier;
|
|
@@ -143907,7 +143907,7 @@ var require_parse7 = __commonJS((exports) => {
|
|
|
143907
143907
|
extension: url3.getExtension(path18)
|
|
143908
143908
|
};
|
|
143909
143909
|
try {
|
|
143910
|
-
const resolver = await
|
|
143910
|
+
const resolver = await readFile4(file2, options8, $refs);
|
|
143911
143911
|
$ref.pathType = resolver.plugin.name;
|
|
143912
143912
|
file2.data = resolver.result;
|
|
143913
143913
|
const parser2 = await parseFile(file2, options8, $refs);
|
|
@@ -143920,7 +143920,7 @@ var require_parse7 = __commonJS((exports) => {
|
|
|
143920
143920
|
throw err;
|
|
143921
143921
|
}
|
|
143922
143922
|
}
|
|
143923
|
-
async function
|
|
143923
|
+
async function readFile4(file2, options8, $refs) {
|
|
143924
143924
|
let resolvers = plugins.all(options8.resolve);
|
|
143925
143925
|
resolvers = plugins.filter(resolvers, "canRead", file2);
|
|
143926
143926
|
plugins.sort(resolvers);
|
|
@@ -218285,7 +218285,6 @@ var PROJECT_CONFIG_PATTERNS = [
|
|
|
218285
218285
|
`${PROJECT_SUBDIR}/config.${CONFIG_FILE_EXTENSION_GLOB}`,
|
|
218286
218286
|
`config.${CONFIG_FILE_EXTENSION_GLOB}`
|
|
218287
218287
|
];
|
|
218288
|
-
var BASE44_APP_ID_ENV_VAR = "BASE44_APP_ID";
|
|
218289
218288
|
var TYPES_OUTPUT_SUBDIR = ".types";
|
|
218290
218289
|
var TYPES_FILENAME = "types.d.ts";
|
|
218291
218290
|
var AUTH_CLIENT_ID = "base44_cli";
|
|
@@ -233981,7 +233980,7 @@ async function parseEnvFile(filePath) {
|
|
|
233981
233980
|
}
|
|
233982
233981
|
var STRIPE_ENV_PREFIX = "BASE44_PROJECTS_";
|
|
233983
233982
|
var BASE44_ENV_KEYS = [
|
|
233984
|
-
|
|
233983
|
+
"BASE44_APP_ID",
|
|
233985
233984
|
"BASE44_ACCESS_TOKEN",
|
|
233986
233985
|
"BASE44_REFRESH_TOKEN",
|
|
233987
233986
|
"BASE44_API_URL"
|
|
@@ -241695,35 +241694,18 @@ function loadFromTestOverrides() {
|
|
|
241695
241694
|
}
|
|
241696
241695
|
return null;
|
|
241697
241696
|
}
|
|
241698
|
-
async function initAppContext(
|
|
241697
|
+
async function initAppContext() {
|
|
241699
241698
|
const testConfig = loadFromTestOverrides();
|
|
241700
241699
|
if (testConfig) {
|
|
241701
241700
|
cache2 = testConfig;
|
|
241702
241701
|
return cache2;
|
|
241703
241702
|
}
|
|
241704
|
-
const projectRoot = findProjectRoot();
|
|
241705
|
-
if (options.appId !== undefined) {
|
|
241706
|
-
const id = options.appId.trim();
|
|
241707
|
-
if (!id) {
|
|
241708
|
-
throw new InvalidInputError("App id cannot be empty.");
|
|
241709
|
-
}
|
|
241710
|
-
cache2 = { id };
|
|
241711
|
-
return cache2;
|
|
241712
|
-
}
|
|
241713
241703
|
if (cache2) {
|
|
241714
241704
|
return cache2;
|
|
241715
241705
|
}
|
|
241706
|
+
const projectRoot = findProjectRoot();
|
|
241716
241707
|
if (!projectRoot) {
|
|
241717
|
-
throw new ConfigNotFoundError(
|
|
241718
|
-
hints: [
|
|
241719
|
-
{ message: "Pass an app ID explicitly with --app-id <id>" },
|
|
241720
|
-
{ message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` },
|
|
241721
|
-
{
|
|
241722
|
-
message: "Run from a linked Base44 project with base44/.app.jsonc, or run 'base44 link'",
|
|
241723
|
-
command: "base44 link"
|
|
241724
|
-
}
|
|
241725
|
-
]
|
|
241726
|
-
});
|
|
241708
|
+
throw new ConfigNotFoundError("No Base44 project found. Run this command from a project directory with a config.jsonc file.");
|
|
241727
241709
|
}
|
|
241728
241710
|
const config3 = await readAppConfig(projectRoot.root);
|
|
241729
241711
|
const appConfigPath = await findAppConfigPath(projectRoot.root);
|
|
@@ -244260,6 +244242,11 @@ function getAppClient() {
|
|
|
244260
244242
|
prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
|
|
244261
244243
|
});
|
|
244262
244244
|
}
|
|
244245
|
+
function getSandboxClient(appId) {
|
|
244246
|
+
return base44Client.extend({
|
|
244247
|
+
prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
|
|
244248
|
+
});
|
|
244249
|
+
}
|
|
244263
244250
|
// src/core/clients/oauth-client.ts
|
|
244264
244251
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
244265
244252
|
var oauthClient = distribution_default.create({
|
|
@@ -244451,8 +244438,8 @@ async function ensureAuth(ctx) {
|
|
|
244451
244438
|
});
|
|
244452
244439
|
} catch {}
|
|
244453
244440
|
}
|
|
244454
|
-
async function ensureAppContext(ctx
|
|
244455
|
-
const appContext = await initAppContext(
|
|
244441
|
+
async function ensureAppContext(ctx) {
|
|
244442
|
+
const appContext = await initAppContext();
|
|
244456
244443
|
ctx.app = appContext;
|
|
244457
244444
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
244458
244445
|
}
|
|
@@ -251118,8 +251105,7 @@ class Base44Command extends Command {
|
|
|
251118
251105
|
await ensureAuth(this.context);
|
|
251119
251106
|
}
|
|
251120
251107
|
if (this._commandOptions.requireAppContext) {
|
|
251121
|
-
|
|
251122
|
-
await ensureAppContext(this.context, { appId });
|
|
251108
|
+
await ensureAppContext(this.context);
|
|
251123
251109
|
}
|
|
251124
251110
|
const result = await fn(this.context, ...args) ?? {};
|
|
251125
251111
|
if (!quiet) {
|
|
@@ -251195,7 +251181,7 @@ function createSimpleRunTask(log) {
|
|
|
251195
251181
|
};
|
|
251196
251182
|
}
|
|
251197
251183
|
// src/cli/utils/stdin.ts
|
|
251198
|
-
async function readStdin(flagName = "--stdin") {
|
|
251184
|
+
async function readStdin(flagName = "--stdin", options = {}) {
|
|
251199
251185
|
if (process.stdin.isTTY) {
|
|
251200
251186
|
throw new InvalidInputError(`${flagName} requires piped input (e.g., echo <value> | base44 ...)`);
|
|
251201
251187
|
}
|
|
@@ -251203,7 +251189,8 @@ async function readStdin(flagName = "--stdin") {
|
|
|
251203
251189
|
for await (const chunk of process.stdin) {
|
|
251204
251190
|
chunks.push(chunk);
|
|
251205
251191
|
}
|
|
251206
|
-
|
|
251192
|
+
const text = Buffer.concat(chunks).toString("utf-8");
|
|
251193
|
+
return options.trim === false ? text : text.trim();
|
|
251207
251194
|
}
|
|
251208
251195
|
|
|
251209
251196
|
// src/cli/utils/secret-input.ts
|
|
@@ -253088,11 +253075,7 @@ function printProjectSummary({ name: name2, dashboardUrl, appUrl }, log) {
|
|
|
253088
253075
|
}
|
|
253089
253076
|
|
|
253090
253077
|
// src/cli/commands/project/create.ts
|
|
253091
|
-
function
|
|
253092
|
-
const { appId } = command2.optsWithGlobals();
|
|
253093
|
-
if (appId !== undefined) {
|
|
253094
|
-
command2.error(`base44 create cannot be used with --app-id or ${BASE44_APP_ID_ENV_VAR}.`);
|
|
253095
|
-
}
|
|
253078
|
+
function validateNonInteractiveFlags(command2) {
|
|
253096
253079
|
const { path: path17 } = command2.opts();
|
|
253097
253080
|
if (path17 && !command2.args.length) {
|
|
253098
253081
|
command2.error("--path requires a project name argument. Usage: base44 create <name> --path <path>");
|
|
@@ -253209,7 +253192,7 @@ function getCreateCommand() {
|
|
|
253209
253192
|
Examples:
|
|
253210
253193
|
$ base44 create my-app Creates a base44 project at ./my-app
|
|
253211
253194
|
$ base44 create my-todo-app --template backend-and-client Creates a base44 backend-and-client project at ./my-todo-app
|
|
253212
|
-
$ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction",
|
|
253195
|
+
$ base44 create my-app --path ./projects/my-app --deploy Creates a base44 project at ./project/my-app and deploys it`).hook("preAction", validateNonInteractiveFlags).action(createAction);
|
|
253213
253196
|
}
|
|
253214
253197
|
|
|
253215
253198
|
// src/cli/commands/project/deploy.ts
|
|
@@ -253305,32 +253288,11 @@ function printStripeResult(r, log) {
|
|
|
253305
253288
|
log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
253306
253289
|
}
|
|
253307
253290
|
|
|
253308
|
-
// src/cli/commands/project/app-id-options.ts
|
|
253309
|
-
function readExplicitAppId(command2) {
|
|
253310
|
-
const { appId } = command2.optsWithGlobals();
|
|
253311
|
-
const { projectId } = command2.opts();
|
|
253312
|
-
const explicitAppId = command2.getOptionValueSourceWithGlobals("appId") === "cli" ? appId : undefined;
|
|
253313
|
-
const legacyProjectId = command2.getOptionValueSource("projectId") === "cli" ? projectId : undefined;
|
|
253314
|
-
return {
|
|
253315
|
-
appId: explicitAppId,
|
|
253316
|
-
legacyProjectId,
|
|
253317
|
-
value: explicitAppId ?? legacyProjectId
|
|
253318
|
-
};
|
|
253319
|
-
}
|
|
253320
|
-
|
|
253321
253291
|
// src/cli/commands/project/link.ts
|
|
253322
|
-
function
|
|
253323
|
-
const { create: create4, name: name2 } = command2.opts();
|
|
253324
|
-
|
|
253325
|
-
|
|
253326
|
-
legacyProjectId,
|
|
253327
|
-
value: selectedAppId
|
|
253328
|
-
} = readExplicitAppId(command2);
|
|
253329
|
-
if (appId && legacyProjectId) {
|
|
253330
|
-
command2.error("--app-id and --project-id cannot be used together");
|
|
253331
|
-
}
|
|
253332
|
-
if (create4 && selectedAppId) {
|
|
253333
|
-
command2.error("--create and --app-id cannot be used together");
|
|
253292
|
+
function validateNonInteractiveFlags2(command2) {
|
|
253293
|
+
const { create: create4, name: name2, projectId } = command2.opts();
|
|
253294
|
+
if (create4 && projectId) {
|
|
253295
|
+
command2.error("--create and --projectId cannot be used together");
|
|
253334
253296
|
}
|
|
253335
253297
|
if (create4 && !name2) {
|
|
253336
253298
|
command2.error("--name is required when using --create");
|
|
@@ -253399,12 +253361,11 @@ async function promptForExistingProject(linkableProjects) {
|
|
|
253399
253361
|
}
|
|
253400
253362
|
return selectedProject;
|
|
253401
253363
|
}
|
|
253402
|
-
async function link(ctx, options
|
|
253364
|
+
async function link(ctx, options) {
|
|
253403
253365
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
253404
|
-
const
|
|
253405
|
-
const skipPrompts = !!options.create || !!appId;
|
|
253366
|
+
const skipPrompts = !!options.create || !!options.projectId;
|
|
253406
253367
|
if (!skipPrompts && isNonInteractive) {
|
|
253407
|
-
throw new InvalidInputError("--create with --name, or --
|
|
253368
|
+
throw new InvalidInputError("--create with --name, or --projectId, is required in non-interactive mode");
|
|
253408
253369
|
}
|
|
253409
253370
|
const projectRoot = findProjectRoot();
|
|
253410
253371
|
if (!projectRoot) {
|
|
@@ -253419,8 +253380,8 @@ async function link(ctx, options, command2) {
|
|
|
253419
253380
|
]
|
|
253420
253381
|
});
|
|
253421
253382
|
}
|
|
253422
|
-
let
|
|
253423
|
-
const action =
|
|
253383
|
+
let finalProjectId;
|
|
253384
|
+
const action = options.projectId ? "choose" : options.create ? "create" : await promptForLinkAction();
|
|
253424
253385
|
if (action === "choose") {
|
|
253425
253386
|
const projects = await runTask2("Fetching projects...", async () => listProjects(), {
|
|
253426
253387
|
successMessage: "Projects fetched",
|
|
@@ -253430,32 +253391,32 @@ async function link(ctx, options, command2) {
|
|
|
253430
253391
|
if (!linkableProjects.length) {
|
|
253431
253392
|
return { outroMessage: "No projects available for linking" };
|
|
253432
253393
|
}
|
|
253433
|
-
let
|
|
253434
|
-
if (
|
|
253435
|
-
const project2 = linkableProjects.find((p) => p.id ===
|
|
253394
|
+
let projectId;
|
|
253395
|
+
if (options.projectId) {
|
|
253396
|
+
const project2 = linkableProjects.find((p) => p.id === options.projectId);
|
|
253436
253397
|
if (!project2) {
|
|
253437
|
-
throw new InvalidInputError(`
|
|
253398
|
+
throw new InvalidInputError(`Project with ID "${options.projectId}" not found or not available for linking.`, {
|
|
253438
253399
|
hints: [
|
|
253439
|
-
{ message: "Check the
|
|
253400
|
+
{ message: "Check the project ID is correct" },
|
|
253440
253401
|
{
|
|
253441
|
-
message: "Use 'base44 link' without --
|
|
253402
|
+
message: "Use 'base44 link' without --projectId to see available projects"
|
|
253442
253403
|
}
|
|
253443
253404
|
]
|
|
253444
253405
|
});
|
|
253445
253406
|
}
|
|
253446
|
-
|
|
253407
|
+
projectId = options.projectId;
|
|
253447
253408
|
} else {
|
|
253448
253409
|
const selectedProject = await promptForExistingProject(linkableProjects);
|
|
253449
|
-
|
|
253410
|
+
projectId = selectedProject.id;
|
|
253450
253411
|
}
|
|
253451
253412
|
await runTask2("Linking project...", async () => {
|
|
253452
|
-
await writeAppConfig(projectRoot.root,
|
|
253453
|
-
setAppContext({ id:
|
|
253413
|
+
await writeAppConfig(projectRoot.root, projectId);
|
|
253414
|
+
setAppContext({ id: projectId, projectRoot: projectRoot.root });
|
|
253454
253415
|
}, {
|
|
253455
253416
|
successMessage: "Project linked successfully",
|
|
253456
253417
|
errorMessage: "Failed to link project"
|
|
253457
253418
|
});
|
|
253458
|
-
|
|
253419
|
+
finalProjectId = projectId;
|
|
253459
253420
|
}
|
|
253460
253421
|
if (action === "create") {
|
|
253461
253422
|
const { name: name2, description } = options.create ? { name: options.name.trim(), description: options.description?.trim() } : await promptForNewProjectDetails();
|
|
@@ -253467,15 +253428,13 @@ async function link(ctx, options, command2) {
|
|
|
253467
253428
|
});
|
|
253468
253429
|
await writeAppConfig(projectRoot.root, projectId);
|
|
253469
253430
|
setAppContext({ id: projectId, projectRoot: projectRoot.root });
|
|
253470
|
-
|
|
253431
|
+
finalProjectId = projectId;
|
|
253471
253432
|
}
|
|
253472
|
-
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(
|
|
253433
|
+
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(finalProjectId))}`);
|
|
253473
253434
|
return { outroMessage: "Project linked" };
|
|
253474
253435
|
}
|
|
253475
253436
|
function getLinkCommand() {
|
|
253476
|
-
return new Base44Command("link", {
|
|
253477
|
-
requireAppContext: false
|
|
253478
|
-
}).description("Link a local project to a Base44 project (create new or link existing)").configureHelp({ showGlobalOptions: true }).option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").addOption(new Option("-p, --project-id <id>", "Project ID to link to an existing project").hideHelp()).addOption(new Option("--projectId <id>", "Project ID to link to an existing project").hideHelp()).hook("preAction", validateNonInteractiveFlags).action(link);
|
|
253437
|
+
return new Base44Command("link", { requireAppContext: false }).description("Link a local project to a Base44 project (create new or link existing)").option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").option("-p, --projectId <id>", "Project ID to link to an existing project (skips selection prompt)").hook("preAction", validateNonInteractiveFlags2).action(link);
|
|
253479
253438
|
}
|
|
253480
253439
|
|
|
253481
253440
|
// src/cli/commands/project/logs.ts
|
|
@@ -253565,12 +253524,8 @@ async function fetchLogsForFunctions(functionNames, options, availableFunctionNa
|
|
|
253565
253524
|
}
|
|
253566
253525
|
return allEntries;
|
|
253567
253526
|
}
|
|
253568
|
-
async function
|
|
253569
|
-
const { functions } = await readProjectConfig(
|
|
253570
|
-
return functions.map((fn) => fn.name);
|
|
253571
|
-
}
|
|
253572
|
-
async function getRemoteFunctionNames() {
|
|
253573
|
-
const { functions } = await listDeployedFunctions();
|
|
253527
|
+
async function getAllFunctionNames() {
|
|
253528
|
+
const { functions } = await readProjectConfig();
|
|
253574
253529
|
return functions.map((fn) => fn.name);
|
|
253575
253530
|
}
|
|
253576
253531
|
function validateLimit(limit) {
|
|
@@ -253581,18 +253536,15 @@ function validateLimit(limit) {
|
|
|
253581
253536
|
throw new InvalidInputError(`Invalid limit: "${limit}". Must be a number between 1 and 1000.`);
|
|
253582
253537
|
}
|
|
253583
253538
|
}
|
|
253584
|
-
async function logsAction(
|
|
253539
|
+
async function logsAction(_ctx, options) {
|
|
253585
253540
|
validateLimit(options.limit);
|
|
253586
253541
|
const specifiedFunctions = parseFunctionNames(options.function);
|
|
253587
|
-
const
|
|
253588
|
-
const
|
|
253589
|
-
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : availableFunctionNames;
|
|
253542
|
+
const allProjectFunctions = await getAllFunctionNames();
|
|
253543
|
+
const functionNames = specifiedFunctions.length > 0 ? specifiedFunctions : allProjectFunctions;
|
|
253590
253544
|
if (functionNames.length === 0) {
|
|
253591
|
-
return {
|
|
253592
|
-
outroMessage: localProjectRoot ? "No functions found in this project." : "No functions found in this app."
|
|
253593
|
-
};
|
|
253545
|
+
return { outroMessage: "No functions found in this project." };
|
|
253594
253546
|
}
|
|
253595
|
-
let entries = await fetchLogsForFunctions(functionNames, options,
|
|
253547
|
+
let entries = await fetchLogsForFunctions(functionNames, options, allProjectFunctions);
|
|
253596
253548
|
const limit = options.limit ? Number.parseInt(options.limit, 10) : undefined;
|
|
253597
253549
|
if (limit !== undefined && entries.length > limit) {
|
|
253598
253550
|
entries = entries.slice(0, limit);
|
|
@@ -253608,20 +253560,17 @@ function getLogsCommand() {
|
|
|
253608
253560
|
// src/cli/commands/project/scaffold.ts
|
|
253609
253561
|
import { basename as basename5, resolve as resolve6 } from "node:path";
|
|
253610
253562
|
function resolveAppId(options) {
|
|
253611
|
-
const appId = options.appId;
|
|
253563
|
+
const appId = options.appId ?? process.env.BASE44_APP_ID;
|
|
253612
253564
|
if (!appId) {
|
|
253613
253565
|
throw new InvalidInputError("No app ID found. `base44 scaffold` sets up a local project for an existing Base44 app.", {
|
|
253614
|
-
hints: [
|
|
253615
|
-
{ message: "Pass it explicitly with --app-id <id>" },
|
|
253616
|
-
{ message: `Set ${BASE44_APP_ID_ENV_VAR} in your environment` }
|
|
253617
|
-
]
|
|
253566
|
+
hints: [{ message: "Pass it explicitly with --app-id <id>" }]
|
|
253618
253567
|
});
|
|
253619
253568
|
}
|
|
253620
253569
|
return appId;
|
|
253621
253570
|
}
|
|
253622
|
-
async function scaffoldAction(ctx, name2, options
|
|
253571
|
+
async function scaffoldAction(ctx, name2, options) {
|
|
253623
253572
|
const { log, runTask: runTask2 } = ctx;
|
|
253624
|
-
const appId = resolveAppId(
|
|
253573
|
+
const appId = resolveAppId(options);
|
|
253625
253574
|
const resolvedPath = resolve6("./");
|
|
253626
253575
|
const projectName = (name2 ?? basename5(resolvedPath)).trim();
|
|
253627
253576
|
const template2 = await getTemplateById("backend-only");
|
|
@@ -253653,12 +253602,308 @@ function getScaffoldCommand() {
|
|
|
253653
253602
|
return new Base44Command("scaffold", {
|
|
253654
253603
|
requireAppContext: false,
|
|
253655
253604
|
fullBanner: true
|
|
253656
|
-
}).description("Scaffold a local project for an existing Base44 app").addArgument(new Argument("name", "Project name").argOptional()).option("--no-skills", "Skip AI agent skills installation").addHelpText("after", `
|
|
253605
|
+
}).description("Scaffold a local project for an existing Base44 app").addArgument(new Argument("name", "Project name").argOptional()).option("--app-id <id>", "Existing Base44 app ID").option("--no-skills", "Skip AI agent skills installation").addHelpText("after", `
|
|
253657
253606
|
Examples:
|
|
253658
253607
|
$ base44 scaffold --app-id app_123 Scaffolds the current dir for the given app
|
|
253659
253608
|
$ base44 scaffold my-app --app-id app_123 Scaffolds the current dir, named "my-app"`).action(scaffoldAction);
|
|
253660
253609
|
}
|
|
253661
253610
|
|
|
253611
|
+
// src/core/resources/sandbox/schema.ts
|
|
253612
|
+
var FileErrorSchema = exports_external.object({
|
|
253613
|
+
code: exports_external.string(),
|
|
253614
|
+
message: exports_external.string()
|
|
253615
|
+
});
|
|
253616
|
+
var ReadFileEntrySchema = exports_external.object({
|
|
253617
|
+
path: exports_external.string(),
|
|
253618
|
+
content: exports_external.string().optional(),
|
|
253619
|
+
start_line: exports_external.number().optional(),
|
|
253620
|
+
end_line: exports_external.number().optional(),
|
|
253621
|
+
total_lines: exports_external.number().optional(),
|
|
253622
|
+
truncated: exports_external.boolean().optional(),
|
|
253623
|
+
error: FileErrorSchema.optional()
|
|
253624
|
+
}).transform((data) => ({
|
|
253625
|
+
path: data.path,
|
|
253626
|
+
content: data.content,
|
|
253627
|
+
startLine: data.start_line,
|
|
253628
|
+
endLine: data.end_line,
|
|
253629
|
+
totalLines: data.total_lines,
|
|
253630
|
+
truncated: data.truncated,
|
|
253631
|
+
error: data.error
|
|
253632
|
+
}));
|
|
253633
|
+
var ReadFileResponseSchema = exports_external.object({
|
|
253634
|
+
files: exports_external.array(ReadFileEntrySchema)
|
|
253635
|
+
});
|
|
253636
|
+
var WriteFileResponseSchema = exports_external.object({
|
|
253637
|
+
path: exports_external.string(),
|
|
253638
|
+
bytes_written: exports_external.number(),
|
|
253639
|
+
created: exports_external.boolean(),
|
|
253640
|
+
overwritten: exports_external.boolean()
|
|
253641
|
+
}).transform((data) => ({
|
|
253642
|
+
path: data.path,
|
|
253643
|
+
bytesWritten: data.bytes_written,
|
|
253644
|
+
created: data.created,
|
|
253645
|
+
overwritten: data.overwritten
|
|
253646
|
+
}));
|
|
253647
|
+
var EditFileResponseSchema = exports_external.object({
|
|
253648
|
+
path: exports_external.string(),
|
|
253649
|
+
diff: exports_external.string(),
|
|
253650
|
+
applied: exports_external.boolean()
|
|
253651
|
+
});
|
|
253652
|
+
var GrepMatchSchema = exports_external.object({
|
|
253653
|
+
path: exports_external.string().nullable(),
|
|
253654
|
+
line: exports_external.number().nullable(),
|
|
253655
|
+
text: exports_external.string()
|
|
253656
|
+
});
|
|
253657
|
+
var GrepResponseSchema = exports_external.object({
|
|
253658
|
+
matches: exports_external.array(GrepMatchSchema),
|
|
253659
|
+
truncated: exports_external.boolean(),
|
|
253660
|
+
returned_matches: exports_external.number()
|
|
253661
|
+
}).transform((data) => ({
|
|
253662
|
+
matches: data.matches,
|
|
253663
|
+
truncated: data.truncated,
|
|
253664
|
+
returnedMatches: data.returned_matches
|
|
253665
|
+
}));
|
|
253666
|
+
var DirectoryEntrySchema = exports_external.object({
|
|
253667
|
+
name: exports_external.string(),
|
|
253668
|
+
path: exports_external.string(),
|
|
253669
|
+
type: exports_external.enum(["file", "directory"]),
|
|
253670
|
+
size: exports_external.number().optional()
|
|
253671
|
+
});
|
|
253672
|
+
var ListDirectoryResponseSchema = exports_external.object({
|
|
253673
|
+
entries: exports_external.array(DirectoryEntrySchema),
|
|
253674
|
+
truncated: exports_external.boolean()
|
|
253675
|
+
});
|
|
253676
|
+
var RunCommandResponseSchema = exports_external.object({
|
|
253677
|
+
stdout: exports_external.string(),
|
|
253678
|
+
stderr: exports_external.string(),
|
|
253679
|
+
exit_code: exports_external.number(),
|
|
253680
|
+
truncated: exports_external.boolean(),
|
|
253681
|
+
duration_ms: exports_external.number()
|
|
253682
|
+
}).transform((data) => ({
|
|
253683
|
+
stdout: data.stdout,
|
|
253684
|
+
stderr: data.stderr,
|
|
253685
|
+
exitCode: data.exit_code,
|
|
253686
|
+
truncated: data.truncated,
|
|
253687
|
+
durationMs: data.duration_ms
|
|
253688
|
+
}));
|
|
253689
|
+
var ReleaseResponseSchema = exports_external.object({
|
|
253690
|
+
app_id: exports_external.string(),
|
|
253691
|
+
released: exports_external.boolean()
|
|
253692
|
+
}).transform((data) => ({
|
|
253693
|
+
appId: data.app_id,
|
|
253694
|
+
released: data.released
|
|
253695
|
+
}));
|
|
253696
|
+
|
|
253697
|
+
// src/core/resources/sandbox/api.ts
|
|
253698
|
+
async function callTool(appId, tool, payload, schema10, context, timeout2 = 60000) {
|
|
253699
|
+
const client = getSandboxClient(appId);
|
|
253700
|
+
let response;
|
|
253701
|
+
try {
|
|
253702
|
+
response = await client.post(tool, { json: payload, timeout: timeout2 });
|
|
253703
|
+
} catch (error48) {
|
|
253704
|
+
throw await ApiError.fromHttpError(error48, context);
|
|
253705
|
+
}
|
|
253706
|
+
const result = schema10.safeParse(await response.json());
|
|
253707
|
+
if (!result.success) {
|
|
253708
|
+
throw new SchemaValidationError("Invalid response from server", result.error);
|
|
253709
|
+
}
|
|
253710
|
+
return result.data;
|
|
253711
|
+
}
|
|
253712
|
+
function listDirectory(appId, params) {
|
|
253713
|
+
return callTool(appId, "list_directory", { ...params }, ListDirectoryResponseSchema, "listing directory");
|
|
253714
|
+
}
|
|
253715
|
+
function readFile2(appId, params) {
|
|
253716
|
+
return callTool(appId, "read_file", { ...params }, ReadFileResponseSchema, "reading file");
|
|
253717
|
+
}
|
|
253718
|
+
function writeFile2(appId, params) {
|
|
253719
|
+
return callTool(appId, "write_file", { ...params }, WriteFileResponseSchema, `writing file "${params.path}"`);
|
|
253720
|
+
}
|
|
253721
|
+
function editFile(appId, params) {
|
|
253722
|
+
return callTool(appId, "edit_file", { ...params }, EditFileResponseSchema, `editing file "${params.path}"`);
|
|
253723
|
+
}
|
|
253724
|
+
function grep(appId, params) {
|
|
253725
|
+
return callTool(appId, "grep", { ...params }, GrepResponseSchema, "searching files");
|
|
253726
|
+
}
|
|
253727
|
+
function runCommand(appId, params) {
|
|
253728
|
+
return callTool(appId, "run_command", { ...params }, RunCommandResponseSchema, "running command", false);
|
|
253729
|
+
}
|
|
253730
|
+
function releaseSession(appId) {
|
|
253731
|
+
return callTool(appId, "release", {}, ReleaseResponseSchema, "releasing sandbox session");
|
|
253732
|
+
}
|
|
253733
|
+
|
|
253734
|
+
// src/cli/commands/sandbox/shared.ts
|
|
253735
|
+
async function resolveAppId2(options) {
|
|
253736
|
+
const explicit = options.appId ?? process.env.BASE44_APP_ID;
|
|
253737
|
+
if (explicit) {
|
|
253738
|
+
return explicit;
|
|
253739
|
+
}
|
|
253740
|
+
try {
|
|
253741
|
+
const { id } = await initAppContext();
|
|
253742
|
+
return id;
|
|
253743
|
+
} catch {
|
|
253744
|
+
throw new InvalidInputError("No app ID found. Sandbox commands operate on a remote app.", {
|
|
253745
|
+
hints: [
|
|
253746
|
+
{ message: "Pass it explicitly with --app-id <id>" },
|
|
253747
|
+
{ message: "Or run from a linked Base44 project directory" }
|
|
253748
|
+
]
|
|
253749
|
+
});
|
|
253750
|
+
}
|
|
253751
|
+
}
|
|
253752
|
+
async function resolveFlagOrStdin(flagValue, flagName) {
|
|
253753
|
+
if (flagValue !== undefined) {
|
|
253754
|
+
return flagValue;
|
|
253755
|
+
}
|
|
253756
|
+
if (process.stdin.isTTY) {
|
|
253757
|
+
throw new InvalidInputError(`Provide ${flagName} or pipe the value via stdin (e.g. echo <value> | base44 sandbox ...).`);
|
|
253758
|
+
}
|
|
253759
|
+
return readStdin(flagName, { trim: false });
|
|
253760
|
+
}
|
|
253761
|
+
function toJsonStdout(result) {
|
|
253762
|
+
return `${JSON.stringify(result, null, 2)}
|
|
253763
|
+
`;
|
|
253764
|
+
}
|
|
253765
|
+
function parsePositiveInt(value, flagName) {
|
|
253766
|
+
if (value === undefined) {
|
|
253767
|
+
return;
|
|
253768
|
+
}
|
|
253769
|
+
const n2 = Number.parseInt(value, 10);
|
|
253770
|
+
if (!Number.isInteger(n2) || n2 < 1) {
|
|
253771
|
+
throw new InvalidInputError(`${flagName} must be a positive integer.`);
|
|
253772
|
+
}
|
|
253773
|
+
return n2;
|
|
253774
|
+
}
|
|
253775
|
+
|
|
253776
|
+
// src/cli/commands/sandbox/edit-file.ts
|
|
253777
|
+
var EditsInputSchema = exports_external.array(exports_external.object({
|
|
253778
|
+
old_text: exports_external.string().min(1),
|
|
253779
|
+
new_text: exports_external.string(),
|
|
253780
|
+
replace_all: exports_external.boolean().optional()
|
|
253781
|
+
})).min(1);
|
|
253782
|
+
function parseEdits(raw2) {
|
|
253783
|
+
let parsed;
|
|
253784
|
+
try {
|
|
253785
|
+
parsed = JSON.parse(raw2);
|
|
253786
|
+
} catch {
|
|
253787
|
+
throw new InvalidInputError("--edits-json must be valid JSON (an array of { old_text, new_text, replace_all? }).");
|
|
253788
|
+
}
|
|
253789
|
+
const result = EditsInputSchema.safeParse(parsed);
|
|
253790
|
+
if (!result.success) {
|
|
253791
|
+
throw new InvalidInputError("Invalid edits: expected a non-empty array of { old_text (non-empty string), new_text (string), replace_all? (boolean) }.");
|
|
253792
|
+
}
|
|
253793
|
+
return result.data;
|
|
253794
|
+
}
|
|
253795
|
+
async function editFileAction({ runTask: runTask2 }, path17, options) {
|
|
253796
|
+
const appId = await resolveAppId2(options);
|
|
253797
|
+
const raw2 = await resolveFlagOrStdin(options.editsJson, "--edits-json");
|
|
253798
|
+
const edits = parseEdits(raw2);
|
|
253799
|
+
const result = await runTask2(options.dryRun ? "Previewing edit" : "Editing file", () => editFile(appId, { path: path17, edits, dry_run: options.dryRun }));
|
|
253800
|
+
return {
|
|
253801
|
+
outroMessage: options.dryRun ? "Previewed edit" : "Edited file",
|
|
253802
|
+
stdout: toJsonStdout(result)
|
|
253803
|
+
};
|
|
253804
|
+
}
|
|
253805
|
+
function getSandboxEditFileCommand() {
|
|
253806
|
+
return new Base44Command("edit-file", { requireAppContext: false }).description("Apply exact old→new string edits to a file in the sandbox").argument("<path>", "File path relative to the app root").option("--edits-json <json>", "JSON array of edits (if omitted, read from stdin)").option("--dry-run", "Return the unified diff without writing").option("--app-id <id>", "Target app ID (defaults to the current app)").addHelpText("after", `
|
|
253807
|
+
Each edit is { "old_text": "...", "new_text": "...", "replace_all"?: true }.
|
|
253808
|
+
|
|
253809
|
+
Examples:
|
|
253810
|
+
$ echo '[{"old_text":"foo","new_text":"bar"}]' | base44 sandbox edit-file src/x.ts
|
|
253811
|
+
$ base44 sandbox edit-file src/x.ts --dry-run --edits-json '[{"old_text":"a","new_text":"b","replace_all":true}]'`).action(editFileAction);
|
|
253812
|
+
}
|
|
253813
|
+
|
|
253814
|
+
// src/cli/commands/sandbox/grep.ts
|
|
253815
|
+
async function grepAction({ runTask: runTask2 }, pattern, options) {
|
|
253816
|
+
const appId = await resolveAppId2(options);
|
|
253817
|
+
const maxResults = parsePositiveInt(options.maxResults, "--max-results");
|
|
253818
|
+
const result = await runTask2("Searching files", () => grep(appId, {
|
|
253819
|
+
pattern,
|
|
253820
|
+
path: options.path,
|
|
253821
|
+
is_regex: options.regex,
|
|
253822
|
+
case_sensitive: options.caseSensitive,
|
|
253823
|
+
glob: options.glob,
|
|
253824
|
+
max_results: maxResults
|
|
253825
|
+
}));
|
|
253826
|
+
return { outroMessage: "Searched files", stdout: toJsonStdout(result) };
|
|
253827
|
+
}
|
|
253828
|
+
function getSandboxGrepCommand() {
|
|
253829
|
+
return new Base44Command("grep", { requireAppContext: false }).description("Search files for a pattern in an app's remote sandbox").argument("<pattern>", "Search pattern").option("--path <path>", "Subtree to search, relative to the app root").option("--no-regex", "Treat the pattern as a literal string, not a regex").option("--case-sensitive", "Case-sensitive match").option("--glob <glob>", 'File glob filter, e.g. "*.tsx"').option("--max-results <n>", "Maximum number of match lines to return").option("--app-id <id>", "Target app ID (defaults to the current app)").action(grepAction);
|
|
253830
|
+
}
|
|
253831
|
+
|
|
253832
|
+
// src/cli/commands/sandbox/list-directory.ts
|
|
253833
|
+
async function listDirectoryAction({ runTask: runTask2 }, path17, options) {
|
|
253834
|
+
const appId = await resolveAppId2(options);
|
|
253835
|
+
const maxDepth = parsePositiveInt(options.maxDepth, "--max-depth");
|
|
253836
|
+
const result = await runTask2("Listing directory", () => listDirectory(appId, {
|
|
253837
|
+
path: path17,
|
|
253838
|
+
recursive: options.recursive,
|
|
253839
|
+
max_depth: maxDepth,
|
|
253840
|
+
include_hidden: options.includeHidden
|
|
253841
|
+
}));
|
|
253842
|
+
return { outroMessage: "Listed directory", stdout: toJsonStdout(result) };
|
|
253843
|
+
}
|
|
253844
|
+
function getSandboxListDirectoryCommand() {
|
|
253845
|
+
return new Base44Command("list-directory", { requireAppContext: false }).description("List directory entries in an app's remote sandbox").argument("[path]", "Directory relative to the app root (default: app root)").option("--recursive", "List nested entries").option("--max-depth <n>", "Max depth when recursive (1-10, default 3)").option("--include-hidden", "Include dotfiles").option("--app-id <id>", "Target app ID (defaults to the current app)").action(listDirectoryAction);
|
|
253846
|
+
}
|
|
253847
|
+
|
|
253848
|
+
// src/cli/commands/sandbox/read-file.ts
|
|
253849
|
+
async function readFileAction({ runTask: runTask2 }, paths, options) {
|
|
253850
|
+
const appId = await resolveAppId2(options);
|
|
253851
|
+
const offset = parsePositiveInt(options.offset, "--offset");
|
|
253852
|
+
const limit = parsePositiveInt(options.limit, "--limit");
|
|
253853
|
+
const result = await runTask2("Reading file", () => readFile2(appId, { paths, offset, limit }));
|
|
253854
|
+
return { outroMessage: "Read file", stdout: toJsonStdout(result) };
|
|
253855
|
+
}
|
|
253856
|
+
function getSandboxReadFileCommand() {
|
|
253857
|
+
return new Base44Command("read-file", { requireAppContext: false }).description("Read file contents from an app's remote sandbox").argument("<paths...>", "One or more file paths relative to the app root").option("--offset <n>", "1-based start line").option("--limit <n>", "Max lines to return from offset").option("--app-id <id>", "Target app ID (defaults to the current app)").action(readFileAction);
|
|
253858
|
+
}
|
|
253859
|
+
|
|
253860
|
+
// src/cli/commands/sandbox/release.ts
|
|
253861
|
+
async function releaseAction({ runTask: runTask2 }, options) {
|
|
253862
|
+
const appId = await resolveAppId2(options);
|
|
253863
|
+
const result = await runTask2("Releasing sandbox session", () => releaseSession(appId));
|
|
253864
|
+
return {
|
|
253865
|
+
outroMessage: "Released sandbox session",
|
|
253866
|
+
stdout: toJsonStdout(result)
|
|
253867
|
+
};
|
|
253868
|
+
}
|
|
253869
|
+
function getSandboxReleaseCommand() {
|
|
253870
|
+
return new Base44Command("release", { requireAppContext: false }).description("Release the external-agent session so the in-app builder can resume").option("--app-id <id>", "Target app ID (defaults to the current app)").action(releaseAction);
|
|
253871
|
+
}
|
|
253872
|
+
|
|
253873
|
+
// src/cli/commands/sandbox/run-command.ts
|
|
253874
|
+
async function runCommandAction({ runTask: runTask2 }, commandParts, options) {
|
|
253875
|
+
const appId = await resolveAppId2(options);
|
|
253876
|
+
const timeoutMs = parsePositiveInt(options.timeoutMs, "--timeout-ms");
|
|
253877
|
+
const command2 = commandParts.join(" ");
|
|
253878
|
+
const result = await runTask2("Running command", () => runCommand(appId, { command: command2, cwd: options.cwd, timeout_ms: timeoutMs }));
|
|
253879
|
+
return { outroMessage: "Ran command", stdout: toJsonStdout(result) };
|
|
253880
|
+
}
|
|
253881
|
+
function getSandboxRunCommandCommand() {
|
|
253882
|
+
return new Base44Command("run-command", { requireAppContext: false }).description("Run a shell command in an app's remote sandbox").argument("<command...>", "Shell command to execute (quote to keep as one)").option("--cwd <path>", "Working directory relative to the app root").option("--timeout-ms <n>", "Timeout in milliseconds (default 120000, max 600000)").option("--app-id <id>", "Target app ID (defaults to the current app)").addHelpText("after", `
|
|
253883
|
+
Examples:
|
|
253884
|
+
$ base44 sandbox run-command "npm test"
|
|
253885
|
+
$ base44 sandbox run-command ls -la --cwd src`).action(runCommandAction);
|
|
253886
|
+
}
|
|
253887
|
+
|
|
253888
|
+
// src/cli/commands/sandbox/write-file.ts
|
|
253889
|
+
async function writeFileAction({ runTask: runTask2 }, path17, options) {
|
|
253890
|
+
const appId = await resolveAppId2(options);
|
|
253891
|
+
const content = await resolveFlagOrStdin(options.content, "--content");
|
|
253892
|
+
const result = await runTask2("Writing file", () => writeFile2(appId, { path: path17, content, overwrite: options.overwrite }));
|
|
253893
|
+
return { outroMessage: "Wrote file", stdout: toJsonStdout(result) };
|
|
253894
|
+
}
|
|
253895
|
+
function getSandboxWriteFileCommand() {
|
|
253896
|
+
return new Base44Command("write-file", { requireAppContext: false }).description("Create or overwrite a file in an app's remote sandbox").argument("<path>", "File path relative to the app root").option("--content <content>", "File content (if omitted, read from stdin)").option("--overwrite", "Overwrite the file if it already exists").option("--app-id <id>", "Target app ID (defaults to the current app)").addHelpText("after", `
|
|
253897
|
+
Examples:
|
|
253898
|
+
$ echo "hello" | base44 sandbox write-file notes.txt
|
|
253899
|
+
$ base44 sandbox write-file notes.txt --content "hello" --overwrite`).action(writeFileAction);
|
|
253900
|
+
}
|
|
253901
|
+
|
|
253902
|
+
// src/cli/commands/sandbox/index.ts
|
|
253903
|
+
function getSandboxCommand() {
|
|
253904
|
+
return new Command("sandbox").description("Develop an app remotely via its server-side sandbox").addCommand(getSandboxListDirectoryCommand()).addCommand(getSandboxReadFileCommand()).addCommand(getSandboxWriteFileCommand()).addCommand(getSandboxEditFileCommand()).addCommand(getSandboxGrepCommand()).addCommand(getSandboxRunCommandCommand()).addCommand(getSandboxReleaseCommand());
|
|
253905
|
+
}
|
|
253906
|
+
|
|
253662
253907
|
// src/cli/commands/secrets/delete.ts
|
|
253663
253908
|
async function deleteSecretAction({ runTask: runTask2 }, key) {
|
|
253664
253909
|
await runTask2(`Deleting secret "${key}"`, async () => {
|
|
@@ -257409,10 +257654,7 @@ function readStdin2() {
|
|
|
257409
257654
|
process.stdin.on("error", reject);
|
|
257410
257655
|
});
|
|
257411
257656
|
}
|
|
257412
|
-
async function execAction({
|
|
257413
|
-
app,
|
|
257414
|
-
isNonInteractive
|
|
257415
|
-
}) {
|
|
257657
|
+
async function execAction(isNonInteractive) {
|
|
257416
257658
|
const noInputError = new InvalidInputError("No input provided. Pipe a script to stdin.", {
|
|
257417
257659
|
hints: [
|
|
257418
257660
|
{ message: "File: cat ./script.ts | base44 exec" },
|
|
@@ -257428,7 +257670,7 @@ async function execAction({
|
|
|
257428
257670
|
if (!code2.trim()) {
|
|
257429
257671
|
throw noInputError;
|
|
257430
257672
|
}
|
|
257431
|
-
const { exitCode } = await runScript({ appId:
|
|
257673
|
+
const { exitCode } = await runScript({ appId: getAppContext().id, code: code2 });
|
|
257432
257674
|
if (exitCode !== 0) {
|
|
257433
257675
|
process.exitCode = exitCode;
|
|
257434
257676
|
}
|
|
@@ -257441,26 +257683,18 @@ Examples:
|
|
|
257441
257683
|
$ cat ./script.ts | base44 exec
|
|
257442
257684
|
|
|
257443
257685
|
Inline script:
|
|
257444
|
-
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async (
|
|
257445
|
-
return await execAction(
|
|
257686
|
+
$ echo "const users = await base44.entities.User.list()" | base44 exec`).action(async ({ isNonInteractive }) => {
|
|
257687
|
+
return await execAction(isNonInteractive);
|
|
257446
257688
|
});
|
|
257447
257689
|
}
|
|
257448
257690
|
|
|
257449
257691
|
// src/cli/commands/project/eject.ts
|
|
257450
257692
|
import { resolve as resolve12 } from "node:path";
|
|
257451
257693
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
257452
|
-
async function eject(ctx, options8
|
|
257694
|
+
async function eject(ctx, options8) {
|
|
257453
257695
|
const { log, runTask: runTask2, isNonInteractive } = ctx;
|
|
257454
|
-
|
|
257455
|
-
|
|
257456
|
-
legacyProjectId,
|
|
257457
|
-
value: selectedAppId
|
|
257458
|
-
} = readExplicitAppId(command2);
|
|
257459
|
-
if (appId && legacyProjectId) {
|
|
257460
|
-
throw new InvalidInputError("--app-id and --project-id cannot be used together");
|
|
257461
|
-
}
|
|
257462
|
-
if (isNonInteractive && !selectedAppId) {
|
|
257463
|
-
throw new InvalidInputError("--app-id is required in non-interactive mode");
|
|
257696
|
+
if (isNonInteractive && !options8.projectId) {
|
|
257697
|
+
throw new InvalidInputError("--project-id is required in non-interactive mode");
|
|
257464
257698
|
}
|
|
257465
257699
|
if (isNonInteractive && !options8.path) {
|
|
257466
257700
|
throw new InvalidInputError("--path is required in non-interactive mode");
|
|
@@ -257468,13 +257702,13 @@ async function eject(ctx, options8, command2) {
|
|
|
257468
257702
|
const projects = await listProjects();
|
|
257469
257703
|
const ejectableProjects = projects.filter((p4) => p4.isManagedSourceCode !== false);
|
|
257470
257704
|
let selectedProject;
|
|
257471
|
-
if (
|
|
257472
|
-
const foundProject = ejectableProjects.find((p4) => p4.id ===
|
|
257705
|
+
if (options8.projectId) {
|
|
257706
|
+
const foundProject = ejectableProjects.find((p4) => p4.id === options8.projectId);
|
|
257473
257707
|
if (!foundProject) {
|
|
257474
|
-
throw new InvalidInputError(`
|
|
257708
|
+
throw new InvalidInputError(`Project with ID "${options8.projectId}" not found or not ejectable`, {
|
|
257475
257709
|
hints: [
|
|
257476
257710
|
{
|
|
257477
|
-
message: "Run 'base44 eject' without --
|
|
257711
|
+
message: "Run 'base44 eject' without --project-id to see available projects"
|
|
257478
257712
|
}
|
|
257479
257713
|
]
|
|
257480
257714
|
});
|
|
@@ -257550,15 +257784,13 @@ async function eject(ctx, options8, command2) {
|
|
|
257550
257784
|
return { outroMessage: "Your new project is set and ready to use" };
|
|
257551
257785
|
}
|
|
257552
257786
|
function getEjectCommand() {
|
|
257553
|
-
return new Base44Command("eject", {
|
|
257554
|
-
requireAppContext: false
|
|
257555
|
-
}).description("Download the code for an existing Base44 project").configureHelp({ showGlobalOptions: true }).option("-p, --path <path>", "Path where to write the project").option("-y, --yes", "Skip confirmation prompts").addOption(new Option("--project-id <id>", "Project ID to eject (skips interactive selection)").hideHelp()).action(eject);
|
|
257787
|
+
return new Base44Command("eject", { requireAppContext: false }).description("Download the code for an existing Base44 project").option("-p, --path <path>", "Path where to write the project").option("--project-id <id>", "Project ID to eject (skips interactive selection)").option("-y, --yes", "Skip confirmation prompts").action(eject);
|
|
257556
257788
|
}
|
|
257557
257789
|
|
|
257558
257790
|
// src/cli/program.ts
|
|
257559
257791
|
function createProgram(context) {
|
|
257560
257792
|
const program2 = new Command;
|
|
257561
|
-
program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version)
|
|
257793
|
+
program2.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version);
|
|
257562
257794
|
program2.configureHelp({
|
|
257563
257795
|
sortSubcommands: true
|
|
257564
257796
|
});
|
|
@@ -257581,6 +257813,7 @@ function createProgram(context) {
|
|
|
257581
257813
|
program2.addCommand(getConnectorsCommand());
|
|
257582
257814
|
program2.addCommand(getFunctionsCommand());
|
|
257583
257815
|
program2.addCommand(getSecretsCommand());
|
|
257816
|
+
program2.addCommand(getSandboxCommand());
|
|
257584
257817
|
program2.addCommand(getAuthCommand());
|
|
257585
257818
|
program2.addCommand(getSiteCommand());
|
|
257586
257819
|
program2.addCommand(getTypesCommand());
|
|
@@ -261832,4 +262065,4 @@ export {
|
|
|
261832
262065
|
CLIExitError
|
|
261833
262066
|
};
|
|
261834
262067
|
|
|
261835
|
-
//# debugId=
|
|
262068
|
+
//# debugId=61B9F8E330C194E064756E2164756E21
|