@base44-preview/cli 0.0.55-pr.545.e6bf97b → 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 +328 -124
- package/dist/cli/index.js.map +20 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,13 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
|
|
|
60
60
|
| [`secrets list`](https://docs.base44.com/developers/references/cli/commands/secrets-list) | List project secret names |
|
|
61
61
|
| [`secrets set`](https://docs.base44.com/developers/references/cli/commands/secrets-set) | Set one or more project secrets |
|
|
62
62
|
| [`secrets delete`](https://docs.base44.com/developers/references/cli/commands/secrets-delete) | Delete a project secret |
|
|
63
|
+
| [`sandbox list-directory`](https://docs.base44.com/developers/references/cli/commands/sandbox-list-directory) | List directory entries in an app's remote sandbox |
|
|
64
|
+
| [`sandbox read-file`](https://docs.base44.com/developers/references/cli/commands/sandbox-read-file) | Read file contents from an app's remote sandbox |
|
|
65
|
+
| [`sandbox write-file`](https://docs.base44.com/developers/references/cli/commands/sandbox-write-file) | Create or overwrite a file in an app's remote sandbox |
|
|
66
|
+
| [`sandbox edit-file`](https://docs.base44.com/developers/references/cli/commands/sandbox-edit-file) | Apply exact old→new string edits to a file in the sandbox |
|
|
67
|
+
| [`sandbox grep`](https://docs.base44.com/developers/references/cli/commands/sandbox-grep) | Search files for a pattern in an app's remote sandbox |
|
|
68
|
+
| [`sandbox run-command`](https://docs.base44.com/developers/references/cli/commands/sandbox-run-command) | Run a shell command in an app's remote sandbox |
|
|
69
|
+
| [`sandbox release`](https://docs.base44.com/developers/references/cli/commands/sandbox-release) | Release the external-agent session so the in-app builder can resume |
|
|
63
70
|
| [`site deploy`](https://docs.base44.com/developers/references/cli/commands/site-deploy) | Deploy built site files to Base44 hosting |
|
|
64
71
|
| [`site open`](https://docs.base44.com/developers/references/cli/commands/site-open) | Open the published site in your browser |
|
|
65
72
|
| [`types generate`](https://docs.base44.com/developers/references/cli/commands/types-generate) | Generate TypeScript types from project resources |
|
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);
|
|
@@ -244242,6 +244242,11 @@ function getAppClient() {
|
|
|
244242
244242
|
prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
|
|
244243
244243
|
});
|
|
244244
244244
|
}
|
|
244245
|
+
function getSandboxClient(appId) {
|
|
244246
|
+
return base44Client.extend({
|
|
244247
|
+
prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
|
|
244248
|
+
});
|
|
244249
|
+
}
|
|
244245
244250
|
// src/core/clients/oauth-client.ts
|
|
244246
244251
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
244247
244252
|
var oauthClient = distribution_default.create({
|
|
@@ -251176,7 +251181,7 @@ function createSimpleRunTask(log) {
|
|
|
251176
251181
|
};
|
|
251177
251182
|
}
|
|
251178
251183
|
// src/cli/utils/stdin.ts
|
|
251179
|
-
async function readStdin(flagName = "--stdin") {
|
|
251184
|
+
async function readStdin(flagName = "--stdin", options = {}) {
|
|
251180
251185
|
if (process.stdin.isTTY) {
|
|
251181
251186
|
throw new InvalidInputError(`${flagName} requires piped input (e.g., echo <value> | base44 ...)`);
|
|
251182
251187
|
}
|
|
@@ -251184,7 +251189,8 @@ async function readStdin(flagName = "--stdin") {
|
|
|
251184
251189
|
for await (const chunk of process.stdin) {
|
|
251185
251190
|
chunks.push(chunk);
|
|
251186
251191
|
}
|
|
251187
|
-
|
|
251192
|
+
const text = Buffer.concat(chunks).toString("utf-8");
|
|
251193
|
+
return options.trim === false ? text : text.trim();
|
|
251188
251194
|
}
|
|
251189
251195
|
|
|
251190
251196
|
// src/cli/utils/secret-input.ts
|
|
@@ -253602,6 +253608,302 @@ Examples:
|
|
|
253602
253608
|
$ base44 scaffold my-app --app-id app_123 Scaffolds the current dir, named "my-app"`).action(scaffoldAction);
|
|
253603
253609
|
}
|
|
253604
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
|
+
|
|
253605
253907
|
// src/cli/commands/secrets/delete.ts
|
|
253606
253908
|
async function deleteSecretAction({ runTask: runTask2 }, key) {
|
|
253607
253909
|
await runTask2(`Deleting secret "${key}"`, async () => {
|
|
@@ -253898,6 +254200,7 @@ function getTypesCommand() {
|
|
|
253898
254200
|
|
|
253899
254201
|
// src/cli/commands/dev.ts
|
|
253900
254202
|
import { join as join28 } from "node:path";
|
|
254203
|
+
import process21 from "node:process";
|
|
253901
254204
|
|
|
253902
254205
|
// src/cli/dev/dev-server/main.ts
|
|
253903
254206
|
var import_cors = __toESM(require_lib4(), 1);
|
|
@@ -254054,11 +254357,12 @@ var stringify = (item) => {
|
|
|
254054
254357
|
return String(item);
|
|
254055
254358
|
}
|
|
254056
254359
|
};
|
|
254057
|
-
function createDevLogger(
|
|
254058
|
-
const prefix = label2 ? `${labelColor(`[${label2}]`)} ` : "";
|
|
254360
|
+
function createDevLogger() {
|
|
254059
254361
|
const print = (type, ...args) => {
|
|
254060
254362
|
const colorize = colorByType[type];
|
|
254061
|
-
console[type](
|
|
254363
|
+
console[type](...args.map((item) => {
|
|
254364
|
+
return colorize(stringify(item));
|
|
254365
|
+
}));
|
|
254062
254366
|
};
|
|
254063
254367
|
return {
|
|
254064
254368
|
log: (...args) => print("log", ...args),
|
|
@@ -255425,92 +255729,6 @@ function createCustomIntegrationRoutes(remoteProxy, logger2) {
|
|
|
255425
255729
|
return router;
|
|
255426
255730
|
}
|
|
255427
255731
|
|
|
255428
|
-
// src/cli/dev/dev-server/serve-runner.ts
|
|
255429
|
-
import { spawn as spawn3 } from "node:child_process";
|
|
255430
|
-
import process21 from "node:process";
|
|
255431
|
-
|
|
255432
|
-
class ServeRunner {
|
|
255433
|
-
command;
|
|
255434
|
-
cwd;
|
|
255435
|
-
env;
|
|
255436
|
-
logger;
|
|
255437
|
-
child;
|
|
255438
|
-
stopping = false;
|
|
255439
|
-
exitListeners = [];
|
|
255440
|
-
constructor(options8) {
|
|
255441
|
-
this.command = options8.command;
|
|
255442
|
-
this.cwd = options8.cwd;
|
|
255443
|
-
this.env = options8.env;
|
|
255444
|
-
this.logger = options8.logger;
|
|
255445
|
-
}
|
|
255446
|
-
start() {
|
|
255447
|
-
if (this.child) {
|
|
255448
|
-
return;
|
|
255449
|
-
}
|
|
255450
|
-
const child = spawn3(this.command, {
|
|
255451
|
-
cwd: this.cwd,
|
|
255452
|
-
shell: true,
|
|
255453
|
-
detached: process21.platform !== "win32",
|
|
255454
|
-
env: { ...process21.env, ...this.env },
|
|
255455
|
-
stdio: ["inherit", "pipe", "pipe"]
|
|
255456
|
-
});
|
|
255457
|
-
this.child = child;
|
|
255458
|
-
this.setupHandlers(child);
|
|
255459
|
-
}
|
|
255460
|
-
onExit(listener) {
|
|
255461
|
-
this.exitListeners.push(listener);
|
|
255462
|
-
}
|
|
255463
|
-
async stop() {
|
|
255464
|
-
const child = this.child;
|
|
255465
|
-
if (!child || child.exitCode !== null) {
|
|
255466
|
-
return;
|
|
255467
|
-
}
|
|
255468
|
-
this.stopping = true;
|
|
255469
|
-
const exited = new Promise((resolve10) => child.once("exit", () => resolve10()));
|
|
255470
|
-
if (process21.platform === "win32" && child.pid) {
|
|
255471
|
-
spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"]);
|
|
255472
|
-
} else if (child.pid) {
|
|
255473
|
-
try {
|
|
255474
|
-
process21.kill(-child.pid, "SIGTERM");
|
|
255475
|
-
} catch {
|
|
255476
|
-
child.kill();
|
|
255477
|
-
}
|
|
255478
|
-
}
|
|
255479
|
-
await exited;
|
|
255480
|
-
}
|
|
255481
|
-
setupHandlers(child) {
|
|
255482
|
-
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
255483
|
-
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
255484
|
-
child.on("error", (error48) => {
|
|
255485
|
-
this.logger.error("Frontend dev server failed to start:", error48);
|
|
255486
|
-
this.notifyExit(null);
|
|
255487
|
-
});
|
|
255488
|
-
child.on("exit", (code2) => {
|
|
255489
|
-
if (this.stopping) {
|
|
255490
|
-
return;
|
|
255491
|
-
}
|
|
255492
|
-
this.logger.error(`Frontend dev server exited with code ${code2}`);
|
|
255493
|
-
this.notifyExit(code2);
|
|
255494
|
-
});
|
|
255495
|
-
}
|
|
255496
|
-
notifyExit(code2) {
|
|
255497
|
-
for (const listener of this.exitListeners) {
|
|
255498
|
-
listener(code2);
|
|
255499
|
-
}
|
|
255500
|
-
}
|
|
255501
|
-
emitLines(data, type) {
|
|
255502
|
-
const lines = data.toString().trimEnd().split(`
|
|
255503
|
-
`);
|
|
255504
|
-
for (const line3 of lines) {
|
|
255505
|
-
if (type === "error") {
|
|
255506
|
-
this.logger.error(line3);
|
|
255507
|
-
} else {
|
|
255508
|
-
this.logger.log(line3);
|
|
255509
|
-
}
|
|
255510
|
-
}
|
|
255511
|
-
}
|
|
255512
|
-
}
|
|
255513
|
-
|
|
255514
255732
|
// src/cli/dev/dev-server/watcher.ts
|
|
255515
255733
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
255516
255734
|
import { relative as relative6 } from "node:path";
|
|
@@ -257234,7 +257452,7 @@ async function createDevServer(options8) {
|
|
|
257234
257452
|
}
|
|
257235
257453
|
next();
|
|
257236
257454
|
});
|
|
257237
|
-
const devLogger = createDevLogger(
|
|
257455
|
+
const devLogger = createDevLogger();
|
|
257238
257456
|
const functionManager = new FunctionManager(functions, devLogger, options8.denoWrapperPath);
|
|
257239
257457
|
const functionRoutes = createFunctionRouter(functionManager, devLogger);
|
|
257240
257458
|
app.use("/api/apps/:appId/functions", functionRoutes);
|
|
@@ -257332,31 +257550,14 @@ async function createDevServer(options8) {
|
|
|
257332
257550
|
}
|
|
257333
257551
|
});
|
|
257334
257552
|
await base44ConfigWatcher.start();
|
|
257335
|
-
let serveRunner;
|
|
257336
|
-
if (options8.serve && project2.site?.serveCommand) {
|
|
257337
|
-
serveRunner = new ServeRunner({
|
|
257338
|
-
command: project2.site.serveCommand,
|
|
257339
|
-
cwd: project2.root,
|
|
257340
|
-
env: {
|
|
257341
|
-
VITE_BASE44_APP_ID: options8.serve.appId,
|
|
257342
|
-
VITE_BASE44_APP_BASE_URL: baseUrl
|
|
257343
|
-
},
|
|
257344
|
-
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
257345
|
-
});
|
|
257346
|
-
}
|
|
257347
257553
|
const shutdown = async () => {
|
|
257348
257554
|
base44ConfigWatcher.close();
|
|
257349
257555
|
io6.close();
|
|
257350
257556
|
await functionManager.stopAll();
|
|
257351
|
-
await serveRunner?.stop();
|
|
257352
257557
|
server.close();
|
|
257353
257558
|
};
|
|
257354
257559
|
process.on("SIGINT", shutdown);
|
|
257355
257560
|
process.on("SIGTERM", shutdown);
|
|
257356
|
-
serveRunner?.onExit(() => {
|
|
257357
|
-
shutdown().finally(() => process.exit(1));
|
|
257358
|
-
});
|
|
257359
|
-
serveRunner?.start();
|
|
257360
257561
|
return { port, server };
|
|
257361
257562
|
}
|
|
257362
257563
|
|
|
@@ -257364,42 +257565,44 @@ async function createDevServer(options8) {
|
|
|
257364
257565
|
function localServerUrl(port) {
|
|
257365
257566
|
return `http://localhost:${port}`;
|
|
257366
257567
|
}
|
|
257367
|
-
async function
|
|
257568
|
+
async function writeEnvLocalIfMissing(projectRoot, port, log) {
|
|
257368
257569
|
const envLocalPath = join28(projectRoot, ".env.local");
|
|
257570
|
+
if (await pathExists(envLocalPath)) {
|
|
257571
|
+
return;
|
|
257572
|
+
}
|
|
257573
|
+
const { id: appId } = await initAppContext();
|
|
257369
257574
|
await writeFile(envLocalPath, `VITE_BASE44_APP_ID=${appId}
|
|
257370
257575
|
VITE_BASE44_APP_BASE_URL=${localServerUrl(port)}
|
|
257371
257576
|
`);
|
|
257372
|
-
log.info("
|
|
257577
|
+
log.info("Created .env.local with app ID and dev server URL");
|
|
257373
257578
|
}
|
|
257374
257579
|
async function devAction({ log }, options8) {
|
|
257375
257580
|
const port = options8.port ? Number(options8.port) : undefined;
|
|
257376
|
-
const serveEnabled = options8.serve !== false;
|
|
257377
257581
|
let projectRoot;
|
|
257378
|
-
const appId = serveEnabled || options8.writeEnv ? (await initAppContext()).id : undefined;
|
|
257379
257582
|
const { port: resolvedPort } = await createDevServer({
|
|
257380
257583
|
log,
|
|
257381
257584
|
port,
|
|
257585
|
+
cwd: process21.cwd(),
|
|
257382
257586
|
denoWrapperPath: getDenoWrapperPath(),
|
|
257383
|
-
serve: serveEnabled && appId ? { appId } : undefined,
|
|
257384
257587
|
loadResources: async () => {
|
|
257385
257588
|
const { functions, entities, project: project2 } = await readProjectConfig();
|
|
257386
257589
|
projectRoot = project2.root;
|
|
257387
257590
|
return { functions, entities, project: project2 };
|
|
257388
257591
|
}
|
|
257389
257592
|
});
|
|
257390
|
-
if (
|
|
257391
|
-
await
|
|
257593
|
+
if (projectRoot) {
|
|
257594
|
+
await writeEnvLocalIfMissing(projectRoot, resolvedPort, log);
|
|
257392
257595
|
}
|
|
257393
257596
|
return {
|
|
257394
257597
|
outroMessage: `Dev server is available at ${theme.colors.links(localServerUrl(resolvedPort))}`
|
|
257395
257598
|
};
|
|
257396
257599
|
}
|
|
257397
257600
|
function getDevCommand() {
|
|
257398
|
-
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").
|
|
257601
|
+
return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").action(devAction);
|
|
257399
257602
|
}
|
|
257400
257603
|
|
|
257401
257604
|
// src/core/exec/run-script.ts
|
|
257402
|
-
import { spawn as
|
|
257605
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
257403
257606
|
import { copyFileSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
257404
257607
|
async function runScript(options8) {
|
|
257405
257608
|
const { appId, code: code2 } = options8;
|
|
@@ -257418,7 +257621,7 @@ async function runScript(options8) {
|
|
|
257418
257621
|
copyFileSync(getExecWrapperPath(), tempWrapper.path);
|
|
257419
257622
|
try {
|
|
257420
257623
|
const exitCode = await new Promise((resolvePromise) => {
|
|
257421
|
-
const child =
|
|
257624
|
+
const child = spawn3("deno", ["run", "--allow-all", "--node-modules-dir=auto", tempWrapper.path], {
|
|
257422
257625
|
env: {
|
|
257423
257626
|
...process.env,
|
|
257424
257627
|
SCRIPT_PATH: scriptPath,
|
|
@@ -257610,6 +257813,7 @@ function createProgram(context) {
|
|
|
257610
257813
|
program2.addCommand(getConnectorsCommand());
|
|
257611
257814
|
program2.addCommand(getFunctionsCommand());
|
|
257612
257815
|
program2.addCommand(getSecretsCommand());
|
|
257816
|
+
program2.addCommand(getSandboxCommand());
|
|
257613
257817
|
program2.addCommand(getAuthCommand());
|
|
257614
257818
|
program2.addCommand(getSiteCommand());
|
|
257615
257819
|
program2.addCommand(getTypesCommand());
|
|
@@ -261861,4 +262065,4 @@ export {
|
|
|
261861
262065
|
CLIExitError
|
|
261862
262066
|
};
|
|
261863
262067
|
|
|
261864
|
-
//# debugId=
|
|
262068
|
+
//# debugId=61B9F8E330C194E064756E2164756E21
|