@base44-preview/cli 0.1.16-pr.635.f70a612 → 0.1.17-pr.626.a210a49
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 +940 -532
- package/dist/cli/index.js.map +36 -28
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -31177,7 +31177,7 @@ function cleanDoc(doc) {
|
|
|
31177
31177
|
return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
|
|
31178
31178
|
}
|
|
31179
31179
|
function replaceEndOfLine(doc, replacement = literalline) {
|
|
31180
|
-
return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ?
|
|
31180
|
+
return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join30(replacement, currentDoc.split(`
|
|
31181
31181
|
`)) : currentDoc);
|
|
31182
31182
|
}
|
|
31183
31183
|
function canBreakFn(doc) {
|
|
@@ -31257,7 +31257,7 @@ function indentIfBreak(contents, options) {
|
|
|
31257
31257
|
negate: options.negate
|
|
31258
31258
|
};
|
|
31259
31259
|
}
|
|
31260
|
-
function
|
|
31260
|
+
function join30(separator, docs) {
|
|
31261
31261
|
assertDoc(separator);
|
|
31262
31262
|
assertDocArray(docs);
|
|
31263
31263
|
const parts = [];
|
|
@@ -31968,7 +31968,7 @@ var init_doc = __esm(() => {
|
|
|
31968
31968
|
MODE_FLAT = Symbol("MODE_FLAT");
|
|
31969
31969
|
DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
|
|
31970
31970
|
builders = {
|
|
31971
|
-
join:
|
|
31971
|
+
join: join30,
|
|
31972
31972
|
line,
|
|
31973
31973
|
softline,
|
|
31974
31974
|
hardline,
|
|
@@ -119090,7 +119090,7 @@ import path52 from "path";
|
|
|
119090
119090
|
import * as path42 from "path";
|
|
119091
119091
|
import * as fs26 from "fs/promises";
|
|
119092
119092
|
import * as path22 from "path";
|
|
119093
|
-
import
|
|
119093
|
+
import process22 from "process";
|
|
119094
119094
|
import * as path32 from "path";
|
|
119095
119095
|
import process32 from "process";
|
|
119096
119096
|
import path92 from "path";
|
|
@@ -119622,7 +119622,7 @@ function partition2(array2, predicate) {
|
|
|
119622
119622
|
return result;
|
|
119623
119623
|
}
|
|
119624
119624
|
async function findInDirectory(nameOrNames, { typeCheck, cwd, allowSymlinks = true, filter: filter2 }) {
|
|
119625
|
-
const directory = toAbsolutePath(cwd) ??
|
|
119625
|
+
const directory = toAbsolutePath(cwd) ?? process22.cwd();
|
|
119626
119626
|
const names = Array.isArray(nameOrNames) ? nameOrNames : [nameOrNames];
|
|
119627
119627
|
for (const name of names) {
|
|
119628
119628
|
const fileOrDirectory = path22.join(directory, name);
|
|
@@ -146002,10 +146002,10 @@ __export(exports_supports_color, {
|
|
|
146002
146002
|
createSupportsColor: () => createSupportsColor2,
|
|
146003
146003
|
default: () => supports_color_default2
|
|
146004
146004
|
});
|
|
146005
|
-
import
|
|
146005
|
+
import process21 from "node:process";
|
|
146006
146006
|
import os9 from "node:os";
|
|
146007
146007
|
import tty4 from "node:tty";
|
|
146008
|
-
function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args :
|
|
146008
|
+
function hasFlag2(flag, argv = globalThis.Deno ? globalThis.Deno.args : process21.argv) {
|
|
146009
146009
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
146010
146010
|
const position = argv.indexOf(prefix + flag);
|
|
146011
146011
|
const terminatorPosition = argv.indexOf("--");
|
|
@@ -146068,7 +146068,7 @@ function _supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
146068
146068
|
if (env3.TERM === "dumb") {
|
|
146069
146069
|
return min;
|
|
146070
146070
|
}
|
|
146071
|
-
if (
|
|
146071
|
+
if (process21.platform === "win32") {
|
|
146072
146072
|
const osRelease = os9.release().split(".");
|
|
146073
146073
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
146074
146074
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
@@ -146130,7 +146130,7 @@ function createSupportsColor2(stream, options = {}) {
|
|
|
146130
146130
|
}
|
|
146131
146131
|
var env3, flagForceColor2, supportsColor2, supports_color_default2;
|
|
146132
146132
|
var init_supports_color = __esm(() => {
|
|
146133
|
-
({ env: env3 } =
|
|
146133
|
+
({ env: env3 } = process21);
|
|
146134
146134
|
if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) {
|
|
146135
146135
|
flagForceColor2 = 0;
|
|
146136
146136
|
} else if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) {
|
|
@@ -228470,6 +228470,17 @@ class DependencyNotFoundError extends UserError {
|
|
|
228470
228470
|
});
|
|
228471
228471
|
}
|
|
228472
228472
|
}
|
|
228473
|
+
var MAX_RESPONSE_TEXT_CHARS = 500;
|
|
228474
|
+
async function readResponseText(response) {
|
|
228475
|
+
try {
|
|
228476
|
+
const text = (await response.clone().text()).trim();
|
|
228477
|
+
if (!text)
|
|
228478
|
+
return;
|
|
228479
|
+
return text.length > MAX_RESPONSE_TEXT_CHARS ? `${text.slice(0, MAX_RESPONSE_TEXT_CHARS)}…` : text;
|
|
228480
|
+
} catch {
|
|
228481
|
+
return;
|
|
228482
|
+
}
|
|
228483
|
+
}
|
|
228473
228484
|
|
|
228474
228485
|
class ApiError extends SystemError {
|
|
228475
228486
|
code = "API_ERROR";
|
|
@@ -228505,7 +228516,9 @@ class ApiError extends SystemError {
|
|
|
228505
228516
|
details = parseErrorDetails(parsedData.extra_data);
|
|
228506
228517
|
}
|
|
228507
228518
|
} catch {
|
|
228508
|
-
|
|
228519
|
+
const body = await readResponseText(error.response);
|
|
228520
|
+
responseBody = body;
|
|
228521
|
+
message = body ? `${error.message} — ${body}` : `${error.message} — empty body, content-type ${error.response.headers.get("content-type") ?? "absent"}`;
|
|
228509
228522
|
}
|
|
228510
228523
|
const statusCode = ApiError.normalizeStatusCode(error.response.status, responseBody);
|
|
228511
228524
|
const requestBody = error.options.context?.__requestBody;
|
|
@@ -228657,6 +228670,20 @@ function isCLIError(error) {
|
|
|
228657
228670
|
function isUserError(error) {
|
|
228658
228671
|
return error instanceof UserError;
|
|
228659
228672
|
}
|
|
228673
|
+
var STEP = Symbol.for("base44.commandStep");
|
|
228674
|
+
async function tagStep(step, run) {
|
|
228675
|
+
try {
|
|
228676
|
+
return await run();
|
|
228677
|
+
} catch (error) {
|
|
228678
|
+
if (error !== null && typeof error === "object" && !(STEP in error) && Object.isExtensible(error)) {
|
|
228679
|
+
Object.defineProperty(error, STEP, { value: step, enumerable: false });
|
|
228680
|
+
}
|
|
228681
|
+
throw error;
|
|
228682
|
+
}
|
|
228683
|
+
}
|
|
228684
|
+
function stepOf(error) {
|
|
228685
|
+
return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
|
|
228686
|
+
}
|
|
228660
228687
|
|
|
228661
228688
|
// src/core/utils/fs.ts
|
|
228662
228689
|
async function pathExists(path) {
|
|
@@ -228783,7 +228810,7 @@ function normalizeBase44Env() {
|
|
|
228783
228810
|
loadProjectEnvFiles();
|
|
228784
228811
|
|
|
228785
228812
|
// src/cli/index.ts
|
|
228786
|
-
import { dirname as
|
|
228813
|
+
import { dirname as dirname29, join as join39 } from "node:path";
|
|
228787
228814
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
228788
228815
|
|
|
228789
228816
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -230705,11 +230732,10 @@ var TemplatesConfigSchema = object({
|
|
|
230705
230732
|
templates: array(TemplateSchema)
|
|
230706
230733
|
});
|
|
230707
230734
|
var SiteConfigSchema = object({
|
|
230708
|
-
buildCommand: string2().
|
|
230735
|
+
buildCommand: string2().default("npm run build"),
|
|
230709
230736
|
serveCommand: string2().optional(),
|
|
230710
|
-
outputDirectory: string2().optional()
|
|
230711
|
-
installCommand: string2().
|
|
230712
|
-
devHostFlag: string2().optional().default("--host")
|
|
230737
|
+
outputDirectory: string2().optional(),
|
|
230738
|
+
installCommand: string2().default("npm install")
|
|
230713
230739
|
});
|
|
230714
230740
|
var PluginMetadataSchema = object({
|
|
230715
230741
|
namespace: string2().min(1, "Plugin namespace cannot be empty").regex(/^[a-zA-Z0-9_-]+$/, "Plugin namespace can only contain letters, numbers, underscores, and dashes")
|
|
@@ -236546,10 +236572,12 @@ var CreateDeploymentResponseSchema = object({
|
|
|
236546
236572
|
url: string2()
|
|
236547
236573
|
}))
|
|
236548
236574
|
})
|
|
236549
|
-
]).nullable().optional()
|
|
236575
|
+
]).nullable().optional(),
|
|
236576
|
+
index_html_staged: boolean2().optional().default(false)
|
|
236550
236577
|
}).transform((data) => ({
|
|
236551
236578
|
deploymentId: data.deployment_id,
|
|
236552
236579
|
sessionId: data.session_id,
|
|
236580
|
+
indexHtmlStaged: data.index_html_staged,
|
|
236553
236581
|
assetUploads: data.asset_uploads == null ? null : data.asset_uploads.type === "cf" ? data.asset_uploads : {
|
|
236554
236582
|
type: "s3",
|
|
236555
236583
|
uploads: data.asset_uploads.uploads.map((upload) => ({
|
|
@@ -239237,7 +239265,7 @@ import { join as join13 } from "node:path";
|
|
|
239237
239265
|
// package.json
|
|
239238
239266
|
var package_default = {
|
|
239239
239267
|
name: "base44",
|
|
239240
|
-
version: "0.1.
|
|
239268
|
+
version: "0.1.17",
|
|
239241
239269
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
239242
239270
|
type: "module",
|
|
239243
239271
|
bin: {
|
|
@@ -239512,9 +239540,9 @@ async function createDeployment(request) {
|
|
|
239512
239540
|
}
|
|
239513
239541
|
async function finalizeDeployment(deploymentId, sessionId, payload) {
|
|
239514
239542
|
const formData = new FormData;
|
|
239515
|
-
if ("
|
|
239543
|
+
if (payload.kind === "static-inline") {
|
|
239516
239544
|
formData.append("index.html", new File([payload.indexHtml], "index.html", { type: "text/html" }));
|
|
239517
|
-
} else {
|
|
239545
|
+
} else if (payload.kind === "worker") {
|
|
239518
239546
|
formData.append("payload", JSON.stringify({ completion_jwt: payload.completionJwt }));
|
|
239519
239547
|
for (const module of payload.modules) {
|
|
239520
239548
|
const content = await readFile(module.absolutePath);
|
|
@@ -239591,91 +239619,8 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
239591
239619
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
239592
239620
|
import { join as join18 } from "node:path";
|
|
239593
239621
|
|
|
239594
|
-
// src/core/site/manifest.ts
|
|
239595
|
-
import { createHash } from "node:crypto";
|
|
239596
|
-
import { createReadStream } from "node:fs";
|
|
239597
|
-
import { stat } from "node:fs/promises";
|
|
239598
|
-
import { basename as basename5, extname, join as join16 } from "node:path";
|
|
239599
|
-
var MAX_ASSET_COUNT = 1e5;
|
|
239600
|
-
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
239601
|
-
var ALWAYS_IGNORED = new Set([
|
|
239602
|
-
ASSETS_IGNORE_FILE,
|
|
239603
|
-
"wrangler.json",
|
|
239604
|
-
".dev.vars"
|
|
239605
|
-
]);
|
|
239606
|
-
var MIME_TYPES = {
|
|
239607
|
-
".html": "text/html",
|
|
239608
|
-
".htm": "text/html",
|
|
239609
|
-
".css": "text/css",
|
|
239610
|
-
".js": "text/javascript",
|
|
239611
|
-
".mjs": "text/javascript",
|
|
239612
|
-
".json": "application/json",
|
|
239613
|
-
".map": "application/json",
|
|
239614
|
-
".txt": "text/plain",
|
|
239615
|
-
".xml": "application/xml",
|
|
239616
|
-
".svg": "image/svg+xml",
|
|
239617
|
-
".png": "image/png",
|
|
239618
|
-
".jpg": "image/jpeg",
|
|
239619
|
-
".jpeg": "image/jpeg",
|
|
239620
|
-
".gif": "image/gif",
|
|
239621
|
-
".webp": "image/webp",
|
|
239622
|
-
".avif": "image/avif",
|
|
239623
|
-
".ico": "image/x-icon",
|
|
239624
|
-
".woff": "font/woff",
|
|
239625
|
-
".woff2": "font/woff2",
|
|
239626
|
-
".ttf": "font/ttf",
|
|
239627
|
-
".otf": "font/otf",
|
|
239628
|
-
".eot": "application/vnd.ms-fontobject",
|
|
239629
|
-
".mp3": "audio/mpeg",
|
|
239630
|
-
".mp4": "video/mp4",
|
|
239631
|
-
".webm": "video/webm",
|
|
239632
|
-
".pdf": "application/pdf",
|
|
239633
|
-
".wasm": "application/wasm",
|
|
239634
|
-
".webmanifest": "application/manifest+json"
|
|
239635
|
-
};
|
|
239636
|
-
function getAssetContentType(filePath) {
|
|
239637
|
-
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
239638
|
-
}
|
|
239639
|
-
async function hashAssetFile(appId, absolutePath) {
|
|
239640
|
-
const hash = createHash("sha256").update(Buffer.from(appId, "utf8"));
|
|
239641
|
-
for await (const chunk of createReadStream(absolutePath)) {
|
|
239642
|
-
hash.update(chunk);
|
|
239643
|
-
}
|
|
239644
|
-
return hash.digest("hex").slice(0, 32);
|
|
239645
|
-
}
|
|
239646
|
-
async function buildAssetManifest(assetsDir, appId) {
|
|
239647
|
-
const manifest = {};
|
|
239648
|
-
const filesByHash = new Map;
|
|
239649
|
-
const found = await globby("**/*", {
|
|
239650
|
-
cwd: assetsDir,
|
|
239651
|
-
dot: true,
|
|
239652
|
-
onlyFiles: true,
|
|
239653
|
-
followSymbolicLinks: false,
|
|
239654
|
-
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
239655
|
-
});
|
|
239656
|
-
const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
|
|
239657
|
-
if (relativeFilePaths.length > MAX_ASSET_COUNT) {
|
|
239658
|
-
throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
239659
|
-
}
|
|
239660
|
-
for (const relativePath of relativeFilePaths.sort()) {
|
|
239661
|
-
const absolutePath = join16(assetsDir, ...relativePath.split("/"));
|
|
239662
|
-
const { size } = await stat(absolutePath);
|
|
239663
|
-
const hash = await hashAssetFile(appId, absolutePath);
|
|
239664
|
-
manifest[`/${relativePath}`] = { hash, size };
|
|
239665
|
-
if (!filesByHash.has(hash)) {
|
|
239666
|
-
filesByHash.set(hash, {
|
|
239667
|
-
absolutePath,
|
|
239668
|
-
hash,
|
|
239669
|
-
size,
|
|
239670
|
-
contentType: getAssetContentType(absolutePath)
|
|
239671
|
-
});
|
|
239672
|
-
}
|
|
239673
|
-
}
|
|
239674
|
-
return { manifest, filesByHash };
|
|
239675
|
-
}
|
|
239676
|
-
|
|
239677
239622
|
// src/core/site/modules.ts
|
|
239678
|
-
import { stat
|
|
239623
|
+
import { stat } from "node:fs/promises";
|
|
239679
239624
|
import { relative as relative5, resolve as resolve3, sep } from "node:path";
|
|
239680
239625
|
var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
|
|
239681
239626
|
var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
|
|
@@ -239750,7 +239695,7 @@ async function collectModules(config) {
|
|
|
239750
239695
|
const modules = [...modulesByName.values()];
|
|
239751
239696
|
let totalBytes = 0;
|
|
239752
239697
|
for (const module of modules) {
|
|
239753
|
-
module.size = (await
|
|
239698
|
+
module.size = (await stat(module.absolutePath)).size;
|
|
239754
239699
|
totalBytes += module.size;
|
|
239755
239700
|
}
|
|
239756
239701
|
if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
|
|
@@ -239769,8 +239714,104 @@ function addSourcemap(modulesByName, configDir, name) {
|
|
|
239769
239714
|
});
|
|
239770
239715
|
}
|
|
239771
239716
|
|
|
239772
|
-
// src/core/site/
|
|
239773
|
-
import {
|
|
239717
|
+
// src/core/site/wrangler-config.ts
|
|
239718
|
+
import { dirname as dirname12, join as join16, resolve as resolve4 } from "node:path";
|
|
239719
|
+
var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
|
|
239720
|
+
var RedirectConfigSchema = looseObject({
|
|
239721
|
+
configPath: string2().min(1)
|
|
239722
|
+
});
|
|
239723
|
+
var WranglerConfigSchema = looseObject({
|
|
239724
|
+
main: string2().min(1, "wrangler config is missing a 'main' entry module"),
|
|
239725
|
+
no_bundle: boolean2().optional(),
|
|
239726
|
+
rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
|
|
239727
|
+
assets: looseObject({
|
|
239728
|
+
directory: string2().optional(),
|
|
239729
|
+
html_handling: string2().optional(),
|
|
239730
|
+
not_found_handling: string2().optional(),
|
|
239731
|
+
run_worker_first: union([boolean2(), array(string2())]).optional(),
|
|
239732
|
+
headers: string2().optional(),
|
|
239733
|
+
redirects: string2().optional()
|
|
239734
|
+
}).optional(),
|
|
239735
|
+
compatibility_date: string2().optional(),
|
|
239736
|
+
compatibility_flags: array(string2()).optional(),
|
|
239737
|
+
vars: record(string2(), unknown()).optional(),
|
|
239738
|
+
upload_source_maps: boolean2().optional()
|
|
239739
|
+
});
|
|
239740
|
+
async function detectFullStackArtifact(projectRoot) {
|
|
239741
|
+
const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
|
|
239742
|
+
return await pathExists(redirectPath) ? redirectPath : null;
|
|
239743
|
+
}
|
|
239744
|
+
async function resolveWranglerConfig(redirectPath) {
|
|
239745
|
+
const configPath = await resolveRedirectedConfigPath(redirectPath);
|
|
239746
|
+
const parsed = await readJsonFile(configPath);
|
|
239747
|
+
const result = WranglerConfigSchema.safeParse(parsed);
|
|
239748
|
+
if (!result.success) {
|
|
239749
|
+
throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
|
|
239750
|
+
}
|
|
239751
|
+
const config = result.data;
|
|
239752
|
+
if (config.no_bundle !== true) {
|
|
239753
|
+
throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
|
|
239754
|
+
}
|
|
239755
|
+
const configDir = dirname12(configPath);
|
|
239756
|
+
const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
|
|
239757
|
+
return {
|
|
239758
|
+
configPath,
|
|
239759
|
+
configDir,
|
|
239760
|
+
main: config.main,
|
|
239761
|
+
assetsDirectory,
|
|
239762
|
+
assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
|
|
239763
|
+
compatibilityDate: config.compatibility_date ?? null,
|
|
239764
|
+
compatibilityFlags: config.compatibility_flags ?? [],
|
|
239765
|
+
rules: (config.rules ?? []).map((rule) => ({
|
|
239766
|
+
type: rule.type,
|
|
239767
|
+
globs: rule.globs
|
|
239768
|
+
})),
|
|
239769
|
+
uploadSourceMaps: config.upload_source_maps ?? false
|
|
239770
|
+
};
|
|
239771
|
+
}
|
|
239772
|
+
async function resolveRedirectedConfigPath(redirectPath) {
|
|
239773
|
+
const parsed = await readJsonFile(redirectPath);
|
|
239774
|
+
const result = RedirectConfigSchema.safeParse(parsed);
|
|
239775
|
+
if (!result.success) {
|
|
239776
|
+
throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
|
|
239777
|
+
}
|
|
239778
|
+
const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
|
|
239779
|
+
if (!await pathExists(configPath)) {
|
|
239780
|
+
throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
|
|
239781
|
+
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
239782
|
+
});
|
|
239783
|
+
}
|
|
239784
|
+
return configPath;
|
|
239785
|
+
}
|
|
239786
|
+
function toResolvedAssetsConfig(assets) {
|
|
239787
|
+
return {
|
|
239788
|
+
htmlHandling: assets.html_handling,
|
|
239789
|
+
notFoundHandling: assets.not_found_handling,
|
|
239790
|
+
runWorkerFirst: assets.run_worker_first,
|
|
239791
|
+
headers: assets.headers,
|
|
239792
|
+
redirects: assets.redirects
|
|
239793
|
+
};
|
|
239794
|
+
}
|
|
239795
|
+
|
|
239796
|
+
// src/core/site/full-stack.ts
|
|
239797
|
+
async function resolveFullStackBuild(projectRoot) {
|
|
239798
|
+
const redirectPath = await detectFullStackArtifact(projectRoot);
|
|
239799
|
+
if (!redirectPath) {
|
|
239800
|
+
return null;
|
|
239801
|
+
}
|
|
239802
|
+
const config = await resolveWranglerConfig(redirectPath);
|
|
239803
|
+
return {
|
|
239804
|
+
config,
|
|
239805
|
+
modules: await collectModules(config),
|
|
239806
|
+
assetsDir: config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null
|
|
239807
|
+
};
|
|
239808
|
+
}
|
|
239809
|
+
|
|
239810
|
+
// src/core/site/manifest.ts
|
|
239811
|
+
import { createHash } from "node:crypto";
|
|
239812
|
+
import { createReadStream } from "node:fs";
|
|
239813
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
239814
|
+
import { basename as basename5, extname, join as join17 } from "node:path";
|
|
239774
239815
|
|
|
239775
239816
|
// ../../node_modules/p-map/index.js
|
|
239776
239817
|
async function pMap(iterable, mapper, {
|
|
@@ -239896,7 +239937,99 @@ async function pMap(iterable, mapper, {
|
|
|
239896
239937
|
}
|
|
239897
239938
|
var pMapSkip = Symbol("skip");
|
|
239898
239939
|
|
|
239940
|
+
// src/core/site/manifest.ts
|
|
239941
|
+
var MAX_ASSET_COUNT = 1e5;
|
|
239942
|
+
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
239943
|
+
var ALWAYS_IGNORED = new Set([
|
|
239944
|
+
ASSETS_IGNORE_FILE,
|
|
239945
|
+
"wrangler.json",
|
|
239946
|
+
".dev.vars"
|
|
239947
|
+
]);
|
|
239948
|
+
var MIME_TYPES = {
|
|
239949
|
+
".html": "text/html",
|
|
239950
|
+
".htm": "text/html",
|
|
239951
|
+
".css": "text/css",
|
|
239952
|
+
".js": "text/javascript",
|
|
239953
|
+
".mjs": "text/javascript",
|
|
239954
|
+
".json": "application/json",
|
|
239955
|
+
".map": "application/json",
|
|
239956
|
+
".txt": "text/plain",
|
|
239957
|
+
".xml": "application/xml",
|
|
239958
|
+
".svg": "image/svg+xml",
|
|
239959
|
+
".png": "image/png",
|
|
239960
|
+
".jpg": "image/jpeg",
|
|
239961
|
+
".jpeg": "image/jpeg",
|
|
239962
|
+
".gif": "image/gif",
|
|
239963
|
+
".webp": "image/webp",
|
|
239964
|
+
".avif": "image/avif",
|
|
239965
|
+
".ico": "image/x-icon",
|
|
239966
|
+
".woff": "font/woff",
|
|
239967
|
+
".woff2": "font/woff2",
|
|
239968
|
+
".ttf": "font/ttf",
|
|
239969
|
+
".otf": "font/otf",
|
|
239970
|
+
".eot": "application/vnd.ms-fontobject",
|
|
239971
|
+
".mp3": "audio/mpeg",
|
|
239972
|
+
".mp4": "video/mp4",
|
|
239973
|
+
".webm": "video/webm",
|
|
239974
|
+
".pdf": "application/pdf",
|
|
239975
|
+
".wasm": "application/wasm",
|
|
239976
|
+
".webmanifest": "application/manifest+json"
|
|
239977
|
+
};
|
|
239978
|
+
function getAssetContentType(filePath) {
|
|
239979
|
+
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
239980
|
+
}
|
|
239981
|
+
async function walkBuildOutput(outputDir) {
|
|
239982
|
+
const found = await globby("**/*", {
|
|
239983
|
+
cwd: outputDir,
|
|
239984
|
+
dot: true,
|
|
239985
|
+
onlyFiles: true,
|
|
239986
|
+
followSymbolicLinks: false,
|
|
239987
|
+
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
239988
|
+
});
|
|
239989
|
+
return found.filter((path) => !ALWAYS_IGNORED.has(basename5(path))).sort();
|
|
239990
|
+
}
|
|
239991
|
+
var STAT_CONCURRENCY = 32;
|
|
239992
|
+
async function describeBuildOutput(outputDir) {
|
|
239993
|
+
const relativePaths = await walkBuildOutput(outputDir);
|
|
239994
|
+
return await pMap(relativePaths, async (path) => {
|
|
239995
|
+
const absolutePath = join17(outputDir, ...path.split("/"));
|
|
239996
|
+
return { path, absolutePath, size: (await stat2(absolutePath)).size };
|
|
239997
|
+
}, { concurrency: STAT_CONCURRENCY });
|
|
239998
|
+
}
|
|
239999
|
+
async function hashFileInto(hash, absolutePath) {
|
|
240000
|
+
for await (const chunk of createReadStream(absolutePath)) {
|
|
240001
|
+
hash.update(chunk);
|
|
240002
|
+
}
|
|
240003
|
+
return hash;
|
|
240004
|
+
}
|
|
240005
|
+
async function hashAssetFile(appId, absolutePath) {
|
|
240006
|
+
const hash = await hashFileInto(createHash("sha256").update(Buffer.from(appId, "utf8")), absolutePath);
|
|
240007
|
+
return hash.digest("hex").slice(0, 32);
|
|
240008
|
+
}
|
|
240009
|
+
async function buildAssetManifest(assetsDir, appId) {
|
|
240010
|
+
const manifest = {};
|
|
240011
|
+
const filesByHash = new Map;
|
|
240012
|
+
const files = await describeBuildOutput(assetsDir);
|
|
240013
|
+
if (files.length > MAX_ASSET_COUNT) {
|
|
240014
|
+
throw new InvalidInputError(`Too many static assets: found ${files.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
240015
|
+
}
|
|
240016
|
+
for (const { path: relativePath, absolutePath, size } of files) {
|
|
240017
|
+
const hash = await hashAssetFile(appId, absolutePath);
|
|
240018
|
+
manifest[`/${relativePath}`] = { hash, size };
|
|
240019
|
+
if (!filesByHash.has(hash)) {
|
|
240020
|
+
filesByHash.set(hash, {
|
|
240021
|
+
absolutePath,
|
|
240022
|
+
hash,
|
|
240023
|
+
size,
|
|
240024
|
+
contentType: getAssetContentType(absolutePath)
|
|
240025
|
+
});
|
|
240026
|
+
}
|
|
240027
|
+
}
|
|
240028
|
+
return { manifest, filesByHash };
|
|
240029
|
+
}
|
|
240030
|
+
|
|
239899
240031
|
// src/core/site/upload.ts
|
|
240032
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
239900
240033
|
var DEFAULT_UPLOAD_CONCURRENCY = 3;
|
|
239901
240034
|
var MAX_UPLOAD_CONCURRENCY = 50;
|
|
239902
240035
|
var MAX_UPLOAD_ATTEMPTS = 3;
|
|
@@ -239995,11 +240128,17 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
239995
240128
|
if (!file) {
|
|
239996
240129
|
throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
|
|
239997
240130
|
}
|
|
239998
|
-
|
|
240131
|
+
await putPresigned(upload, file.absolutePath);
|
|
240132
|
+
}
|
|
240133
|
+
async function putPresigned(upload, absolutePath) {
|
|
240134
|
+
const content = await readFile2(absolutePath);
|
|
239999
240135
|
try {
|
|
240000
240136
|
await distribution_default.put(upload.url, {
|
|
240001
240137
|
body: new Uint8Array(content),
|
|
240002
|
-
headers: {
|
|
240138
|
+
headers: {
|
|
240139
|
+
"Content-Type": upload.contentType,
|
|
240140
|
+
...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
|
|
240141
|
+
},
|
|
240003
240142
|
timeout: 120000,
|
|
240004
240143
|
retry: UPLOAD_RETRY
|
|
240005
240144
|
});
|
|
@@ -240008,85 +240147,6 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
240008
240147
|
}
|
|
240009
240148
|
}
|
|
240010
240149
|
|
|
240011
|
-
// src/core/site/wrangler-config.ts
|
|
240012
|
-
import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
|
|
240013
|
-
var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
|
|
240014
|
-
var RedirectConfigSchema = looseObject({
|
|
240015
|
-
configPath: string2().min(1)
|
|
240016
|
-
});
|
|
240017
|
-
var WranglerConfigSchema = looseObject({
|
|
240018
|
-
main: string2().min(1, "wrangler config is missing a 'main' entry module"),
|
|
240019
|
-
no_bundle: boolean2().optional(),
|
|
240020
|
-
rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
|
|
240021
|
-
assets: looseObject({
|
|
240022
|
-
directory: string2().optional(),
|
|
240023
|
-
html_handling: string2().optional(),
|
|
240024
|
-
not_found_handling: string2().optional(),
|
|
240025
|
-
run_worker_first: union([boolean2(), array(string2())]).optional(),
|
|
240026
|
-
headers: string2().optional(),
|
|
240027
|
-
redirects: string2().optional()
|
|
240028
|
-
}).optional(),
|
|
240029
|
-
compatibility_date: string2().optional(),
|
|
240030
|
-
compatibility_flags: array(string2()).optional(),
|
|
240031
|
-
vars: record(string2(), unknown()).optional(),
|
|
240032
|
-
upload_source_maps: boolean2().optional()
|
|
240033
|
-
});
|
|
240034
|
-
async function detectFullStackArtifact(projectRoot) {
|
|
240035
|
-
const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
|
|
240036
|
-
return await pathExists(redirectPath) ? redirectPath : null;
|
|
240037
|
-
}
|
|
240038
|
-
async function resolveWranglerConfig(redirectPath) {
|
|
240039
|
-
const configPath = await resolveRedirectedConfigPath(redirectPath);
|
|
240040
|
-
const parsed = await readJsonFile(configPath);
|
|
240041
|
-
const result = WranglerConfigSchema.safeParse(parsed);
|
|
240042
|
-
if (!result.success) {
|
|
240043
|
-
throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
|
|
240044
|
-
}
|
|
240045
|
-
const config = result.data;
|
|
240046
|
-
if (config.no_bundle !== true) {
|
|
240047
|
-
throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
|
|
240048
|
-
}
|
|
240049
|
-
const configDir = dirname12(configPath);
|
|
240050
|
-
const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
|
|
240051
|
-
return {
|
|
240052
|
-
configPath,
|
|
240053
|
-
configDir,
|
|
240054
|
-
main: config.main,
|
|
240055
|
-
assetsDirectory,
|
|
240056
|
-
assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
|
|
240057
|
-
compatibilityDate: config.compatibility_date ?? null,
|
|
240058
|
-
compatibilityFlags: config.compatibility_flags ?? [],
|
|
240059
|
-
rules: (config.rules ?? []).map((rule) => ({
|
|
240060
|
-
type: rule.type,
|
|
240061
|
-
globs: rule.globs
|
|
240062
|
-
})),
|
|
240063
|
-
uploadSourceMaps: config.upload_source_maps ?? false
|
|
240064
|
-
};
|
|
240065
|
-
}
|
|
240066
|
-
async function resolveRedirectedConfigPath(redirectPath) {
|
|
240067
|
-
const parsed = await readJsonFile(redirectPath);
|
|
240068
|
-
const result = RedirectConfigSchema.safeParse(parsed);
|
|
240069
|
-
if (!result.success) {
|
|
240070
|
-
throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
|
|
240071
|
-
}
|
|
240072
|
-
const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
|
|
240073
|
-
if (!await pathExists(configPath)) {
|
|
240074
|
-
throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
|
|
240075
|
-
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
240076
|
-
});
|
|
240077
|
-
}
|
|
240078
|
-
return configPath;
|
|
240079
|
-
}
|
|
240080
|
-
function toResolvedAssetsConfig(assets) {
|
|
240081
|
-
return {
|
|
240082
|
-
htmlHandling: assets.html_handling,
|
|
240083
|
-
notFoundHandling: assets.not_found_handling,
|
|
240084
|
-
runWorkerFirst: assets.run_worker_first,
|
|
240085
|
-
headers: assets.headers,
|
|
240086
|
-
redirects: assets.redirects
|
|
240087
|
-
};
|
|
240088
|
-
}
|
|
240089
|
-
|
|
240090
240150
|
// src/core/site/deployment.ts
|
|
240091
240151
|
var NO_ASSETS = { manifest: {}, filesByHash: new Map };
|
|
240092
240152
|
var DEPLOYMENTS_API_ENV = "BASE44_DEPLOYMENTS_API";
|
|
@@ -240099,26 +240159,28 @@ async function deployToDeployments(options) {
|
|
|
240099
240159
|
const worker = await resolveWorkerBuild(projectRoot, progress);
|
|
240100
240160
|
const assetsDir = worker ? worker.assetsDir : outputDir;
|
|
240101
240161
|
const assets = assetsDir ? await buildAssetManifest(assetsDir, getAppContext().id) : NO_ASSETS;
|
|
240102
|
-
|
|
240162
|
+
if (!worker) {
|
|
240163
|
+
requireStaticEntryPoint(assetsDir, assets);
|
|
240164
|
+
}
|
|
240103
240165
|
const created = await createDeployment({
|
|
240104
240166
|
git_hash: gitHash,
|
|
240105
240167
|
config: worker?.config,
|
|
240106
240168
|
asset_manifest: assets.manifest
|
|
240107
240169
|
});
|
|
240108
240170
|
const completionJwt = await uploadDeploymentAssets(created.assetUploads, assets, { concurrency, progress });
|
|
240109
|
-
|
|
240171
|
+
const completion = worker ? { kind: "worker", modules: worker.modules, completionJwt } : await resolveStaticCompletion(assetsDir, assets, created.indexHtmlStaged);
|
|
240172
|
+
if (completion.kind === "worker") {
|
|
240110
240173
|
progress?.onWorker?.({ moduleCount: completion.modules.length });
|
|
240111
240174
|
}
|
|
240112
|
-
const finalized = await finalizeDeployment(created.deploymentId, created.sessionId,
|
|
240175
|
+
const finalized = await finalizeDeployment(created.deploymentId, created.sessionId, completion);
|
|
240113
240176
|
return { deploymentId: finalized.deploymentId, gitHash };
|
|
240114
240177
|
}
|
|
240115
240178
|
async function resolveWorkerBuild(projectRoot, progress) {
|
|
240116
|
-
const
|
|
240117
|
-
if (!
|
|
240179
|
+
const built = await resolveFullStackBuild(projectRoot);
|
|
240180
|
+
if (!built) {
|
|
240118
240181
|
return null;
|
|
240119
240182
|
}
|
|
240120
|
-
const config =
|
|
240121
|
-
const assetsDir = config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null;
|
|
240183
|
+
const { config, modules, assetsDir } = built;
|
|
240122
240184
|
return {
|
|
240123
240185
|
config: {
|
|
240124
240186
|
main: config.main,
|
|
@@ -240126,15 +240188,24 @@ async function resolveWorkerBuild(projectRoot, progress) {
|
|
|
240126
240188
|
compatibility_flags: config.compatibilityFlags,
|
|
240127
240189
|
assets: buildAssetsConfig(config.assetsConfig, progress)
|
|
240128
240190
|
},
|
|
240129
|
-
modules
|
|
240191
|
+
modules,
|
|
240130
240192
|
assetsDir
|
|
240131
240193
|
};
|
|
240132
240194
|
}
|
|
240133
|
-
|
|
240195
|
+
function requireStaticEntryPoint(assetsDir, assets) {
|
|
240134
240196
|
if (!assetsDir || !assets.manifest["/index.html"]) {
|
|
240135
240197
|
throw new InvalidInputError(`No index.html found in "${assetsDir ?? "the site output directory"}" — a static site needs one at the output directory root.`);
|
|
240136
240198
|
}
|
|
240137
|
-
return
|
|
240199
|
+
return assetsDir;
|
|
240200
|
+
}
|
|
240201
|
+
async function resolveStaticCompletion(assetsDir, assets, indexHtmlStaged) {
|
|
240202
|
+
if (indexHtmlStaged)
|
|
240203
|
+
return { kind: "static-staged" };
|
|
240204
|
+
const dir = requireStaticEntryPoint(assetsDir, assets);
|
|
240205
|
+
return {
|
|
240206
|
+
kind: "static-inline",
|
|
240207
|
+
indexHtml: new Uint8Array(await readFile3(join18(dir, "index.html")))
|
|
240208
|
+
};
|
|
240138
240209
|
}
|
|
240139
240210
|
function buildAssetsConfig(assetsConfig, progress) {
|
|
240140
240211
|
if (!assetsConfig)
|
|
@@ -246670,6 +246741,13 @@ async function resolveGitHash(projectRoot, explicit) {
|
|
|
246670
246741
|
}
|
|
246671
246742
|
return hash;
|
|
246672
246743
|
}
|
|
246744
|
+
async function resolveProvenanceCommit(projectRoot, explicit) {
|
|
246745
|
+
if (explicit) {
|
|
246746
|
+
return await resolveGitHash(projectRoot, explicit);
|
|
246747
|
+
}
|
|
246748
|
+
const hash = await gitHead(projectRoot);
|
|
246749
|
+
return hash && isGitCommitHash(hash) ? hash : undefined;
|
|
246750
|
+
}
|
|
246673
246751
|
async function gitHead(projectRoot) {
|
|
246674
246752
|
try {
|
|
246675
246753
|
const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
|
|
@@ -246680,22 +246758,6 @@ async function gitHead(projectRoot) {
|
|
|
246680
246758
|
return null;
|
|
246681
246759
|
}
|
|
246682
246760
|
}
|
|
246683
|
-
// src/core/site/serve-command.ts
|
|
246684
|
-
var DEFAULT_SERVE_COMMAND = "npm run dev";
|
|
246685
|
-
var NPM_RUN_COMMAND = /^npm(\s+--prefix\s+\S+)?\s+run\s+\S+$/;
|
|
246686
|
-
function withServeAddress(serveCommand, { host, port, hostFlag }) {
|
|
246687
|
-
const args = [
|
|
246688
|
-
...host ? [hostFlag, host] : [],
|
|
246689
|
-
...port === undefined ? [] : ["--port", String(port)]
|
|
246690
|
-
];
|
|
246691
|
-
if (args.length === 0 || !NPM_RUN_COMMAND.test(serveCommand.trim())) {
|
|
246692
|
-
return serveCommand;
|
|
246693
|
-
}
|
|
246694
|
-
return `${serveCommand} -- ${args.join(" ")}`;
|
|
246695
|
-
}
|
|
246696
|
-
function forwardsServeAddress(serveCommand) {
|
|
246697
|
-
return NPM_RUN_COMMAND.test(serveCommand.trim());
|
|
246698
|
-
}
|
|
246699
246761
|
// src/core/project/deploy.ts
|
|
246700
246762
|
function hasResourcesToDeploy(projectData) {
|
|
246701
246763
|
const {
|
|
@@ -246708,7 +246770,7 @@ function hasResourcesToDeploy(projectData) {
|
|
|
246708
246770
|
connectors,
|
|
246709
246771
|
authConfig
|
|
246710
246772
|
} = projectData;
|
|
246711
|
-
const hasSite = project.site
|
|
246773
|
+
const hasSite = Boolean(project.site?.outputDirectory);
|
|
246712
246774
|
const hasEntities = entities.length > 0;
|
|
246713
246775
|
const hasFunctions = functions.length > 0;
|
|
246714
246776
|
const hasActors = actors.length > 0;
|
|
@@ -246774,6 +246836,49 @@ async function deployAll(projectData, options) {
|
|
|
246774
246836
|
}
|
|
246775
246837
|
return { connectorResults };
|
|
246776
246838
|
}
|
|
246839
|
+
// src/core/project/target.ts
|
|
246840
|
+
import { dirname as dirname13, join as join19, resolve as resolve6 } from "node:path";
|
|
246841
|
+
var DEFAULT_BUILD_COMMAND = "npm run build";
|
|
246842
|
+
var DEFAULT_OUTPUT_DIRECTORY = "dist";
|
|
246843
|
+
async function resolveBuildTarget(projectRoot, overrides = {}) {
|
|
246844
|
+
const project = await readSettingsIfPresent(projectRoot);
|
|
246845
|
+
const root = project?.root ?? projectRoot ?? process.cwd();
|
|
246846
|
+
return {
|
|
246847
|
+
root,
|
|
246848
|
+
configDir: project ? dirname13(project.configPath) : join19(root, PROJECT_SUBDIR),
|
|
246849
|
+
buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
|
|
246850
|
+
outputDir: outputDirectory(project, root, overrides.outputDir),
|
|
246851
|
+
entitiesDir: project?.entitiesDir ?? "entities",
|
|
246852
|
+
agentsDir: project?.agentsDir ?? "agents"
|
|
246853
|
+
};
|
|
246854
|
+
}
|
|
246855
|
+
function outputDirectory(project, root, override) {
|
|
246856
|
+
const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
|
|
246857
|
+
return configured ? resolve6(root, configured) : null;
|
|
246858
|
+
}
|
|
246859
|
+
function requireOutputDir(target) {
|
|
246860
|
+
if (target.outputDir === null) {
|
|
246861
|
+
throw new ConfigNotFoundError("No site configuration found.", {
|
|
246862
|
+
hints: [
|
|
246863
|
+
{
|
|
246864
|
+
message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
|
|
246865
|
+
},
|
|
246866
|
+
{ message: `Or pass --output-dir <dir>, relative to ${target.root}` }
|
|
246867
|
+
]
|
|
246868
|
+
});
|
|
246869
|
+
}
|
|
246870
|
+
return target.outputDir;
|
|
246871
|
+
}
|
|
246872
|
+
async function readSettingsIfPresent(projectRoot) {
|
|
246873
|
+
try {
|
|
246874
|
+
return await readProjectSettings(projectRoot);
|
|
246875
|
+
} catch (error) {
|
|
246876
|
+
if (error instanceof ConfigNotFoundError) {
|
|
246877
|
+
return null;
|
|
246878
|
+
}
|
|
246879
|
+
throw error;
|
|
246880
|
+
}
|
|
246881
|
+
}
|
|
246777
246882
|
// src/core/clients/base44-client.ts
|
|
246778
246883
|
var retriedRequests = new WeakSet;
|
|
246779
246884
|
async function captureRequestBody(request, options) {
|
|
@@ -247055,6 +247160,12 @@ async function ensureAppContext(ctx, options = {}) {
|
|
|
247055
247160
|
ctx.app = appContext;
|
|
247056
247161
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
247057
247162
|
}
|
|
247163
|
+
function requireApp(ctx) {
|
|
247164
|
+
if (!ctx.app) {
|
|
247165
|
+
throw new InternalError("This command read an app context it never resolved — it is declared with requireAppContext: false.");
|
|
247166
|
+
}
|
|
247167
|
+
return ctx.app;
|
|
247168
|
+
}
|
|
247058
247169
|
|
|
247059
247170
|
// src/cli/utils/version-check.ts
|
|
247060
247171
|
async function checkForUpgrade() {
|
|
@@ -247238,6 +247349,10 @@ function writeJsonError(error) {
|
|
|
247238
247349
|
const envelope = {
|
|
247239
247350
|
error: error instanceof Error ? error.message : String(error)
|
|
247240
247351
|
};
|
|
247352
|
+
const step = stepOf(error);
|
|
247353
|
+
if (step !== undefined) {
|
|
247354
|
+
envelope.step = step;
|
|
247355
|
+
}
|
|
247241
247356
|
if (isCLIError(error)) {
|
|
247242
247357
|
envelope.code = error.code;
|
|
247243
247358
|
if (error.details.length > 0) {
|
|
@@ -247607,7 +247722,7 @@ function getActorsCommand() {
|
|
|
247607
247722
|
}
|
|
247608
247723
|
|
|
247609
247724
|
// src/cli/commands/agent-skills/pull.ts
|
|
247610
|
-
import { dirname as
|
|
247725
|
+
import { dirname as dirname14, join as join20 } from "node:path";
|
|
247611
247726
|
// src/core/utils/dependencies.ts
|
|
247612
247727
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
247613
247728
|
function verifyDenoInstalled(context) {
|
|
@@ -247696,7 +247811,7 @@ async function pullAction({
|
|
|
247696
247811
|
runTask
|
|
247697
247812
|
}) {
|
|
247698
247813
|
const { project } = await readProjectConfig();
|
|
247699
|
-
const dir =
|
|
247814
|
+
const dir = join20(dirname14(project.configPath), project.agentSkillsDir);
|
|
247700
247815
|
const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
|
|
247701
247816
|
successMessage: "Agent skills fetched successfully",
|
|
247702
247817
|
errorMessage: "Failed to fetch agent skills"
|
|
@@ -247752,14 +247867,14 @@ function getAgentSkillsCommand() {
|
|
|
247752
247867
|
}
|
|
247753
247868
|
|
|
247754
247869
|
// src/cli/commands/agents/pull.ts
|
|
247755
|
-
import { dirname as
|
|
247870
|
+
import { dirname as dirname15, join as join21 } from "node:path";
|
|
247756
247871
|
async function pullAgentsAction({
|
|
247757
247872
|
log,
|
|
247758
247873
|
runTask
|
|
247759
247874
|
}) {
|
|
247760
247875
|
const { project } = await readProjectConfig();
|
|
247761
|
-
const configDir =
|
|
247762
|
-
const agentsDir =
|
|
247876
|
+
const configDir = dirname15(project.configPath);
|
|
247877
|
+
const agentsDir = join21(configDir, project.agentsDir);
|
|
247763
247878
|
const remoteAgents = await runTask("Fetching agents from Base44", async () => {
|
|
247764
247879
|
return await fetchAgents();
|
|
247765
247880
|
}, {
|
|
@@ -247829,12 +247944,12 @@ function getAgentsCommand() {
|
|
|
247829
247944
|
}
|
|
247830
247945
|
|
|
247831
247946
|
// src/cli/commands/auth/password-login.ts
|
|
247832
|
-
import { dirname as
|
|
247947
|
+
import { dirname as dirname16, join as join22 } from "node:path";
|
|
247833
247948
|
async function passwordLoginAction({ log, runTask }, action) {
|
|
247834
247949
|
const shouldEnable = action === "enable";
|
|
247835
247950
|
const { project } = await readProjectConfig();
|
|
247836
|
-
const configDir =
|
|
247837
|
-
const authDir =
|
|
247951
|
+
const configDir = dirname16(project.configPath);
|
|
247952
|
+
const authDir = join22(configDir, project.authDir);
|
|
247838
247953
|
const updated = await runTask("Updating local auth config", async () => {
|
|
247839
247954
|
const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
|
|
247840
247955
|
const merged = { ...current, enableUsernamePassword: shouldEnable };
|
|
@@ -247854,14 +247969,14 @@ function getPasswordLoginCommand() {
|
|
|
247854
247969
|
}
|
|
247855
247970
|
|
|
247856
247971
|
// src/cli/commands/auth/pull.ts
|
|
247857
|
-
import { dirname as
|
|
247972
|
+
import { dirname as dirname17, join as join23 } from "node:path";
|
|
247858
247973
|
async function pullAuthAction({
|
|
247859
247974
|
log,
|
|
247860
247975
|
runTask
|
|
247861
247976
|
}) {
|
|
247862
247977
|
const { project } = await readProjectConfig();
|
|
247863
|
-
const configDir =
|
|
247864
|
-
const authDir =
|
|
247978
|
+
const configDir = dirname17(project.configPath);
|
|
247979
|
+
const authDir = join23(configDir, project.authDir);
|
|
247865
247980
|
const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
|
|
247866
247981
|
return await pullAuthConfig();
|
|
247867
247982
|
}, {
|
|
@@ -247925,7 +248040,7 @@ function getAuthPushCommand() {
|
|
|
247925
248040
|
}
|
|
247926
248041
|
|
|
247927
248042
|
// src/cli/commands/auth/social-login.ts
|
|
247928
|
-
import { dirname as
|
|
248043
|
+
import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
|
|
247929
248044
|
var PROVIDER_LABELS = {
|
|
247930
248045
|
google: "Google",
|
|
247931
248046
|
microsoft: "Microsoft",
|
|
@@ -247965,7 +248080,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
247965
248080
|
let clientSecret;
|
|
247966
248081
|
if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
|
|
247967
248082
|
if (options.envFile) {
|
|
247968
|
-
const secrets = await parseEnvFile(
|
|
248083
|
+
const secrets = await parseEnvFile(resolve7(options.envFile));
|
|
247969
248084
|
const value = secrets[oauthCli.envVar];
|
|
247970
248085
|
if (!value) {
|
|
247971
248086
|
throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
|
|
@@ -247995,8 +248110,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
247995
248110
|
}
|
|
247996
248111
|
}
|
|
247997
248112
|
const { project } = await readProjectConfig();
|
|
247998
|
-
const configDir =
|
|
247999
|
-
const authDir =
|
|
248113
|
+
const configDir = dirname18(project.configPath);
|
|
248114
|
+
const authDir = join24(configDir, project.authDir);
|
|
248000
248115
|
const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
|
|
248001
248116
|
if (clientSecret) {
|
|
248002
248117
|
await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
|
|
@@ -248021,7 +248136,7 @@ function getSocialLoginCommand() {
|
|
|
248021
248136
|
}
|
|
248022
248137
|
|
|
248023
248138
|
// src/cli/commands/auth/sso.ts
|
|
248024
|
-
import { dirname as
|
|
248139
|
+
import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
|
|
248025
248140
|
var SSOConfigFileSchema = object({
|
|
248026
248141
|
provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
248027
248142
|
clientId: string2(),
|
|
@@ -248037,7 +248152,7 @@ var SSOConfigFileSchema = object({
|
|
|
248037
248152
|
ssoName: string2().optional()
|
|
248038
248153
|
});
|
|
248039
248154
|
async function loadSSOConfigFile(filePath) {
|
|
248040
|
-
const resolved =
|
|
248155
|
+
const resolved = resolve8(filePath);
|
|
248041
248156
|
const raw = await readJsonFile(resolved);
|
|
248042
248157
|
const result = SSOConfigFileSchema.safeParse(raw);
|
|
248043
248158
|
if (!result.success) {
|
|
@@ -248125,7 +248240,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248125
248240
|
}
|
|
248126
248241
|
let clientSecret;
|
|
248127
248242
|
if (merged.envFile && !merged.clientSecret) {
|
|
248128
|
-
const secrets = await parseEnvFile(
|
|
248243
|
+
const secrets = await parseEnvFile(resolve8(merged.envFile));
|
|
248129
248244
|
const value = secrets.sso_client_secret;
|
|
248130
248245
|
if (!value) {
|
|
248131
248246
|
throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
|
|
@@ -248184,8 +248299,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248184
248299
|
throw error;
|
|
248185
248300
|
}
|
|
248186
248301
|
const { project } = await readProjectConfig();
|
|
248187
|
-
const configDir =
|
|
248188
|
-
const authDir =
|
|
248302
|
+
const configDir = dirname19(project.configPath);
|
|
248303
|
+
const authDir = join25(configDir, project.authDir);
|
|
248189
248304
|
await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
|
|
248190
248305
|
await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
|
|
248191
248306
|
return {
|
|
@@ -248200,8 +248315,8 @@ async function ssoDisableAction({ log, runTask }, options) {
|
|
|
248200
248315
|
throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
|
|
248201
248316
|
}
|
|
248202
248317
|
const { project } = await readProjectConfig();
|
|
248203
|
-
const configDir =
|
|
248204
|
-
const authDir =
|
|
248318
|
+
const configDir = dirname19(project.configPath);
|
|
248319
|
+
const authDir = join25(configDir, project.authDir);
|
|
248205
248320
|
const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
|
|
248206
248321
|
await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
|
|
248207
248322
|
if (!hasAnyLoginMethod(updated)) {
|
|
@@ -249083,13 +249198,13 @@ function getConnectorsListAvailableCommand() {
|
|
|
249083
249198
|
}
|
|
249084
249199
|
|
|
249085
249200
|
// src/cli/commands/connectors/pull.ts
|
|
249086
|
-
import { dirname as
|
|
249201
|
+
import { dirname as dirname20, join as join26, resolve as resolve9 } from "node:path";
|
|
249087
249202
|
async function resolveConnectorsDir(options) {
|
|
249088
249203
|
if (!getAppContext().projectRoot) {
|
|
249089
|
-
return
|
|
249204
|
+
return resolve9(options.dir ?? "connectors");
|
|
249090
249205
|
}
|
|
249091
249206
|
const { project } = await readProjectConfig();
|
|
249092
|
-
return
|
|
249207
|
+
return join26(dirname20(project.configPath), project.connectorsDir);
|
|
249093
249208
|
}
|
|
249094
249209
|
async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
|
|
249095
249210
|
const connectorsDir = await resolveConnectorsDir(options);
|
|
@@ -249130,10 +249245,10 @@ function getConnectorsPullCommand() {
|
|
|
249130
249245
|
}
|
|
249131
249246
|
|
|
249132
249247
|
// src/cli/commands/connectors/push.ts
|
|
249133
|
-
import { resolve as
|
|
249248
|
+
import { resolve as resolve10 } from "node:path";
|
|
249134
249249
|
async function readConnectorsToPush(options) {
|
|
249135
249250
|
if (!getAppContext().projectRoot) {
|
|
249136
|
-
return readAllConnectors(
|
|
249251
|
+
return readAllConnectors(resolve10(options.dir ?? "connectors"));
|
|
249137
249252
|
}
|
|
249138
249253
|
const { connectors } = await readProjectConfig();
|
|
249139
249254
|
return connectors;
|
|
@@ -249476,11 +249591,11 @@ function getListCommand() {
|
|
|
249476
249591
|
}
|
|
249477
249592
|
|
|
249478
249593
|
// src/cli/commands/functions/pull.ts
|
|
249479
|
-
import { dirname as
|
|
249594
|
+
import { dirname as dirname21, join as join27 } from "node:path";
|
|
249480
249595
|
async function pullFunctionsAction({ log, runTask }, name) {
|
|
249481
249596
|
const { project, functions } = await readProjectConfig();
|
|
249482
|
-
const configDir =
|
|
249483
|
-
const functionsDir =
|
|
249597
|
+
const configDir = dirname21(project.configPath);
|
|
249598
|
+
const functionsDir = join27(configDir, project.functionsDir);
|
|
249484
249599
|
const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
|
|
249485
249600
|
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
249486
249601
|
const { functions } = await listDeployedFunctions();
|
|
@@ -249583,14 +249698,11 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
|
|
|
249583
249698
|
|
|
249584
249699
|
// src/cli/commands/project/build.ts
|
|
249585
249700
|
async function buildAction(ctx) {
|
|
249586
|
-
const
|
|
249587
|
-
|
|
249588
|
-
throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
|
|
249589
|
-
}
|
|
249590
|
-
const { project } = await readProjectConfig(app.projectRoot);
|
|
249701
|
+
const app = requireApp(ctx);
|
|
249702
|
+
const target = await resolveBuildTarget(app.projectRoot);
|
|
249591
249703
|
await runSiteBuild(ctx, {
|
|
249592
|
-
root:
|
|
249593
|
-
buildCommand:
|
|
249704
|
+
root: target.root,
|
|
249705
|
+
buildCommand: target.buildCommand,
|
|
249594
249706
|
appId: app.id
|
|
249595
249707
|
});
|
|
249596
249708
|
return {
|
|
@@ -249598,15 +249710,15 @@ async function buildAction(ctx) {
|
|
|
249598
249710
|
};
|
|
249599
249711
|
}
|
|
249600
249712
|
function getBuildCommand() {
|
|
249601
|
-
return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
|
|
249713
|
+
return new Base44Command("build", { requireAuth: false }).description("Build the site with the Base44 app id injected").action(buildAction);
|
|
249602
249714
|
}
|
|
249603
249715
|
|
|
249604
249716
|
// src/cli/commands/project/create.ts
|
|
249605
|
-
import { basename as basename6, resolve as
|
|
249717
|
+
import { basename as basename6, resolve as resolve11 } from "node:path";
|
|
249606
249718
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
249607
249719
|
|
|
249608
249720
|
// src/cli/commands/project/scaffold-shared.ts
|
|
249609
|
-
import { join as
|
|
249721
|
+
import { join as join28 } from "node:path";
|
|
249610
249722
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
249611
249723
|
async function getTemplateById(templateId) {
|
|
249612
249724
|
const templates = await listTemplates();
|
|
@@ -249669,7 +249781,7 @@ async function completeProjectSetup({
|
|
|
249669
249781
|
env: { VITE_BASE44_APP_ID: projectId }
|
|
249670
249782
|
})`${buildCommand}`;
|
|
249671
249783
|
updateMessage("Deploying site...");
|
|
249672
|
-
return await deploySite(
|
|
249784
|
+
return await deploySite(join28(resolvedPath, outputDirectory));
|
|
249673
249785
|
}, {
|
|
249674
249786
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
249675
249787
|
errorMessage: "Failed to deploy site"
|
|
@@ -249798,7 +249910,7 @@ async function createInteractive(options, ctx) {
|
|
|
249798
249910
|
}, ctx);
|
|
249799
249911
|
}
|
|
249800
249912
|
async function createNonInteractive(options, ctx) {
|
|
249801
|
-
ctx.log.info(`Creating a new project at ${
|
|
249913
|
+
ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
|
|
249802
249914
|
const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
|
|
249803
249915
|
return await executeCreate({
|
|
249804
249916
|
template,
|
|
@@ -249822,7 +249934,7 @@ async function executeCreate({
|
|
|
249822
249934
|
}, ctx) {
|
|
249823
249935
|
const { log, runTask } = ctx;
|
|
249824
249936
|
const name = rawName.trim();
|
|
249825
|
-
const resolvedPath =
|
|
249937
|
+
const resolvedPath = resolve11(projectPath);
|
|
249826
249938
|
const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
|
|
249827
249939
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
249828
249940
|
return await createProjectFiles({
|
|
@@ -249995,36 +250107,6 @@ function printStripeResult(r, log) {
|
|
|
249995
250107
|
log.info(` Connectors dashboard: ${theme.colors.links(getConnectorsUrl())}`);
|
|
249996
250108
|
}
|
|
249997
250109
|
|
|
249998
|
-
// src/cli/commands/project/install.ts
|
|
249999
|
-
async function installAction({
|
|
250000
|
-
runTask
|
|
250001
|
-
}) {
|
|
250002
|
-
const { project } = await readProjectConfig();
|
|
250003
|
-
const installCommand = project.site?.installCommand;
|
|
250004
|
-
if (!installCommand) {
|
|
250005
|
-
throw new ConfigNotFoundError("No site install command found.", {
|
|
250006
|
-
hints: [
|
|
250007
|
-
{
|
|
250008
|
-
message: `Add a 'site' block to your config.jsonc (e.g., "site": { "installCommand": "npm ci" }). Inside one, installCommand defaults to "npm install".`
|
|
250009
|
-
}
|
|
250010
|
-
]
|
|
250011
|
-
});
|
|
250012
|
-
}
|
|
250013
|
-
await runTask("Installing site dependencies...", () => execa({ cwd: project.root, shell: true })`${installCommand}`, {
|
|
250014
|
-
successMessage: "Dependencies installed",
|
|
250015
|
-
errorMessage: "Install failed"
|
|
250016
|
-
});
|
|
250017
|
-
return {
|
|
250018
|
-
outroMessage: `Installed with ${theme.styles.bold(installCommand)}`
|
|
250019
|
-
};
|
|
250020
|
-
}
|
|
250021
|
-
function getInstallCommand() {
|
|
250022
|
-
return new Base44Command("install", {
|
|
250023
|
-
requireAuth: false,
|
|
250024
|
-
requireAppContext: false
|
|
250025
|
-
}).description("Install the site's dependencies with its configured command").action(installAction);
|
|
250026
|
-
}
|
|
250027
|
-
|
|
250028
250110
|
// src/cli/commands/project/app-id-options.ts
|
|
250029
250111
|
function readExplicitAppId(command) {
|
|
250030
250112
|
const { appId } = command.optsWithGlobals();
|
|
@@ -250493,7 +250575,7 @@ function getLogsCommand() {
|
|
|
250493
250575
|
}
|
|
250494
250576
|
|
|
250495
250577
|
// src/cli/commands/project/scaffold.ts
|
|
250496
|
-
import { basename as basename7, resolve as
|
|
250578
|
+
import { basename as basename7, resolve as resolve12 } from "node:path";
|
|
250497
250579
|
function resolveAppId(options) {
|
|
250498
250580
|
const appId = options.appId;
|
|
250499
250581
|
if (!appId) {
|
|
@@ -250509,7 +250591,7 @@ function resolveAppId(options) {
|
|
|
250509
250591
|
async function scaffoldAction(ctx, name, options, command) {
|
|
250510
250592
|
const { log, runTask } = ctx;
|
|
250511
250593
|
const appId = resolveAppId(command.optsWithGlobals());
|
|
250512
|
-
const resolvedPath =
|
|
250594
|
+
const resolvedPath = resolve12("./");
|
|
250513
250595
|
const projectName = (name ?? basename7(resolvedPath)).trim();
|
|
250514
250596
|
const template = await getTemplateById("backend-only");
|
|
250515
250597
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
@@ -250557,6 +250639,315 @@ function getVisibilityCommand() {
|
|
|
250557
250639
|
])).action(setVisibility);
|
|
250558
250640
|
}
|
|
250559
250641
|
|
|
250642
|
+
// src/core/version/schema.ts
|
|
250643
|
+
var DeclareVersionResponseSchema = object({
|
|
250644
|
+
session_id: string2(),
|
|
250645
|
+
uploads: array(object({
|
|
250646
|
+
path: string2(),
|
|
250647
|
+
url: string2(),
|
|
250648
|
+
content_type: string2(),
|
|
250649
|
+
content_length: number2(),
|
|
250650
|
+
checksum_sha256: string2()
|
|
250651
|
+
}))
|
|
250652
|
+
}).transform((data) => ({
|
|
250653
|
+
sessionId: data.session_id,
|
|
250654
|
+
uploads: data.uploads.map((upload) => ({
|
|
250655
|
+
path: upload.path,
|
|
250656
|
+
url: upload.url,
|
|
250657
|
+
contentType: upload.content_type,
|
|
250658
|
+
contentLength: upload.content_length,
|
|
250659
|
+
checksumSha256: upload.checksum_sha256
|
|
250660
|
+
}))
|
|
250661
|
+
}));
|
|
250662
|
+
var CreateVersionResponseSchema = object({
|
|
250663
|
+
version_id: string2(),
|
|
250664
|
+
manifest_hash: string2()
|
|
250665
|
+
}).transform((data) => ({
|
|
250666
|
+
versionId: data.version_id,
|
|
250667
|
+
manifestHash: data.manifest_hash
|
|
250668
|
+
}));
|
|
250669
|
+
var EnvironmentResponseSchema = object({
|
|
250670
|
+
name: string2(),
|
|
250671
|
+
version_id: string2(),
|
|
250672
|
+
manifest_hash: string2(),
|
|
250673
|
+
deployment_id: string2()
|
|
250674
|
+
}).transform((data) => ({
|
|
250675
|
+
name: data.name,
|
|
250676
|
+
versionId: data.version_id,
|
|
250677
|
+
manifestHash: data.manifest_hash,
|
|
250678
|
+
deploymentId: data.deployment_id
|
|
250679
|
+
}));
|
|
250680
|
+
|
|
250681
|
+
// src/core/version/api.ts
|
|
250682
|
+
var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
|
|
250683
|
+
var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
|
|
250684
|
+
function declaredFile({ path, size, digest }) {
|
|
250685
|
+
return { path, size, digest };
|
|
250686
|
+
}
|
|
250687
|
+
function declaredModule(module) {
|
|
250688
|
+
return { ...declaredFile(module), type: module.type };
|
|
250689
|
+
}
|
|
250690
|
+
function declaredServingConfig(config) {
|
|
250691
|
+
const stated = {
|
|
250692
|
+
html_handling: config?.htmlHandling ?? null,
|
|
250693
|
+
not_found_handling: config?.notFoundHandling ?? null,
|
|
250694
|
+
run_worker_first: config?.runWorkerFirst ?? null,
|
|
250695
|
+
headers: config?.headers ?? null,
|
|
250696
|
+
redirects: config?.redirects ?? null
|
|
250697
|
+
};
|
|
250698
|
+
return Object.values(stated).every((v) => v === null) ? null : stated;
|
|
250699
|
+
}
|
|
250700
|
+
async function post(path, json, doing) {
|
|
250701
|
+
try {
|
|
250702
|
+
return await getAppClient().post(path, { json, timeout: 180000 });
|
|
250703
|
+
} catch (error) {
|
|
250704
|
+
throw await ApiError.fromHttpError(error, doing);
|
|
250705
|
+
}
|
|
250706
|
+
}
|
|
250707
|
+
var KEYED_RETRY = {
|
|
250708
|
+
limit: 3,
|
|
250709
|
+
methods: ["patch"],
|
|
250710
|
+
statusCodes: [408, 500, 502, 503, 504],
|
|
250711
|
+
retryOnTimeout: true
|
|
250712
|
+
};
|
|
250713
|
+
async function patch(path, json, doing, retry) {
|
|
250714
|
+
try {
|
|
250715
|
+
return await getAppClient().patch(path, {
|
|
250716
|
+
json,
|
|
250717
|
+
timeout: 180000,
|
|
250718
|
+
...retry ? { retry } : {}
|
|
250719
|
+
});
|
|
250720
|
+
} catch (error) {
|
|
250721
|
+
throw await ApiError.fromHttpError(error, doing);
|
|
250722
|
+
}
|
|
250723
|
+
}
|
|
250724
|
+
function parse10(schema, body, what) {
|
|
250725
|
+
const result = schema.safeParse(body);
|
|
250726
|
+
if (!result.success) {
|
|
250727
|
+
throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
|
|
250728
|
+
}
|
|
250729
|
+
return result.data;
|
|
250730
|
+
}
|
|
250731
|
+
async function createVersion(artifacts, options = {}) {
|
|
250732
|
+
const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
|
|
250733
|
+
assets: artifacts.assets.map(declaredFile),
|
|
250734
|
+
...artifacts.siteWorker ? {
|
|
250735
|
+
site_worker: {
|
|
250736
|
+
main: artifacts.siteWorker.main,
|
|
250737
|
+
modules: artifacts.siteWorker.modules.map(declaredModule),
|
|
250738
|
+
compatibility_date: artifacts.siteWorker.compatibilityDate,
|
|
250739
|
+
compatibility_flags: artifacts.siteWorker.compatibilityFlags,
|
|
250740
|
+
serving_config: declaredServingConfig(artifacts.siteWorker.servingConfig)
|
|
250741
|
+
}
|
|
250742
|
+
} : {},
|
|
250743
|
+
entities: artifacts.entities,
|
|
250744
|
+
agents: artifacts.agents,
|
|
250745
|
+
source_commit: options.sourceCommit
|
|
250746
|
+
}, "declaring a version")).json(), "declare");
|
|
250747
|
+
const declaredFiles = [
|
|
250748
|
+
...artifacts.assets,
|
|
250749
|
+
...artifacts.siteWorker?.modules ?? []
|
|
250750
|
+
];
|
|
250751
|
+
options.progress?.onDeclared?.({ fileCount: declaredFiles.length });
|
|
250752
|
+
if (declared.uploads.length !== declaredFiles.length) {
|
|
250753
|
+
throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
|
|
250754
|
+
}
|
|
250755
|
+
const drifted = declared.uploads.findIndex((upload, index) => upload.path !== declaredFiles[index].path);
|
|
250756
|
+
if (drifted !== -1) {
|
|
250757
|
+
throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
|
|
250758
|
+
}
|
|
250759
|
+
let uploadedFiles = 0;
|
|
250760
|
+
await pMap(declared.uploads, async (upload, index) => {
|
|
250761
|
+
await putPresigned(upload, declaredFiles[index].absolutePath);
|
|
250762
|
+
uploadedFiles++;
|
|
250763
|
+
options.progress?.onUpload?.({
|
|
250764
|
+
uploadedFiles,
|
|
250765
|
+
totalFiles: declared.uploads.length
|
|
250766
|
+
});
|
|
250767
|
+
}, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
|
|
250768
|
+
return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
|
|
250769
|
+
}
|
|
250770
|
+
async function setEnvironmentVersion(environment, versionId, options = {}) {
|
|
250771
|
+
return parse10(EnvironmentResponseSchema, await (await patch(`environments/${encodeURIComponent(environment)}`, {
|
|
250772
|
+
version_id: versionId,
|
|
250773
|
+
...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
|
|
250774
|
+
}, "setting the environment's version", options.idempotencyKey ? KEYED_RETRY : undefined)).json(), "environment");
|
|
250775
|
+
}
|
|
250776
|
+
// src/core/version/artifacts.ts
|
|
250777
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
250778
|
+
import { join as join29, resolve as resolve13 } from "node:path";
|
|
250779
|
+
var MAX_FILE_COUNT = 50000;
|
|
250780
|
+
var HASH_CONCURRENCY = 32;
|
|
250781
|
+
var ENTRY2 = "index.html";
|
|
250782
|
+
async function digestFile(absolutePath) {
|
|
250783
|
+
const hash = await hashFileInto(createHash2("sha256"), absolutePath);
|
|
250784
|
+
return `sha256:${hash.digest("hex")}`;
|
|
250785
|
+
}
|
|
250786
|
+
async function collectBuildOutput(outputDir, options = {}) {
|
|
250787
|
+
const found = await describeBuildOutput(outputDir);
|
|
250788
|
+
if (found.length > MAX_FILE_COUNT) {
|
|
250789
|
+
throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
|
|
250790
|
+
}
|
|
250791
|
+
if (options.entryFile) {
|
|
250792
|
+
if (found.length === 0) {
|
|
250793
|
+
throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
|
|
250794
|
+
hints: [
|
|
250795
|
+
{ message: "Run 'base44 build' first", command: "base44 build" }
|
|
250796
|
+
]
|
|
250797
|
+
});
|
|
250798
|
+
}
|
|
250799
|
+
if (!found.some((f) => f.path === options.entryFile)) {
|
|
250800
|
+
throw new InvalidInputError(`${outputDir} has no ${options.entryFile}, so nothing could enter the site.`);
|
|
250801
|
+
}
|
|
250802
|
+
}
|
|
250803
|
+
return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
|
|
250804
|
+
}
|
|
250805
|
+
async function describeSiteWorker(built) {
|
|
250806
|
+
const { config, modules } = built;
|
|
250807
|
+
const entry = resolve13(config.configDir, config.main);
|
|
250808
|
+
const main = modules.find((m) => m.absolutePath === entry)?.name;
|
|
250809
|
+
if (!main) {
|
|
250810
|
+
throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
|
|
250811
|
+
}
|
|
250812
|
+
return {
|
|
250813
|
+
main,
|
|
250814
|
+
modules: await pMap(modules, async ({ name, absolutePath, size, type }) => ({
|
|
250815
|
+
path: name,
|
|
250816
|
+
absolutePath,
|
|
250817
|
+
size,
|
|
250818
|
+
digest: await digestFile(absolutePath),
|
|
250819
|
+
type
|
|
250820
|
+
}), { concurrency: HASH_CONCURRENCY }),
|
|
250821
|
+
compatibilityDate: config.compatibilityDate,
|
|
250822
|
+
compatibilityFlags: config.compatibilityFlags,
|
|
250823
|
+
servingConfig: config.assetsConfig
|
|
250824
|
+
};
|
|
250825
|
+
}
|
|
250826
|
+
async function readRawResources(dir) {
|
|
250827
|
+
if (!await pathExists(dir)) {
|
|
250828
|
+
return {};
|
|
250829
|
+
}
|
|
250830
|
+
const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
|
|
250831
|
+
cwd: dir,
|
|
250832
|
+
onlyFiles: true,
|
|
250833
|
+
followSymbolicLinks: false
|
|
250834
|
+
});
|
|
250835
|
+
const payloads = {};
|
|
250836
|
+
for (const relativePath of files.sort()) {
|
|
250837
|
+
const name = relativePath.replace(/\.jsonc?$/, "");
|
|
250838
|
+
payloads[name] = await readJsonFile(join29(dir, ...relativePath.split("/")));
|
|
250839
|
+
}
|
|
250840
|
+
return payloads;
|
|
250841
|
+
}
|
|
250842
|
+
async function collectResources(configDir, dirs) {
|
|
250843
|
+
const [entities, agents] = await Promise.all([
|
|
250844
|
+
readRawResources(join29(configDir, dirs.entitiesDir)),
|
|
250845
|
+
readRawResources(join29(configDir, dirs.agentsDir))
|
|
250846
|
+
]);
|
|
250847
|
+
return { entities, agents };
|
|
250848
|
+
}
|
|
250849
|
+
async function collectArtifacts(target) {
|
|
250850
|
+
const built = await resolveFullStackBuild(target.root);
|
|
250851
|
+
const siteWorker = built ? await describeSiteWorker(built) : null;
|
|
250852
|
+
return {
|
|
250853
|
+
assets: built ? built.assetsDir ? await collectBuildOutput(built.assetsDir) : [] : await collectBuildOutput(requireOutputDir(target), {
|
|
250854
|
+
entryFile: ENTRY2
|
|
250855
|
+
}),
|
|
250856
|
+
...siteWorker ? { siteWorker } : {},
|
|
250857
|
+
...await collectResources(target.configDir, target)
|
|
250858
|
+
};
|
|
250859
|
+
}
|
|
250860
|
+
// src/core/version/gate.ts
|
|
250861
|
+
var VERSIONS_API_ENV = "BASE44_VERSIONS_API";
|
|
250862
|
+
function versionsApiEnabled(env = process.env) {
|
|
250863
|
+
const value = env[VERSIONS_API_ENV];
|
|
250864
|
+
return value === "1" || value === "true";
|
|
250865
|
+
}
|
|
250866
|
+
// src/core/version/publish.ts
|
|
250867
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
250868
|
+
var DEFAULT_ENVIRONMENT = "production";
|
|
250869
|
+
async function tagStep2(step, run) {
|
|
250870
|
+
return await tagStep(step, run);
|
|
250871
|
+
}
|
|
250872
|
+
async function publishVersion(artifacts, options = {}) {
|
|
250873
|
+
const version = await tagStep2("create_version", () => createVersion(artifacts, {
|
|
250874
|
+
sourceCommit: options.sourceCommit,
|
|
250875
|
+
concurrency: options.concurrency,
|
|
250876
|
+
progress: options.progress
|
|
250877
|
+
}));
|
|
250878
|
+
const environment = await tagStep2("deploy", () => setEnvironmentVersion(options.target ?? DEFAULT_ENVIRONMENT, version.versionId, {
|
|
250879
|
+
idempotencyKey: randomUUID4()
|
|
250880
|
+
}));
|
|
250881
|
+
return {
|
|
250882
|
+
environment: environment.name,
|
|
250883
|
+
versionId: environment.versionId,
|
|
250884
|
+
manifestHash: environment.manifestHash,
|
|
250885
|
+
deploymentId: environment.deploymentId
|
|
250886
|
+
};
|
|
250887
|
+
}
|
|
250888
|
+
// src/cli/commands/versions/options.ts
|
|
250889
|
+
function outputDirOption() {
|
|
250890
|
+
return new Option2("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)");
|
|
250891
|
+
}
|
|
250892
|
+
function targetOption() {
|
|
250893
|
+
return new Option2("--target <name>", "Environment to serve the version at");
|
|
250894
|
+
}
|
|
250895
|
+
function gitHashOption() {
|
|
250896
|
+
return new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser((value) => {
|
|
250897
|
+
if (!isGitCommitHash(value)) {
|
|
250898
|
+
throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
|
|
250899
|
+
}
|
|
250900
|
+
return value;
|
|
250901
|
+
});
|
|
250902
|
+
}
|
|
250903
|
+
function concurrencyOption() {
|
|
250904
|
+
return new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser((value) => {
|
|
250905
|
+
const parsed = Number(value);
|
|
250906
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
|
|
250907
|
+
throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
|
|
250908
|
+
}
|
|
250909
|
+
return parsed;
|
|
250910
|
+
});
|
|
250911
|
+
}
|
|
250912
|
+
|
|
250913
|
+
// src/cli/commands/publish.ts
|
|
250914
|
+
async function publishAction(ctx, options) {
|
|
250915
|
+
const { runTask, log, jsonMode } = ctx;
|
|
250916
|
+
const app = requireApp(ctx);
|
|
250917
|
+
const target = await tagStep2("create_version", () => resolveBuildTarget(app.projectRoot, { outputDir: options.outputDir }));
|
|
250918
|
+
if (options.build !== false) {
|
|
250919
|
+
await tagStep2("build", () => runSiteBuild(ctx, {
|
|
250920
|
+
root: target.root,
|
|
250921
|
+
buildCommand: target.buildCommand,
|
|
250922
|
+
appId: app.id
|
|
250923
|
+
}));
|
|
250924
|
+
}
|
|
250925
|
+
const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
|
|
250926
|
+
const result = await runTask("Publishing...", async (updateMessage) => {
|
|
250927
|
+
const artifacts = await tagStep2("create_version", () => collectArtifacts(target));
|
|
250928
|
+
return await publishVersion(artifacts, {
|
|
250929
|
+
sourceCommit: gitHash,
|
|
250930
|
+
target: options.target,
|
|
250931
|
+
concurrency: options.concurrency,
|
|
250932
|
+
progress: {
|
|
250933
|
+
onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
|
|
250934
|
+
onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
|
|
250935
|
+
}
|
|
250936
|
+
});
|
|
250937
|
+
}, { successMessage: "Published", errorMessage: "Publish failed" });
|
|
250938
|
+
if (!jsonMode) {
|
|
250939
|
+
log.message(theme.styles.dim(`version ${result.versionId}`));
|
|
250940
|
+
}
|
|
250941
|
+
return {
|
|
250942
|
+
outroMessage: `${result.environment} now serves ${result.versionId}`,
|
|
250943
|
+
stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
|
|
250944
|
+
` : undefined
|
|
250945
|
+
};
|
|
250946
|
+
}
|
|
250947
|
+
function getPublishCommand() {
|
|
250948
|
+
return new Base44Command("publish").description("Build the app, record it as a version, and serve that version").option("--no-build", "Publish the existing build output without rebuilding").addOption(outputDirOption()).addOption(targetOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(publishAction);
|
|
250949
|
+
}
|
|
250950
|
+
|
|
250560
250951
|
// src/core/resources/sandbox/schema.ts
|
|
250561
250952
|
var FileErrorSchema = object({
|
|
250562
250953
|
code: string2(),
|
|
@@ -250942,7 +251333,7 @@ function getSecretsListCommand() {
|
|
|
250942
251333
|
}
|
|
250943
251334
|
|
|
250944
251335
|
// src/cli/commands/secrets/set.ts
|
|
250945
|
-
import { resolve as
|
|
251336
|
+
import { resolve as resolve14 } from "node:path";
|
|
250946
251337
|
function parseEntries(entries) {
|
|
250947
251338
|
const secrets = {};
|
|
250948
251339
|
for (const entry of entries) {
|
|
@@ -250973,7 +251364,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
|
|
|
250973
251364
|
validateInput(entries, options);
|
|
250974
251365
|
let secrets;
|
|
250975
251366
|
if (options.envFile) {
|
|
250976
|
-
secrets = await parseEnvFile(
|
|
251367
|
+
secrets = await parseEnvFile(resolve14(options.envFile));
|
|
250977
251368
|
if (Object.keys(secrets).length === 0) {
|
|
250978
251369
|
throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
|
|
250979
251370
|
}
|
|
@@ -251002,7 +251393,7 @@ function getSecretsCommand() {
|
|
|
251002
251393
|
}
|
|
251003
251394
|
|
|
251004
251395
|
// src/cli/commands/site/deploy.ts
|
|
251005
|
-
import { resolve as
|
|
251396
|
+
import { resolve as resolve15 } from "node:path";
|
|
251006
251397
|
async function deployAction2(ctx, options) {
|
|
251007
251398
|
const { isNonInteractive } = ctx;
|
|
251008
251399
|
if (isNonInteractive && !options.yes) {
|
|
@@ -251067,7 +251458,7 @@ async function deployTarball({ runTask }, project) {
|
|
|
251067
251458
|
throw new ConfigNotFoundError("No site configuration found.", {
|
|
251068
251459
|
hints: [
|
|
251069
251460
|
{
|
|
251070
|
-
message: `Add
|
|
251461
|
+
message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
|
|
251071
251462
|
}
|
|
251072
251463
|
]
|
|
251073
251464
|
});
|
|
@@ -251080,7 +251471,7 @@ async function deployTarball({ runTask }, project) {
|
|
|
251080
251471
|
}
|
|
251081
251472
|
function siteOutputDir(project) {
|
|
251082
251473
|
const outputDirectory = project.site?.outputDirectory;
|
|
251083
|
-
return outputDirectory ?
|
|
251474
|
+
return outputDirectory ? resolve15(project.root, outputDirectory) : null;
|
|
251084
251475
|
}
|
|
251085
251476
|
function getSiteDeployCommand() {
|
|
251086
251477
|
const command = new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)");
|
|
@@ -251104,213 +251495,6 @@ function parseConcurrency(value) {
|
|
|
251104
251495
|
return parsed;
|
|
251105
251496
|
}
|
|
251106
251497
|
|
|
251107
|
-
// src/cli/dev/createDevLogger.ts
|
|
251108
|
-
var colorByType = {
|
|
251109
|
-
error: theme.styles.error,
|
|
251110
|
-
warn: theme.styles.warn,
|
|
251111
|
-
log: (input) => input
|
|
251112
|
-
};
|
|
251113
|
-
var stringify = (item) => {
|
|
251114
|
-
if (typeof item === "string") {
|
|
251115
|
-
return item;
|
|
251116
|
-
}
|
|
251117
|
-
if (item instanceof Error) {
|
|
251118
|
-
return item.toString();
|
|
251119
|
-
}
|
|
251120
|
-
try {
|
|
251121
|
-
return JSON.stringify(item, null, 2) ?? String(item);
|
|
251122
|
-
} catch {
|
|
251123
|
-
return String(item);
|
|
251124
|
-
}
|
|
251125
|
-
};
|
|
251126
|
-
function createDevLogger(label, labelColor = theme.styles.dim) {
|
|
251127
|
-
const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
|
|
251128
|
-
const print = (type, ...args) => {
|
|
251129
|
-
const colorize = colorByType[type];
|
|
251130
|
-
console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
|
|
251131
|
-
};
|
|
251132
|
-
return {
|
|
251133
|
-
log: (...args) => print("log", ...args),
|
|
251134
|
-
error: (msg, err) => {
|
|
251135
|
-
print("error", msg);
|
|
251136
|
-
if (err) {
|
|
251137
|
-
print("error", err);
|
|
251138
|
-
}
|
|
251139
|
-
},
|
|
251140
|
-
warn: (...args) => print("warn", ...args)
|
|
251141
|
-
};
|
|
251142
|
-
}
|
|
251143
|
-
|
|
251144
|
-
// src/cli/dev/dev-server/serve-runner.ts
|
|
251145
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
251146
|
-
import process21 from "node:process";
|
|
251147
|
-
|
|
251148
|
-
class ServeRunner {
|
|
251149
|
-
command;
|
|
251150
|
-
cwd;
|
|
251151
|
-
env;
|
|
251152
|
-
logger;
|
|
251153
|
-
child;
|
|
251154
|
-
stopping = false;
|
|
251155
|
-
stopPromise;
|
|
251156
|
-
exitListeners = [];
|
|
251157
|
-
constructor(options) {
|
|
251158
|
-
this.command = options.command;
|
|
251159
|
-
this.cwd = options.cwd;
|
|
251160
|
-
this.env = options.env;
|
|
251161
|
-
this.logger = options.logger;
|
|
251162
|
-
}
|
|
251163
|
-
start() {
|
|
251164
|
-
if (this.child) {
|
|
251165
|
-
return;
|
|
251166
|
-
}
|
|
251167
|
-
const stdin = process21.platform === "win32" ? "ignore" : "inherit";
|
|
251168
|
-
const child = spawn2(this.command, {
|
|
251169
|
-
cwd: this.cwd,
|
|
251170
|
-
shell: true,
|
|
251171
|
-
detached: process21.platform !== "win32",
|
|
251172
|
-
env: { ...process21.env, ...this.env },
|
|
251173
|
-
stdio: [stdin, "pipe", "pipe"],
|
|
251174
|
-
windowsHide: true
|
|
251175
|
-
});
|
|
251176
|
-
this.child = child;
|
|
251177
|
-
this.setupHandlers(child);
|
|
251178
|
-
}
|
|
251179
|
-
onExit(listener) {
|
|
251180
|
-
this.exitListeners.push(listener);
|
|
251181
|
-
}
|
|
251182
|
-
async stop() {
|
|
251183
|
-
if (this.stopPromise) {
|
|
251184
|
-
return this.stopPromise;
|
|
251185
|
-
}
|
|
251186
|
-
this.stopPromise = this.stopChild();
|
|
251187
|
-
return this.stopPromise;
|
|
251188
|
-
}
|
|
251189
|
-
async stopChild() {
|
|
251190
|
-
const child = this.child;
|
|
251191
|
-
if (!child || child.exitCode !== null) {
|
|
251192
|
-
return;
|
|
251193
|
-
}
|
|
251194
|
-
this.stopping = true;
|
|
251195
|
-
const exited = new Promise((resolve) => child.once("exit", () => resolve()));
|
|
251196
|
-
if (process21.platform === "win32" && child.pid) {
|
|
251197
|
-
const taskkill = spawn2("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
251198
|
-
stdio: "ignore",
|
|
251199
|
-
windowsHide: true
|
|
251200
|
-
});
|
|
251201
|
-
await new Promise((resolve) => {
|
|
251202
|
-
taskkill.once("exit", () => resolve());
|
|
251203
|
-
taskkill.once("error", () => resolve());
|
|
251204
|
-
});
|
|
251205
|
-
} else if (child.pid) {
|
|
251206
|
-
try {
|
|
251207
|
-
process21.kill(-child.pid, "SIGTERM");
|
|
251208
|
-
} catch {
|
|
251209
|
-
child.kill();
|
|
251210
|
-
}
|
|
251211
|
-
}
|
|
251212
|
-
await exited;
|
|
251213
|
-
}
|
|
251214
|
-
setupHandlers(child) {
|
|
251215
|
-
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
251216
|
-
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
251217
|
-
child.on("error", (error) => {
|
|
251218
|
-
this.logger.error("Frontend dev server failed to start:", error);
|
|
251219
|
-
this.notifyExit(null);
|
|
251220
|
-
});
|
|
251221
|
-
child.on("exit", (code) => {
|
|
251222
|
-
if (this.stopping) {
|
|
251223
|
-
return;
|
|
251224
|
-
}
|
|
251225
|
-
this.logger.error(`Frontend dev server exited with code ${code}`);
|
|
251226
|
-
this.notifyExit(code);
|
|
251227
|
-
});
|
|
251228
|
-
}
|
|
251229
|
-
notifyExit(code) {
|
|
251230
|
-
for (const listener of this.exitListeners) {
|
|
251231
|
-
listener(code);
|
|
251232
|
-
}
|
|
251233
|
-
}
|
|
251234
|
-
emitLines(data, type) {
|
|
251235
|
-
const lines = data.toString().trimEnd().split(`
|
|
251236
|
-
`);
|
|
251237
|
-
for (const line of lines) {
|
|
251238
|
-
if (type === "error") {
|
|
251239
|
-
this.logger.error(line);
|
|
251240
|
-
} else {
|
|
251241
|
-
this.logger.log(line);
|
|
251242
|
-
}
|
|
251243
|
-
}
|
|
251244
|
-
}
|
|
251245
|
-
}
|
|
251246
|
-
|
|
251247
|
-
// src/cli/dev/serve-command-runner.ts
|
|
251248
|
-
function createServeCommandRunner({
|
|
251249
|
-
serveCommand,
|
|
251250
|
-
projectRoot,
|
|
251251
|
-
appId,
|
|
251252
|
-
appBaseUrl
|
|
251253
|
-
}) {
|
|
251254
|
-
return new ServeRunner({
|
|
251255
|
-
command: serveCommand,
|
|
251256
|
-
cwd: projectRoot,
|
|
251257
|
-
env: {
|
|
251258
|
-
VITE_BASE44_APP_ID: appId,
|
|
251259
|
-
VITE_BASE44_APP_BASE_URL: appBaseUrl
|
|
251260
|
-
},
|
|
251261
|
-
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
251262
|
-
});
|
|
251263
|
-
}
|
|
251264
|
-
|
|
251265
|
-
// src/cli/dev/stop-runner-on-signals.ts
|
|
251266
|
-
import process22 from "node:process";
|
|
251267
|
-
function stopRunnerOnProcessSignals(runner) {
|
|
251268
|
-
const stop = () => void runner.stop();
|
|
251269
|
-
process22.on("SIGINT", stop);
|
|
251270
|
-
process22.on("SIGTERM", stop);
|
|
251271
|
-
}
|
|
251272
|
-
|
|
251273
|
-
// src/cli/commands/site/dev.ts
|
|
251274
|
-
async function siteDevAction(ctx, options) {
|
|
251275
|
-
const { app, log } = ctx;
|
|
251276
|
-
if (!app) {
|
|
251277
|
-
throw new InvalidInputError("No app id resolved for this project.");
|
|
251278
|
-
}
|
|
251279
|
-
const port = options.port === undefined ? undefined : Number(options.port);
|
|
251280
|
-
if (port !== undefined && !Number.isInteger(port)) {
|
|
251281
|
-
throw new InvalidInputError(`--port must be a whole number: ${options.port}`);
|
|
251282
|
-
}
|
|
251283
|
-
const { project } = await readProjectConfig(app.projectRoot);
|
|
251284
|
-
const site = project.site;
|
|
251285
|
-
if (!site) {
|
|
251286
|
-
throw new InvalidInputError(`This project has no 'site' block in base44/config.jsonc, so there is no frontend to serve. Add one; inside it serveCommand defaults to "npm run dev".`);
|
|
251287
|
-
}
|
|
251288
|
-
const serveCommand = site.serveCommand ?? DEFAULT_SERVE_COMMAND;
|
|
251289
|
-
const command = withServeAddress(serveCommand, {
|
|
251290
|
-
host: options.host,
|
|
251291
|
-
port,
|
|
251292
|
-
hostFlag: site.devHostFlag
|
|
251293
|
-
});
|
|
251294
|
-
if ((options.host || port !== undefined) && !forwardsServeAddress(serveCommand)) {
|
|
251295
|
-
log.warn(`serveCommand '${serveCommand}' is not an 'npm run' invocation, so --host/--port were not passed to it. Put the address in serveCommand itself.`);
|
|
251296
|
-
}
|
|
251297
|
-
const runner = createServeCommandRunner({
|
|
251298
|
-
serveCommand: command,
|
|
251299
|
-
projectRoot: project.root,
|
|
251300
|
-
appId: app.id,
|
|
251301
|
-
appBaseUrl: options.backendUrl
|
|
251302
|
-
});
|
|
251303
|
-
stopRunnerOnProcessSignals(runner);
|
|
251304
|
-
runner.onExit((code) => process.exit(code ?? 1));
|
|
251305
|
-
runner.start();
|
|
251306
|
-
return {
|
|
251307
|
-
outroMessage: `Frontend dev server running '${command}' against ${theme.styles.bold(options.backendUrl)}`
|
|
251308
|
-
};
|
|
251309
|
-
}
|
|
251310
|
-
function getSiteDevCommand() {
|
|
251311
|
-
return new Base44Command("dev", { requireAuth: false }).description("Run the site's dev server against a given backend (no local backend)").requiredOption("--backend-url <url>", "Backend the frontend should call, injected as VITE_BASE44_APP_BASE_URL").option("--host <address>", "Address to bind, e.g. 0.0.0.0").option("--port <number>", "Port to bind").action(siteDevAction);
|
|
251312
|
-
}
|
|
251313
|
-
|
|
251314
251498
|
// src/cli/commands/site/open.ts
|
|
251315
251499
|
async function openAction({
|
|
251316
251500
|
isNonInteractive
|
|
@@ -251327,7 +251511,7 @@ function getSiteOpenCommand() {
|
|
|
251327
251511
|
|
|
251328
251512
|
// src/cli/commands/site/index.ts
|
|
251329
251513
|
function getSiteCommand() {
|
|
251330
|
-
return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(
|
|
251514
|
+
return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteOpenCommand());
|
|
251331
251515
|
}
|
|
251332
251516
|
|
|
251333
251517
|
// src/core/types/generator.ts
|
|
@@ -251419,10 +251603,10 @@ function toPascalCase(name) {
|
|
|
251419
251603
|
return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
251420
251604
|
}
|
|
251421
251605
|
// src/core/types/update-project.ts
|
|
251422
|
-
import { join as
|
|
251606
|
+
import { join as join33 } from "node:path";
|
|
251423
251607
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
251424
251608
|
async function updateProjectConfig(projectRoot) {
|
|
251425
|
-
const tsconfigPath =
|
|
251609
|
+
const tsconfigPath = join33(projectRoot, "tsconfig.json");
|
|
251426
251610
|
if (!await pathExists(tsconfigPath)) {
|
|
251427
251611
|
return false;
|
|
251428
251612
|
}
|
|
@@ -251471,6 +251655,59 @@ function getTypesCommand() {
|
|
|
251471
251655
|
return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
251472
251656
|
}
|
|
251473
251657
|
|
|
251658
|
+
// src/cli/commands/versions/create.ts
|
|
251659
|
+
async function createAction2(ctx, options) {
|
|
251660
|
+
const { runTask, jsonMode } = ctx;
|
|
251661
|
+
const target = await resolveBuildTarget(requireApp(ctx).projectRoot, {
|
|
251662
|
+
outputDir: options.outputDir
|
|
251663
|
+
});
|
|
251664
|
+
const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
|
|
251665
|
+
const version = await runTask("Creating version...", async (updateMessage) => await createVersion(await collectArtifacts(target), {
|
|
251666
|
+
sourceCommit: gitHash,
|
|
251667
|
+
concurrency: options.concurrency,
|
|
251668
|
+
progress: {
|
|
251669
|
+
onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
|
|
251670
|
+
onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
|
|
251671
|
+
}
|
|
251672
|
+
}), {
|
|
251673
|
+
successMessage: "Version created",
|
|
251674
|
+
errorMessage: "Create version failed"
|
|
251675
|
+
});
|
|
251676
|
+
return {
|
|
251677
|
+
outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
|
|
251678
|
+
stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
|
|
251679
|
+
` : undefined
|
|
251680
|
+
};
|
|
251681
|
+
}
|
|
251682
|
+
function getVersionCreateCommand() {
|
|
251683
|
+
return new Base44Command("create").description("Record the built output as a version, without deploying it").addOption(outputDirOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(createAction2);
|
|
251684
|
+
}
|
|
251685
|
+
|
|
251686
|
+
// src/cli/commands/versions/deploy.ts
|
|
251687
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
251688
|
+
async function deployAction3({ runTask, jsonMode }, versionId, options) {
|
|
251689
|
+
const environment = options.target ?? DEFAULT_ENVIRONMENT;
|
|
251690
|
+
const result = await runTask(`Pointing ${environment} at ${versionId}...`, async () => await setEnvironmentVersion(environment, versionId, {
|
|
251691
|
+
idempotencyKey: randomUUID5()
|
|
251692
|
+
}), {
|
|
251693
|
+
successMessage: "Environment updated",
|
|
251694
|
+
errorMessage: "Could not update the environment"
|
|
251695
|
+
});
|
|
251696
|
+
return {
|
|
251697
|
+
outroMessage: `${result.name} now serves ${result.versionId}`,
|
|
251698
|
+
stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
|
|
251699
|
+
` : undefined
|
|
251700
|
+
};
|
|
251701
|
+
}
|
|
251702
|
+
function getVersionDeployCommand() {
|
|
251703
|
+
return new Base44Command("deploy").description("Point an environment at an already-recorded version (also the rollback)").argument("<version-id>", "The version to serve").addOption(targetOption()).action(deployAction3);
|
|
251704
|
+
}
|
|
251705
|
+
|
|
251706
|
+
// src/cli/commands/versions/index.ts
|
|
251707
|
+
function getVersionsCommand() {
|
|
251708
|
+
return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
|
|
251709
|
+
}
|
|
251710
|
+
|
|
251474
251711
|
// src/core/resources/workflow/schema.ts
|
|
251475
251712
|
var WorkflowRunStatusSchema = _enum([
|
|
251476
251713
|
"running",
|
|
@@ -251847,10 +252084,47 @@ function getWorkspaceCommand() {
|
|
|
251847
252084
|
return new Command2("workspace").description("List workspaces, inspect one, and move apps between them").addCommand(getWorkspaceListCommand()).addCommand(getWorkspaceGetCommand()).addCommand(getWorkspaceMoveCommand());
|
|
251848
252085
|
}
|
|
251849
252086
|
|
|
252087
|
+
// src/cli/dev/createDevLogger.ts
|
|
252088
|
+
var colorByType = {
|
|
252089
|
+
error: theme.styles.error,
|
|
252090
|
+
warn: theme.styles.warn,
|
|
252091
|
+
log: (input) => input
|
|
252092
|
+
};
|
|
252093
|
+
var stringify = (item) => {
|
|
252094
|
+
if (typeof item === "string") {
|
|
252095
|
+
return item;
|
|
252096
|
+
}
|
|
252097
|
+
if (item instanceof Error) {
|
|
252098
|
+
return item.toString();
|
|
252099
|
+
}
|
|
252100
|
+
try {
|
|
252101
|
+
return JSON.stringify(item, null, 2) ?? String(item);
|
|
252102
|
+
} catch {
|
|
252103
|
+
return String(item);
|
|
252104
|
+
}
|
|
252105
|
+
};
|
|
252106
|
+
function createDevLogger(label, labelColor = theme.styles.dim) {
|
|
252107
|
+
const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
|
|
252108
|
+
const print = (type, ...args) => {
|
|
252109
|
+
const colorize = colorByType[type];
|
|
252110
|
+
console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
|
|
252111
|
+
};
|
|
252112
|
+
return {
|
|
252113
|
+
log: (...args) => print("log", ...args),
|
|
252114
|
+
error: (msg, err) => {
|
|
252115
|
+
print("error", msg);
|
|
252116
|
+
if (err) {
|
|
252117
|
+
print("error", err);
|
|
252118
|
+
}
|
|
252119
|
+
},
|
|
252120
|
+
warn: (...args) => print("warn", ...args)
|
|
252121
|
+
};
|
|
252122
|
+
}
|
|
252123
|
+
|
|
251850
252124
|
// src/cli/dev/dev-server/main.ts
|
|
251851
252125
|
var import_cors = __toESM(require_lib4(), 1);
|
|
251852
252126
|
var import_express6 = __toESM(require_express(), 1);
|
|
251853
|
-
import { dirname as
|
|
252127
|
+
import { dirname as dirname27, join as join38 } from "node:path";
|
|
251854
252128
|
|
|
251855
252129
|
// ../../node_modules/get-port/index.js
|
|
251856
252130
|
import net from "node:net";
|
|
@@ -251979,8 +252253,8 @@ var $dir = async (options) => dirWithOptions(options);
|
|
|
251979
252253
|
var $tmpName = promisify11(tmp.tmpName);
|
|
251980
252254
|
|
|
251981
252255
|
// src/cli/dev/dev-server/function-manager.ts
|
|
251982
|
-
import { spawn as
|
|
251983
|
-
import { dirname as
|
|
252256
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
252257
|
+
import { dirname as dirname24, join as join34 } from "node:path";
|
|
251984
252258
|
import { pathToFileURL } from "node:url";
|
|
251985
252259
|
|
|
251986
252260
|
// src/cli/dev/dev-server/base-function-manager.ts
|
|
@@ -252077,7 +252351,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
252077
252351
|
async stopFunction(_name, { process: proc }) {
|
|
252078
252352
|
const exited = new Promise((r) => proc.once("exit", () => r()));
|
|
252079
252353
|
if (process.platform === "win32" && proc.pid) {
|
|
252080
|
-
|
|
252354
|
+
spawn2("taskkill", ["/pid", String(proc.pid), "/T", "/F"]);
|
|
252081
252355
|
} else {
|
|
252082
252356
|
proc.kill();
|
|
252083
252357
|
}
|
|
@@ -252085,8 +252359,8 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
252085
252359
|
}
|
|
252086
252360
|
spawnFunction(func, port) {
|
|
252087
252361
|
this.logger.log(`Spawning function "${func.name}" on port ${port}`);
|
|
252088
|
-
const importMapPath =
|
|
252089
|
-
const process2 =
|
|
252362
|
+
const importMapPath = join34(dirname24(this.wrapperPath), "import-map.json");
|
|
252363
|
+
const process2 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
|
|
252090
252364
|
env: {
|
|
252091
252365
|
...globalThis.process.env,
|
|
252092
252366
|
FUNCTION_PATH: pathToFileURL(func.entryPath).href,
|
|
@@ -252159,7 +252433,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
252159
252433
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
252160
252434
|
import { isBuiltin } from "node:module";
|
|
252161
252435
|
import { homedir as homedir3 } from "node:os";
|
|
252162
|
-
import { join as
|
|
252436
|
+
import { join as join35 } from "node:path";
|
|
252163
252437
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
252164
252438
|
var depsPromise;
|
|
252165
252439
|
function loadDeps() {
|
|
@@ -252280,9 +252554,9 @@ export default {
|
|
|
252280
252554
|
};
|
|
252281
252555
|
`;
|
|
252282
252556
|
function ensureBundlerConfig() {
|
|
252283
|
-
const dir =
|
|
252557
|
+
const dir = join35(homedir3(), ".base44", "function-bundler");
|
|
252284
252558
|
mkdirSync2(dir, { recursive: true });
|
|
252285
|
-
const configPath =
|
|
252559
|
+
const configPath = join35(dir, "deno.json");
|
|
252286
252560
|
writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
|
|
252287
252561
|
`);
|
|
252288
252562
|
return configPath;
|
|
@@ -253663,11 +253937,11 @@ async function createEntityRoutes(db, logger, broadcast) {
|
|
|
253663
253937
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
253664
253938
|
var import_express5 = __toESM(require_express(), 1);
|
|
253665
253939
|
var import_multer = __toESM(require_multer(), 1);
|
|
253666
|
-
import { createHash as
|
|
253940
|
+
import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
|
|
253667
253941
|
import fs28 from "node:fs";
|
|
253668
253942
|
import path18 from "node:path";
|
|
253669
253943
|
function createFileToken(fileUri) {
|
|
253670
|
-
return
|
|
253944
|
+
return createHash3("sha256").update(fileUri).digest("hex");
|
|
253671
253945
|
}
|
|
253672
253946
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
253673
253947
|
const router = import_express5.Router({ mergeParams: true });
|
|
@@ -253680,14 +253954,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
253680
253954
|
destination: mediaFilesDir,
|
|
253681
253955
|
filename: (_req, file, cb) => {
|
|
253682
253956
|
const ext = path18.extname(file.originalname);
|
|
253683
|
-
cb(null, `${
|
|
253957
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253684
253958
|
}
|
|
253685
253959
|
});
|
|
253686
253960
|
const privateStorage = import_multer.default.diskStorage({
|
|
253687
253961
|
destination: privateFilesDir,
|
|
253688
253962
|
filename: (_req, file, cb) => {
|
|
253689
253963
|
const ext = path18.extname(file.originalname);
|
|
253690
|
-
cb(null, `${
|
|
253964
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253691
253965
|
}
|
|
253692
253966
|
});
|
|
253693
253967
|
const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
|
|
@@ -255549,8 +255823,8 @@ async function createDevServer(options) {
|
|
|
255549
255823
|
broadcastEntityEvent(io, appId, entityName, event);
|
|
255550
255824
|
};
|
|
255551
255825
|
const base44ConfigWatcher = new WatchBase44({
|
|
255552
|
-
functions:
|
|
255553
|
-
entities:
|
|
255826
|
+
functions: join38(dirname27(project.configPath), project.functionsDir),
|
|
255827
|
+
entities: join38(dirname27(project.configPath), project.entitiesDir)
|
|
255554
255828
|
}, devLogger);
|
|
255555
255829
|
base44ConfigWatcher.on("change", async (name) => {
|
|
255556
255830
|
try {
|
|
@@ -255616,6 +255890,127 @@ async function createDevServer(options) {
|
|
|
255616
255890
|
return { port, server, shutdown };
|
|
255617
255891
|
}
|
|
255618
255892
|
|
|
255893
|
+
// src/cli/dev/dev-server/serve-runner.ts
|
|
255894
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
255895
|
+
import process23 from "node:process";
|
|
255896
|
+
|
|
255897
|
+
class ServeRunner {
|
|
255898
|
+
command;
|
|
255899
|
+
cwd;
|
|
255900
|
+
env;
|
|
255901
|
+
logger;
|
|
255902
|
+
child;
|
|
255903
|
+
stopping = false;
|
|
255904
|
+
stopPromise;
|
|
255905
|
+
exitListeners = [];
|
|
255906
|
+
constructor(options) {
|
|
255907
|
+
this.command = options.command;
|
|
255908
|
+
this.cwd = options.cwd;
|
|
255909
|
+
this.env = options.env;
|
|
255910
|
+
this.logger = options.logger;
|
|
255911
|
+
}
|
|
255912
|
+
start() {
|
|
255913
|
+
if (this.child) {
|
|
255914
|
+
return;
|
|
255915
|
+
}
|
|
255916
|
+
const stdin = process23.platform === "win32" ? "ignore" : "inherit";
|
|
255917
|
+
const child = spawn3(this.command, {
|
|
255918
|
+
cwd: this.cwd,
|
|
255919
|
+
shell: true,
|
|
255920
|
+
detached: process23.platform !== "win32",
|
|
255921
|
+
env: { ...process23.env, ...this.env },
|
|
255922
|
+
stdio: [stdin, "pipe", "pipe"],
|
|
255923
|
+
windowsHide: true
|
|
255924
|
+
});
|
|
255925
|
+
this.child = child;
|
|
255926
|
+
this.setupHandlers(child);
|
|
255927
|
+
}
|
|
255928
|
+
onExit(listener) {
|
|
255929
|
+
this.exitListeners.push(listener);
|
|
255930
|
+
}
|
|
255931
|
+
async stop() {
|
|
255932
|
+
if (this.stopPromise) {
|
|
255933
|
+
return this.stopPromise;
|
|
255934
|
+
}
|
|
255935
|
+
this.stopPromise = this.stopChild();
|
|
255936
|
+
return this.stopPromise;
|
|
255937
|
+
}
|
|
255938
|
+
async stopChild() {
|
|
255939
|
+
const child = this.child;
|
|
255940
|
+
if (!child || child.exitCode !== null) {
|
|
255941
|
+
return;
|
|
255942
|
+
}
|
|
255943
|
+
this.stopping = true;
|
|
255944
|
+
const exited = new Promise((resolve) => child.once("exit", () => resolve()));
|
|
255945
|
+
if (process23.platform === "win32" && child.pid) {
|
|
255946
|
+
const taskkill = spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
255947
|
+
stdio: "ignore",
|
|
255948
|
+
windowsHide: true
|
|
255949
|
+
});
|
|
255950
|
+
await new Promise((resolve) => {
|
|
255951
|
+
taskkill.once("exit", () => resolve());
|
|
255952
|
+
taskkill.once("error", () => resolve());
|
|
255953
|
+
});
|
|
255954
|
+
} else if (child.pid) {
|
|
255955
|
+
try {
|
|
255956
|
+
process23.kill(-child.pid, "SIGTERM");
|
|
255957
|
+
} catch {
|
|
255958
|
+
child.kill();
|
|
255959
|
+
}
|
|
255960
|
+
}
|
|
255961
|
+
await exited;
|
|
255962
|
+
}
|
|
255963
|
+
setupHandlers(child) {
|
|
255964
|
+
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
255965
|
+
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
255966
|
+
child.on("error", (error) => {
|
|
255967
|
+
this.logger.error("Frontend dev server failed to start:", error);
|
|
255968
|
+
this.notifyExit(null);
|
|
255969
|
+
});
|
|
255970
|
+
child.on("exit", (code) => {
|
|
255971
|
+
if (this.stopping) {
|
|
255972
|
+
return;
|
|
255973
|
+
}
|
|
255974
|
+
this.logger.error(`Frontend dev server exited with code ${code}`);
|
|
255975
|
+
this.notifyExit(code);
|
|
255976
|
+
});
|
|
255977
|
+
}
|
|
255978
|
+
notifyExit(code) {
|
|
255979
|
+
for (const listener of this.exitListeners) {
|
|
255980
|
+
listener(code);
|
|
255981
|
+
}
|
|
255982
|
+
}
|
|
255983
|
+
emitLines(data, type) {
|
|
255984
|
+
const lines = data.toString().trimEnd().split(`
|
|
255985
|
+
`);
|
|
255986
|
+
for (const line of lines) {
|
|
255987
|
+
if (type === "error") {
|
|
255988
|
+
this.logger.error(line);
|
|
255989
|
+
} else {
|
|
255990
|
+
this.logger.log(line);
|
|
255991
|
+
}
|
|
255992
|
+
}
|
|
255993
|
+
}
|
|
255994
|
+
}
|
|
255995
|
+
|
|
255996
|
+
// src/cli/dev/serve-command-runner.ts
|
|
255997
|
+
function createServeCommandRunner({
|
|
255998
|
+
serveCommand,
|
|
255999
|
+
projectRoot,
|
|
256000
|
+
appId,
|
|
256001
|
+
appBaseUrl
|
|
256002
|
+
}) {
|
|
256003
|
+
return new ServeRunner({
|
|
256004
|
+
command: serveCommand,
|
|
256005
|
+
cwd: projectRoot,
|
|
256006
|
+
env: {
|
|
256007
|
+
VITE_BASE44_APP_ID: appId,
|
|
256008
|
+
VITE_BASE44_APP_BASE_URL: appBaseUrl
|
|
256009
|
+
},
|
|
256010
|
+
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
256011
|
+
});
|
|
256012
|
+
}
|
|
256013
|
+
|
|
255619
256014
|
// src/cli/commands/dev.ts
|
|
255620
256015
|
function localServerUrl(port) {
|
|
255621
256016
|
return `http://localhost:${port}`;
|
|
@@ -255641,6 +256036,11 @@ async function resolveConfiguredSite(app) {
|
|
|
255641
256036
|
const serveCommand = project.site?.serveCommand;
|
|
255642
256037
|
return serveCommand ? { serveCommand, projectRoot: project.root } : undefined;
|
|
255643
256038
|
}
|
|
256039
|
+
function stopRunnerOnProcessSignals(runner) {
|
|
256040
|
+
const stop = () => void runner.stop();
|
|
256041
|
+
process.on("SIGINT", stop);
|
|
256042
|
+
process.on("SIGTERM", stop);
|
|
256043
|
+
}
|
|
255644
256044
|
function startServeCommand(runner, backend) {
|
|
255645
256045
|
stopRunnerOnProcessSignals(runner);
|
|
255646
256046
|
runner.onExit(() => {
|
|
@@ -255821,7 +256221,7 @@ Examples:
|
|
|
255821
256221
|
}
|
|
255822
256222
|
|
|
255823
256223
|
// src/cli/commands/project/eject.ts
|
|
255824
|
-
import { resolve as
|
|
256224
|
+
import { resolve as resolve19 } from "node:path";
|
|
255825
256225
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
255826
256226
|
async function eject(ctx, options, command) {
|
|
255827
256227
|
const { log, runTask, isNonInteractive } = ctx;
|
|
@@ -255885,7 +256285,7 @@ async function eject(ctx, options, command) {
|
|
|
255885
256285
|
Ne("Operation cancelled.");
|
|
255886
256286
|
throw new CLIExitError(0);
|
|
255887
256287
|
}
|
|
255888
|
-
const resolvedPath =
|
|
256288
|
+
const resolvedPath = resolve19(selectedPath);
|
|
255889
256289
|
await runTask("Downloading your project's code...", async (updateMessage) => {
|
|
255890
256290
|
await createProjectFilesForExistingProject({
|
|
255891
256291
|
projectId,
|
|
@@ -255903,17 +256303,22 @@ async function eject(ctx, options, command) {
|
|
|
255903
256303
|
errorMessage: "Failed to pull project"
|
|
255904
256304
|
});
|
|
255905
256305
|
const { project } = await readProjectConfig(resolvedPath);
|
|
255906
|
-
const
|
|
255907
|
-
|
|
255908
|
-
if (installCommand && buildCommand) {
|
|
256306
|
+
const site = project.site;
|
|
256307
|
+
if (site) {
|
|
255909
256308
|
const shouldDeploy = options.yes ? true : await Re({
|
|
255910
256309
|
message: "Would you like to deploy your project now?"
|
|
255911
256310
|
});
|
|
255912
256311
|
if (!Ct(shouldDeploy) && shouldDeploy) {
|
|
255913
256312
|
await runTask("Installing dependencies...", async (updateMessage) => {
|
|
255914
|
-
await execa({
|
|
256313
|
+
await execa({
|
|
256314
|
+
cwd: resolvedPath,
|
|
256315
|
+
shell: true
|
|
256316
|
+
})`${site.installCommand}`;
|
|
255915
256317
|
updateMessage("Building project...");
|
|
255916
|
-
await execa({
|
|
256318
|
+
await execa({
|
|
256319
|
+
cwd: resolvedPath,
|
|
256320
|
+
shell: true
|
|
256321
|
+
})`${site.buildCommand}`;
|
|
255917
256322
|
}, {
|
|
255918
256323
|
successMessage: theme.colors.base44Orange("Project built successfully"),
|
|
255919
256324
|
errorMessage: "Failed to build project"
|
|
@@ -255951,7 +256356,6 @@ function createProgram(context) {
|
|
|
255951
256356
|
program.addCommand(getCreateCommand());
|
|
255952
256357
|
program.addCommand(getScaffoldCommand());
|
|
255953
256358
|
program.addCommand(getDashboardCommand());
|
|
255954
|
-
program.addCommand(getInstallCommand());
|
|
255955
256359
|
program.addCommand(getBuildCommand());
|
|
255956
256360
|
program.addCommand(getDeployCommand3());
|
|
255957
256361
|
program.addCommand(getVisibilityCommand());
|
|
@@ -255970,6 +256374,10 @@ function createProgram(context) {
|
|
|
255970
256374
|
program.addCommand(getBranchesCommand());
|
|
255971
256375
|
program.addCommand(getAuthCommand());
|
|
255972
256376
|
program.addCommand(getSiteCommand());
|
|
256377
|
+
if (versionsApiEnabled()) {
|
|
256378
|
+
program.addCommand(getPublishCommand());
|
|
256379
|
+
program.addCommand(getVersionsCommand());
|
|
256380
|
+
}
|
|
255973
256381
|
program.addCommand(getTypesCommand());
|
|
255974
256382
|
program.addCommand(getExecCommand());
|
|
255975
256383
|
program.addCommand(getDevCommand());
|
|
@@ -255982,7 +256390,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
255982
256390
|
import { release, type } from "node:os";
|
|
255983
256391
|
|
|
255984
256392
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
255985
|
-
import { dirname as
|
|
256393
|
+
import { dirname as dirname28, posix, sep as sep2 } from "path";
|
|
255986
256394
|
function createModulerModifier() {
|
|
255987
256395
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
255988
256396
|
return async (frames) => {
|
|
@@ -255991,7 +256399,7 @@ function createModulerModifier() {
|
|
|
255991
256399
|
return frames;
|
|
255992
256400
|
};
|
|
255993
256401
|
}
|
|
255994
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
256402
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname28(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
|
|
255995
256403
|
const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
|
|
255996
256404
|
return (filename) => {
|
|
255997
256405
|
if (!filename)
|
|
@@ -259980,9 +260388,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
|
|
|
259980
260388
|
});
|
|
259981
260389
|
}
|
|
259982
260390
|
// src/cli/index.ts
|
|
259983
|
-
var __dirname4 =
|
|
260391
|
+
var __dirname4 = dirname29(fileURLToPath6(import.meta.url));
|
|
259984
260392
|
async function runCLI(options) {
|
|
259985
|
-
ensureNpmAssets(
|
|
260393
|
+
ensureNpmAssets(join39(__dirname4, "../assets"));
|
|
259986
260394
|
const errorReporter = new ErrorReporter;
|
|
259987
260395
|
errorReporter.registerProcessErrorHandlers();
|
|
259988
260396
|
const jsonMode = process.argv.includes("--json");
|
|
@@ -260021,4 +260429,4 @@ export {
|
|
|
260021
260429
|
runCLI
|
|
260022
260430
|
};
|
|
260023
260431
|
|
|
260024
|
-
//# debugId=
|
|
260432
|
+
//# debugId=53FA3E8A10325F7E64756E2164756E21
|