@base44-preview/cli 0.1.15-pr.632.1a53729 → 0.1.16-pr.626.47e8953
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 +722 -248
- package/dist/cli/index.js.map +26 -14
- 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,
|
|
@@ -228657,6 +228657,20 @@ function isCLIError(error) {
|
|
|
228657
228657
|
function isUserError(error) {
|
|
228658
228658
|
return error instanceof UserError;
|
|
228659
228659
|
}
|
|
228660
|
+
var STEP = Symbol.for("base44.commandStep");
|
|
228661
|
+
async function tagStep(step, run) {
|
|
228662
|
+
try {
|
|
228663
|
+
return await run();
|
|
228664
|
+
} catch (error) {
|
|
228665
|
+
if (error !== null && typeof error === "object" && !(STEP in error) && Object.isExtensible(error)) {
|
|
228666
|
+
Object.defineProperty(error, STEP, { value: step, enumerable: false });
|
|
228667
|
+
}
|
|
228668
|
+
throw error;
|
|
228669
|
+
}
|
|
228670
|
+
}
|
|
228671
|
+
function stepOf(error) {
|
|
228672
|
+
return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
|
|
228673
|
+
}
|
|
228660
228674
|
|
|
228661
228675
|
// src/core/utils/fs.ts
|
|
228662
228676
|
async function pathExists(path) {
|
|
@@ -228783,7 +228797,7 @@ function normalizeBase44Env() {
|
|
|
228783
228797
|
loadProjectEnvFiles();
|
|
228784
228798
|
|
|
228785
228799
|
// src/cli/index.ts
|
|
228786
|
-
import { dirname as
|
|
228800
|
+
import { dirname as dirname29, join as join39 } from "node:path";
|
|
228787
228801
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
228788
228802
|
|
|
228789
228803
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -239236,7 +239250,7 @@ import { join as join13 } from "node:path";
|
|
|
239236
239250
|
// package.json
|
|
239237
239251
|
var package_default = {
|
|
239238
239252
|
name: "base44",
|
|
239239
|
-
version: "0.1.
|
|
239253
|
+
version: "0.1.16",
|
|
239240
239254
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
239241
239255
|
type: "module",
|
|
239242
239256
|
bin: {
|
|
@@ -239590,91 +239604,8 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
239590
239604
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
239591
239605
|
import { join as join18 } from "node:path";
|
|
239592
239606
|
|
|
239593
|
-
// src/core/site/manifest.ts
|
|
239594
|
-
import { createHash } from "node:crypto";
|
|
239595
|
-
import { createReadStream } from "node:fs";
|
|
239596
|
-
import { stat } from "node:fs/promises";
|
|
239597
|
-
import { basename as basename5, extname, join as join16 } from "node:path";
|
|
239598
|
-
var MAX_ASSET_COUNT = 1e5;
|
|
239599
|
-
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
239600
|
-
var ALWAYS_IGNORED = new Set([
|
|
239601
|
-
ASSETS_IGNORE_FILE,
|
|
239602
|
-
"wrangler.json",
|
|
239603
|
-
".dev.vars"
|
|
239604
|
-
]);
|
|
239605
|
-
var MIME_TYPES = {
|
|
239606
|
-
".html": "text/html",
|
|
239607
|
-
".htm": "text/html",
|
|
239608
|
-
".css": "text/css",
|
|
239609
|
-
".js": "text/javascript",
|
|
239610
|
-
".mjs": "text/javascript",
|
|
239611
|
-
".json": "application/json",
|
|
239612
|
-
".map": "application/json",
|
|
239613
|
-
".txt": "text/plain",
|
|
239614
|
-
".xml": "application/xml",
|
|
239615
|
-
".svg": "image/svg+xml",
|
|
239616
|
-
".png": "image/png",
|
|
239617
|
-
".jpg": "image/jpeg",
|
|
239618
|
-
".jpeg": "image/jpeg",
|
|
239619
|
-
".gif": "image/gif",
|
|
239620
|
-
".webp": "image/webp",
|
|
239621
|
-
".avif": "image/avif",
|
|
239622
|
-
".ico": "image/x-icon",
|
|
239623
|
-
".woff": "font/woff",
|
|
239624
|
-
".woff2": "font/woff2",
|
|
239625
|
-
".ttf": "font/ttf",
|
|
239626
|
-
".otf": "font/otf",
|
|
239627
|
-
".eot": "application/vnd.ms-fontobject",
|
|
239628
|
-
".mp3": "audio/mpeg",
|
|
239629
|
-
".mp4": "video/mp4",
|
|
239630
|
-
".webm": "video/webm",
|
|
239631
|
-
".pdf": "application/pdf",
|
|
239632
|
-
".wasm": "application/wasm",
|
|
239633
|
-
".webmanifest": "application/manifest+json"
|
|
239634
|
-
};
|
|
239635
|
-
function getAssetContentType(filePath) {
|
|
239636
|
-
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
239637
|
-
}
|
|
239638
|
-
async function hashAssetFile(appId, absolutePath) {
|
|
239639
|
-
const hash = createHash("sha256").update(Buffer.from(appId, "utf8"));
|
|
239640
|
-
for await (const chunk of createReadStream(absolutePath)) {
|
|
239641
|
-
hash.update(chunk);
|
|
239642
|
-
}
|
|
239643
|
-
return hash.digest("hex").slice(0, 32);
|
|
239644
|
-
}
|
|
239645
|
-
async function buildAssetManifest(assetsDir, appId) {
|
|
239646
|
-
const manifest = {};
|
|
239647
|
-
const filesByHash = new Map;
|
|
239648
|
-
const found = await globby("**/*", {
|
|
239649
|
-
cwd: assetsDir,
|
|
239650
|
-
dot: true,
|
|
239651
|
-
onlyFiles: true,
|
|
239652
|
-
followSymbolicLinks: false,
|
|
239653
|
-
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
239654
|
-
});
|
|
239655
|
-
const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
|
|
239656
|
-
if (relativeFilePaths.length > MAX_ASSET_COUNT) {
|
|
239657
|
-
throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
239658
|
-
}
|
|
239659
|
-
for (const relativePath of relativeFilePaths.sort()) {
|
|
239660
|
-
const absolutePath = join16(assetsDir, ...relativePath.split("/"));
|
|
239661
|
-
const { size } = await stat(absolutePath);
|
|
239662
|
-
const hash = await hashAssetFile(appId, absolutePath);
|
|
239663
|
-
manifest[`/${relativePath}`] = { hash, size };
|
|
239664
|
-
if (!filesByHash.has(hash)) {
|
|
239665
|
-
filesByHash.set(hash, {
|
|
239666
|
-
absolutePath,
|
|
239667
|
-
hash,
|
|
239668
|
-
size,
|
|
239669
|
-
contentType: getAssetContentType(absolutePath)
|
|
239670
|
-
});
|
|
239671
|
-
}
|
|
239672
|
-
}
|
|
239673
|
-
return { manifest, filesByHash };
|
|
239674
|
-
}
|
|
239675
|
-
|
|
239676
239607
|
// src/core/site/modules.ts
|
|
239677
|
-
import { stat
|
|
239608
|
+
import { stat } from "node:fs/promises";
|
|
239678
239609
|
import { relative as relative5, resolve as resolve3, sep } from "node:path";
|
|
239679
239610
|
var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
|
|
239680
239611
|
var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
|
|
@@ -239749,7 +239680,7 @@ async function collectModules(config) {
|
|
|
239749
239680
|
const modules = [...modulesByName.values()];
|
|
239750
239681
|
let totalBytes = 0;
|
|
239751
239682
|
for (const module of modules) {
|
|
239752
|
-
module.size = (await
|
|
239683
|
+
module.size = (await stat(module.absolutePath)).size;
|
|
239753
239684
|
totalBytes += module.size;
|
|
239754
239685
|
}
|
|
239755
239686
|
if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
|
|
@@ -239768,8 +239699,104 @@ function addSourcemap(modulesByName, configDir, name) {
|
|
|
239768
239699
|
});
|
|
239769
239700
|
}
|
|
239770
239701
|
|
|
239771
|
-
// src/core/site/
|
|
239772
|
-
import {
|
|
239702
|
+
// src/core/site/wrangler-config.ts
|
|
239703
|
+
import { dirname as dirname12, join as join16, resolve as resolve4 } from "node:path";
|
|
239704
|
+
var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
|
|
239705
|
+
var RedirectConfigSchema = looseObject({
|
|
239706
|
+
configPath: string2().min(1)
|
|
239707
|
+
});
|
|
239708
|
+
var WranglerConfigSchema = looseObject({
|
|
239709
|
+
main: string2().min(1, "wrangler config is missing a 'main' entry module"),
|
|
239710
|
+
no_bundle: boolean2().optional(),
|
|
239711
|
+
rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
|
|
239712
|
+
assets: looseObject({
|
|
239713
|
+
directory: string2().optional(),
|
|
239714
|
+
html_handling: string2().optional(),
|
|
239715
|
+
not_found_handling: string2().optional(),
|
|
239716
|
+
run_worker_first: union([boolean2(), array(string2())]).optional(),
|
|
239717
|
+
headers: string2().optional(),
|
|
239718
|
+
redirects: string2().optional()
|
|
239719
|
+
}).optional(),
|
|
239720
|
+
compatibility_date: string2().optional(),
|
|
239721
|
+
compatibility_flags: array(string2()).optional(),
|
|
239722
|
+
vars: record(string2(), unknown()).optional(),
|
|
239723
|
+
upload_source_maps: boolean2().optional()
|
|
239724
|
+
});
|
|
239725
|
+
async function detectFullStackArtifact(projectRoot) {
|
|
239726
|
+
const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
|
|
239727
|
+
return await pathExists(redirectPath) ? redirectPath : null;
|
|
239728
|
+
}
|
|
239729
|
+
async function resolveWranglerConfig(redirectPath) {
|
|
239730
|
+
const configPath = await resolveRedirectedConfigPath(redirectPath);
|
|
239731
|
+
const parsed = await readJsonFile(configPath);
|
|
239732
|
+
const result = WranglerConfigSchema.safeParse(parsed);
|
|
239733
|
+
if (!result.success) {
|
|
239734
|
+
throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
|
|
239735
|
+
}
|
|
239736
|
+
const config = result.data;
|
|
239737
|
+
if (config.no_bundle !== true) {
|
|
239738
|
+
throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
|
|
239739
|
+
}
|
|
239740
|
+
const configDir = dirname12(configPath);
|
|
239741
|
+
const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
|
|
239742
|
+
return {
|
|
239743
|
+
configPath,
|
|
239744
|
+
configDir,
|
|
239745
|
+
main: config.main,
|
|
239746
|
+
assetsDirectory,
|
|
239747
|
+
assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
|
|
239748
|
+
compatibilityDate: config.compatibility_date ?? null,
|
|
239749
|
+
compatibilityFlags: config.compatibility_flags ?? [],
|
|
239750
|
+
rules: (config.rules ?? []).map((rule) => ({
|
|
239751
|
+
type: rule.type,
|
|
239752
|
+
globs: rule.globs
|
|
239753
|
+
})),
|
|
239754
|
+
uploadSourceMaps: config.upload_source_maps ?? false
|
|
239755
|
+
};
|
|
239756
|
+
}
|
|
239757
|
+
async function resolveRedirectedConfigPath(redirectPath) {
|
|
239758
|
+
const parsed = await readJsonFile(redirectPath);
|
|
239759
|
+
const result = RedirectConfigSchema.safeParse(parsed);
|
|
239760
|
+
if (!result.success) {
|
|
239761
|
+
throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
|
|
239762
|
+
}
|
|
239763
|
+
const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
|
|
239764
|
+
if (!await pathExists(configPath)) {
|
|
239765
|
+
throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
|
|
239766
|
+
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
239767
|
+
});
|
|
239768
|
+
}
|
|
239769
|
+
return configPath;
|
|
239770
|
+
}
|
|
239771
|
+
function toResolvedAssetsConfig(assets) {
|
|
239772
|
+
return {
|
|
239773
|
+
htmlHandling: assets.html_handling,
|
|
239774
|
+
notFoundHandling: assets.not_found_handling,
|
|
239775
|
+
runWorkerFirst: assets.run_worker_first,
|
|
239776
|
+
headers: assets.headers,
|
|
239777
|
+
redirects: assets.redirects
|
|
239778
|
+
};
|
|
239779
|
+
}
|
|
239780
|
+
|
|
239781
|
+
// src/core/site/full-stack.ts
|
|
239782
|
+
async function resolveFullStackBuild(projectRoot) {
|
|
239783
|
+
const redirectPath = await detectFullStackArtifact(projectRoot);
|
|
239784
|
+
if (!redirectPath) {
|
|
239785
|
+
return null;
|
|
239786
|
+
}
|
|
239787
|
+
const config = await resolveWranglerConfig(redirectPath);
|
|
239788
|
+
return {
|
|
239789
|
+
config,
|
|
239790
|
+
modules: await collectModules(config),
|
|
239791
|
+
assetsDir: config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null
|
|
239792
|
+
};
|
|
239793
|
+
}
|
|
239794
|
+
|
|
239795
|
+
// src/core/site/manifest.ts
|
|
239796
|
+
import { createHash } from "node:crypto";
|
|
239797
|
+
import { createReadStream } from "node:fs";
|
|
239798
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
239799
|
+
import { basename as basename5, extname, join as join17 } from "node:path";
|
|
239773
239800
|
|
|
239774
239801
|
// ../../node_modules/p-map/index.js
|
|
239775
239802
|
async function pMap(iterable, mapper, {
|
|
@@ -239895,7 +239922,99 @@ async function pMap(iterable, mapper, {
|
|
|
239895
239922
|
}
|
|
239896
239923
|
var pMapSkip = Symbol("skip");
|
|
239897
239924
|
|
|
239925
|
+
// src/core/site/manifest.ts
|
|
239926
|
+
var MAX_ASSET_COUNT = 1e5;
|
|
239927
|
+
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
239928
|
+
var ALWAYS_IGNORED = new Set([
|
|
239929
|
+
ASSETS_IGNORE_FILE,
|
|
239930
|
+
"wrangler.json",
|
|
239931
|
+
".dev.vars"
|
|
239932
|
+
]);
|
|
239933
|
+
var MIME_TYPES = {
|
|
239934
|
+
".html": "text/html",
|
|
239935
|
+
".htm": "text/html",
|
|
239936
|
+
".css": "text/css",
|
|
239937
|
+
".js": "text/javascript",
|
|
239938
|
+
".mjs": "text/javascript",
|
|
239939
|
+
".json": "application/json",
|
|
239940
|
+
".map": "application/json",
|
|
239941
|
+
".txt": "text/plain",
|
|
239942
|
+
".xml": "application/xml",
|
|
239943
|
+
".svg": "image/svg+xml",
|
|
239944
|
+
".png": "image/png",
|
|
239945
|
+
".jpg": "image/jpeg",
|
|
239946
|
+
".jpeg": "image/jpeg",
|
|
239947
|
+
".gif": "image/gif",
|
|
239948
|
+
".webp": "image/webp",
|
|
239949
|
+
".avif": "image/avif",
|
|
239950
|
+
".ico": "image/x-icon",
|
|
239951
|
+
".woff": "font/woff",
|
|
239952
|
+
".woff2": "font/woff2",
|
|
239953
|
+
".ttf": "font/ttf",
|
|
239954
|
+
".otf": "font/otf",
|
|
239955
|
+
".eot": "application/vnd.ms-fontobject",
|
|
239956
|
+
".mp3": "audio/mpeg",
|
|
239957
|
+
".mp4": "video/mp4",
|
|
239958
|
+
".webm": "video/webm",
|
|
239959
|
+
".pdf": "application/pdf",
|
|
239960
|
+
".wasm": "application/wasm",
|
|
239961
|
+
".webmanifest": "application/manifest+json"
|
|
239962
|
+
};
|
|
239963
|
+
function getAssetContentType(filePath) {
|
|
239964
|
+
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
239965
|
+
}
|
|
239966
|
+
async function walkBuildOutput(outputDir) {
|
|
239967
|
+
const found = await globby("**/*", {
|
|
239968
|
+
cwd: outputDir,
|
|
239969
|
+
dot: true,
|
|
239970
|
+
onlyFiles: true,
|
|
239971
|
+
followSymbolicLinks: false,
|
|
239972
|
+
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
239973
|
+
});
|
|
239974
|
+
return found.filter((path) => !ALWAYS_IGNORED.has(basename5(path))).sort();
|
|
239975
|
+
}
|
|
239976
|
+
var STAT_CONCURRENCY = 32;
|
|
239977
|
+
async function describeBuildOutput(outputDir) {
|
|
239978
|
+
const relativePaths = await walkBuildOutput(outputDir);
|
|
239979
|
+
return await pMap(relativePaths, async (path) => {
|
|
239980
|
+
const absolutePath = join17(outputDir, ...path.split("/"));
|
|
239981
|
+
return { path, absolutePath, size: (await stat2(absolutePath)).size };
|
|
239982
|
+
}, { concurrency: STAT_CONCURRENCY });
|
|
239983
|
+
}
|
|
239984
|
+
async function hashFileInto(hash, absolutePath) {
|
|
239985
|
+
for await (const chunk of createReadStream(absolutePath)) {
|
|
239986
|
+
hash.update(chunk);
|
|
239987
|
+
}
|
|
239988
|
+
return hash;
|
|
239989
|
+
}
|
|
239990
|
+
async function hashAssetFile(appId, absolutePath) {
|
|
239991
|
+
const hash = await hashFileInto(createHash("sha256").update(Buffer.from(appId, "utf8")), absolutePath);
|
|
239992
|
+
return hash.digest("hex").slice(0, 32);
|
|
239993
|
+
}
|
|
239994
|
+
async function buildAssetManifest(assetsDir, appId) {
|
|
239995
|
+
const manifest = {};
|
|
239996
|
+
const filesByHash = new Map;
|
|
239997
|
+
const files = await describeBuildOutput(assetsDir);
|
|
239998
|
+
if (files.length > MAX_ASSET_COUNT) {
|
|
239999
|
+
throw new InvalidInputError(`Too many static assets: found ${files.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
240000
|
+
}
|
|
240001
|
+
for (const { path: relativePath, absolutePath, size } of files) {
|
|
240002
|
+
const hash = await hashAssetFile(appId, absolutePath);
|
|
240003
|
+
manifest[`/${relativePath}`] = { hash, size };
|
|
240004
|
+
if (!filesByHash.has(hash)) {
|
|
240005
|
+
filesByHash.set(hash, {
|
|
240006
|
+
absolutePath,
|
|
240007
|
+
hash,
|
|
240008
|
+
size,
|
|
240009
|
+
contentType: getAssetContentType(absolutePath)
|
|
240010
|
+
});
|
|
240011
|
+
}
|
|
240012
|
+
}
|
|
240013
|
+
return { manifest, filesByHash };
|
|
240014
|
+
}
|
|
240015
|
+
|
|
239898
240016
|
// src/core/site/upload.ts
|
|
240017
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
239899
240018
|
var DEFAULT_UPLOAD_CONCURRENCY = 3;
|
|
239900
240019
|
var MAX_UPLOAD_CONCURRENCY = 50;
|
|
239901
240020
|
var MAX_UPLOAD_ATTEMPTS = 3;
|
|
@@ -239994,11 +240113,17 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
239994
240113
|
if (!file) {
|
|
239995
240114
|
throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
|
|
239996
240115
|
}
|
|
239997
|
-
|
|
240116
|
+
await putPresigned(upload, file.absolutePath);
|
|
240117
|
+
}
|
|
240118
|
+
async function putPresigned(upload, absolutePath) {
|
|
240119
|
+
const content = await readFile2(absolutePath);
|
|
239998
240120
|
try {
|
|
239999
240121
|
await distribution_default.put(upload.url, {
|
|
240000
240122
|
body: new Uint8Array(content),
|
|
240001
|
-
headers: {
|
|
240123
|
+
headers: {
|
|
240124
|
+
"Content-Type": upload.contentType,
|
|
240125
|
+
...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
|
|
240126
|
+
},
|
|
240002
240127
|
timeout: 120000,
|
|
240003
240128
|
retry: UPLOAD_RETRY
|
|
240004
240129
|
});
|
|
@@ -240007,85 +240132,6 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
240007
240132
|
}
|
|
240008
240133
|
}
|
|
240009
240134
|
|
|
240010
|
-
// src/core/site/wrangler-config.ts
|
|
240011
|
-
import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
|
|
240012
|
-
var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
|
|
240013
|
-
var RedirectConfigSchema = looseObject({
|
|
240014
|
-
configPath: string2().min(1)
|
|
240015
|
-
});
|
|
240016
|
-
var WranglerConfigSchema = looseObject({
|
|
240017
|
-
main: string2().min(1, "wrangler config is missing a 'main' entry module"),
|
|
240018
|
-
no_bundle: boolean2().optional(),
|
|
240019
|
-
rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
|
|
240020
|
-
assets: looseObject({
|
|
240021
|
-
directory: string2().optional(),
|
|
240022
|
-
html_handling: string2().optional(),
|
|
240023
|
-
not_found_handling: string2().optional(),
|
|
240024
|
-
run_worker_first: union([boolean2(), array(string2())]).optional(),
|
|
240025
|
-
headers: string2().optional(),
|
|
240026
|
-
redirects: string2().optional()
|
|
240027
|
-
}).optional(),
|
|
240028
|
-
compatibility_date: string2().optional(),
|
|
240029
|
-
compatibility_flags: array(string2()).optional(),
|
|
240030
|
-
vars: record(string2(), unknown()).optional(),
|
|
240031
|
-
upload_source_maps: boolean2().optional()
|
|
240032
|
-
});
|
|
240033
|
-
async function detectFullStackArtifact(projectRoot) {
|
|
240034
|
-
const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
|
|
240035
|
-
return await pathExists(redirectPath) ? redirectPath : null;
|
|
240036
|
-
}
|
|
240037
|
-
async function resolveWranglerConfig(redirectPath) {
|
|
240038
|
-
const configPath = await resolveRedirectedConfigPath(redirectPath);
|
|
240039
|
-
const parsed = await readJsonFile(configPath);
|
|
240040
|
-
const result = WranglerConfigSchema.safeParse(parsed);
|
|
240041
|
-
if (!result.success) {
|
|
240042
|
-
throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
|
|
240043
|
-
}
|
|
240044
|
-
const config = result.data;
|
|
240045
|
-
if (config.no_bundle !== true) {
|
|
240046
|
-
throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
|
|
240047
|
-
}
|
|
240048
|
-
const configDir = dirname12(configPath);
|
|
240049
|
-
const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
|
|
240050
|
-
return {
|
|
240051
|
-
configPath,
|
|
240052
|
-
configDir,
|
|
240053
|
-
main: config.main,
|
|
240054
|
-
assetsDirectory,
|
|
240055
|
-
assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
|
|
240056
|
-
compatibilityDate: config.compatibility_date ?? null,
|
|
240057
|
-
compatibilityFlags: config.compatibility_flags ?? [],
|
|
240058
|
-
rules: (config.rules ?? []).map((rule) => ({
|
|
240059
|
-
type: rule.type,
|
|
240060
|
-
globs: rule.globs
|
|
240061
|
-
})),
|
|
240062
|
-
uploadSourceMaps: config.upload_source_maps ?? false
|
|
240063
|
-
};
|
|
240064
|
-
}
|
|
240065
|
-
async function resolveRedirectedConfigPath(redirectPath) {
|
|
240066
|
-
const parsed = await readJsonFile(redirectPath);
|
|
240067
|
-
const result = RedirectConfigSchema.safeParse(parsed);
|
|
240068
|
-
if (!result.success) {
|
|
240069
|
-
throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
|
|
240070
|
-
}
|
|
240071
|
-
const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
|
|
240072
|
-
if (!await pathExists(configPath)) {
|
|
240073
|
-
throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
|
|
240074
|
-
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
240075
|
-
});
|
|
240076
|
-
}
|
|
240077
|
-
return configPath;
|
|
240078
|
-
}
|
|
240079
|
-
function toResolvedAssetsConfig(assets) {
|
|
240080
|
-
return {
|
|
240081
|
-
htmlHandling: assets.html_handling,
|
|
240082
|
-
notFoundHandling: assets.not_found_handling,
|
|
240083
|
-
runWorkerFirst: assets.run_worker_first,
|
|
240084
|
-
headers: assets.headers,
|
|
240085
|
-
redirects: assets.redirects
|
|
240086
|
-
};
|
|
240087
|
-
}
|
|
240088
|
-
|
|
240089
240135
|
// src/core/site/deployment.ts
|
|
240090
240136
|
var NO_ASSETS = { manifest: {}, filesByHash: new Map };
|
|
240091
240137
|
var DEPLOYMENTS_API_ENV = "BASE44_DEPLOYMENTS_API";
|
|
@@ -240112,12 +240158,11 @@ async function deployToDeployments(options) {
|
|
|
240112
240158
|
return { deploymentId: finalized.deploymentId, gitHash };
|
|
240113
240159
|
}
|
|
240114
240160
|
async function resolveWorkerBuild(projectRoot, progress) {
|
|
240115
|
-
const
|
|
240116
|
-
if (!
|
|
240161
|
+
const built = await resolveFullStackBuild(projectRoot);
|
|
240162
|
+
if (!built) {
|
|
240117
240163
|
return null;
|
|
240118
240164
|
}
|
|
240119
|
-
const config =
|
|
240120
|
-
const assetsDir = config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null;
|
|
240165
|
+
const { config, modules, assetsDir } = built;
|
|
240121
240166
|
return {
|
|
240122
240167
|
config: {
|
|
240123
240168
|
main: config.main,
|
|
@@ -240125,7 +240170,7 @@ async function resolveWorkerBuild(projectRoot, progress) {
|
|
|
240125
240170
|
compatibility_flags: config.compatibilityFlags,
|
|
240126
240171
|
assets: buildAssetsConfig(config.assetsConfig, progress)
|
|
240127
240172
|
},
|
|
240128
|
-
modules
|
|
240173
|
+
modules,
|
|
240129
240174
|
assetsDir
|
|
240130
240175
|
};
|
|
240131
240176
|
}
|
|
@@ -246669,6 +246714,13 @@ async function resolveGitHash(projectRoot, explicit) {
|
|
|
246669
246714
|
}
|
|
246670
246715
|
return hash;
|
|
246671
246716
|
}
|
|
246717
|
+
async function resolveProvenanceCommit(projectRoot, explicit) {
|
|
246718
|
+
if (explicit) {
|
|
246719
|
+
return await resolveGitHash(projectRoot, explicit);
|
|
246720
|
+
}
|
|
246721
|
+
const hash = await gitHead(projectRoot);
|
|
246722
|
+
return hash && isGitCommitHash(hash) ? hash : undefined;
|
|
246723
|
+
}
|
|
246672
246724
|
async function gitHead(projectRoot) {
|
|
246673
246725
|
try {
|
|
246674
246726
|
const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
|
|
@@ -246757,6 +246809,49 @@ async function deployAll(projectData, options) {
|
|
|
246757
246809
|
}
|
|
246758
246810
|
return { connectorResults };
|
|
246759
246811
|
}
|
|
246812
|
+
// src/core/project/target.ts
|
|
246813
|
+
import { dirname as dirname13, join as join19, resolve as resolve6 } from "node:path";
|
|
246814
|
+
var DEFAULT_BUILD_COMMAND = "npm run build";
|
|
246815
|
+
var DEFAULT_OUTPUT_DIRECTORY = "dist";
|
|
246816
|
+
async function resolveBuildTarget(projectRoot, overrides = {}) {
|
|
246817
|
+
const project = await readSettingsIfPresent(projectRoot);
|
|
246818
|
+
const root = project?.root ?? projectRoot ?? process.cwd();
|
|
246819
|
+
return {
|
|
246820
|
+
root,
|
|
246821
|
+
configDir: project ? dirname13(project.configPath) : join19(root, PROJECT_SUBDIR),
|
|
246822
|
+
buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
|
|
246823
|
+
outputDir: outputDirectory(project, root, overrides.outputDir),
|
|
246824
|
+
entitiesDir: project?.entitiesDir ?? "entities",
|
|
246825
|
+
agentsDir: project?.agentsDir ?? "agents"
|
|
246826
|
+
};
|
|
246827
|
+
}
|
|
246828
|
+
function outputDirectory(project, root, override) {
|
|
246829
|
+
const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
|
|
246830
|
+
return configured ? resolve6(root, configured) : null;
|
|
246831
|
+
}
|
|
246832
|
+
function requireOutputDir(target) {
|
|
246833
|
+
if (target.outputDir === null) {
|
|
246834
|
+
throw new ConfigNotFoundError("No site configuration found.", {
|
|
246835
|
+
hints: [
|
|
246836
|
+
{
|
|
246837
|
+
message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
|
|
246838
|
+
},
|
|
246839
|
+
{ message: `Or pass --output-dir <dir>, relative to ${target.root}` }
|
|
246840
|
+
]
|
|
246841
|
+
});
|
|
246842
|
+
}
|
|
246843
|
+
return target.outputDir;
|
|
246844
|
+
}
|
|
246845
|
+
async function readSettingsIfPresent(projectRoot) {
|
|
246846
|
+
try {
|
|
246847
|
+
return await readProjectSettings(projectRoot);
|
|
246848
|
+
} catch (error) {
|
|
246849
|
+
if (error instanceof ConfigNotFoundError) {
|
|
246850
|
+
return null;
|
|
246851
|
+
}
|
|
246852
|
+
throw error;
|
|
246853
|
+
}
|
|
246854
|
+
}
|
|
246760
246855
|
// src/core/clients/base44-client.ts
|
|
246761
246856
|
var retriedRequests = new WeakSet;
|
|
246762
246857
|
async function captureRequestBody(request, options) {
|
|
@@ -247038,6 +247133,12 @@ async function ensureAppContext(ctx, options = {}) {
|
|
|
247038
247133
|
ctx.app = appContext;
|
|
247039
247134
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
247040
247135
|
}
|
|
247136
|
+
function requireApp(ctx) {
|
|
247137
|
+
if (!ctx.app) {
|
|
247138
|
+
throw new InternalError("This command read an app context it never resolved — it is declared with requireAppContext: false.");
|
|
247139
|
+
}
|
|
247140
|
+
return ctx.app;
|
|
247141
|
+
}
|
|
247041
247142
|
|
|
247042
247143
|
// src/cli/utils/version-check.ts
|
|
247043
247144
|
async function checkForUpgrade() {
|
|
@@ -247221,6 +247322,10 @@ function writeJsonError(error) {
|
|
|
247221
247322
|
const envelope = {
|
|
247222
247323
|
error: error instanceof Error ? error.message : String(error)
|
|
247223
247324
|
};
|
|
247325
|
+
const step = stepOf(error);
|
|
247326
|
+
if (step !== undefined) {
|
|
247327
|
+
envelope.step = step;
|
|
247328
|
+
}
|
|
247224
247329
|
if (isCLIError(error)) {
|
|
247225
247330
|
envelope.code = error.code;
|
|
247226
247331
|
if (error.details.length > 0) {
|
|
@@ -247590,7 +247695,7 @@ function getActorsCommand() {
|
|
|
247590
247695
|
}
|
|
247591
247696
|
|
|
247592
247697
|
// src/cli/commands/agent-skills/pull.ts
|
|
247593
|
-
import { dirname as
|
|
247698
|
+
import { dirname as dirname14, join as join20 } from "node:path";
|
|
247594
247699
|
// src/core/utils/dependencies.ts
|
|
247595
247700
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
247596
247701
|
function verifyDenoInstalled(context) {
|
|
@@ -247679,7 +247784,7 @@ async function pullAction({
|
|
|
247679
247784
|
runTask
|
|
247680
247785
|
}) {
|
|
247681
247786
|
const { project } = await readProjectConfig();
|
|
247682
|
-
const dir =
|
|
247787
|
+
const dir = join20(dirname14(project.configPath), project.agentSkillsDir);
|
|
247683
247788
|
const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
|
|
247684
247789
|
successMessage: "Agent skills fetched successfully",
|
|
247685
247790
|
errorMessage: "Failed to fetch agent skills"
|
|
@@ -247735,14 +247840,14 @@ function getAgentSkillsCommand() {
|
|
|
247735
247840
|
}
|
|
247736
247841
|
|
|
247737
247842
|
// src/cli/commands/agents/pull.ts
|
|
247738
|
-
import { dirname as
|
|
247843
|
+
import { dirname as dirname15, join as join21 } from "node:path";
|
|
247739
247844
|
async function pullAgentsAction({
|
|
247740
247845
|
log,
|
|
247741
247846
|
runTask
|
|
247742
247847
|
}) {
|
|
247743
247848
|
const { project } = await readProjectConfig();
|
|
247744
|
-
const configDir =
|
|
247745
|
-
const agentsDir =
|
|
247849
|
+
const configDir = dirname15(project.configPath);
|
|
247850
|
+
const agentsDir = join21(configDir, project.agentsDir);
|
|
247746
247851
|
const remoteAgents = await runTask("Fetching agents from Base44", async () => {
|
|
247747
247852
|
return await fetchAgents();
|
|
247748
247853
|
}, {
|
|
@@ -247812,12 +247917,12 @@ function getAgentsCommand() {
|
|
|
247812
247917
|
}
|
|
247813
247918
|
|
|
247814
247919
|
// src/cli/commands/auth/password-login.ts
|
|
247815
|
-
import { dirname as
|
|
247920
|
+
import { dirname as dirname16, join as join22 } from "node:path";
|
|
247816
247921
|
async function passwordLoginAction({ log, runTask }, action) {
|
|
247817
247922
|
const shouldEnable = action === "enable";
|
|
247818
247923
|
const { project } = await readProjectConfig();
|
|
247819
|
-
const configDir =
|
|
247820
|
-
const authDir =
|
|
247924
|
+
const configDir = dirname16(project.configPath);
|
|
247925
|
+
const authDir = join22(configDir, project.authDir);
|
|
247821
247926
|
const updated = await runTask("Updating local auth config", async () => {
|
|
247822
247927
|
const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
|
|
247823
247928
|
const merged = { ...current, enableUsernamePassword: shouldEnable };
|
|
@@ -247837,14 +247942,14 @@ function getPasswordLoginCommand() {
|
|
|
247837
247942
|
}
|
|
247838
247943
|
|
|
247839
247944
|
// src/cli/commands/auth/pull.ts
|
|
247840
|
-
import { dirname as
|
|
247945
|
+
import { dirname as dirname17, join as join23 } from "node:path";
|
|
247841
247946
|
async function pullAuthAction({
|
|
247842
247947
|
log,
|
|
247843
247948
|
runTask
|
|
247844
247949
|
}) {
|
|
247845
247950
|
const { project } = await readProjectConfig();
|
|
247846
|
-
const configDir =
|
|
247847
|
-
const authDir =
|
|
247951
|
+
const configDir = dirname17(project.configPath);
|
|
247952
|
+
const authDir = join23(configDir, project.authDir);
|
|
247848
247953
|
const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
|
|
247849
247954
|
return await pullAuthConfig();
|
|
247850
247955
|
}, {
|
|
@@ -247908,7 +248013,7 @@ function getAuthPushCommand() {
|
|
|
247908
248013
|
}
|
|
247909
248014
|
|
|
247910
248015
|
// src/cli/commands/auth/social-login.ts
|
|
247911
|
-
import { dirname as
|
|
248016
|
+
import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
|
|
247912
248017
|
var PROVIDER_LABELS = {
|
|
247913
248018
|
google: "Google",
|
|
247914
248019
|
microsoft: "Microsoft",
|
|
@@ -247948,7 +248053,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
247948
248053
|
let clientSecret;
|
|
247949
248054
|
if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
|
|
247950
248055
|
if (options.envFile) {
|
|
247951
|
-
const secrets = await parseEnvFile(
|
|
248056
|
+
const secrets = await parseEnvFile(resolve7(options.envFile));
|
|
247952
248057
|
const value = secrets[oauthCli.envVar];
|
|
247953
248058
|
if (!value) {
|
|
247954
248059
|
throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
|
|
@@ -247978,8 +248083,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
247978
248083
|
}
|
|
247979
248084
|
}
|
|
247980
248085
|
const { project } = await readProjectConfig();
|
|
247981
|
-
const configDir =
|
|
247982
|
-
const authDir =
|
|
248086
|
+
const configDir = dirname18(project.configPath);
|
|
248087
|
+
const authDir = join24(configDir, project.authDir);
|
|
247983
248088
|
const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
|
|
247984
248089
|
if (clientSecret) {
|
|
247985
248090
|
await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
|
|
@@ -248004,7 +248109,7 @@ function getSocialLoginCommand() {
|
|
|
248004
248109
|
}
|
|
248005
248110
|
|
|
248006
248111
|
// src/cli/commands/auth/sso.ts
|
|
248007
|
-
import { dirname as
|
|
248112
|
+
import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
|
|
248008
248113
|
var SSOConfigFileSchema = object({
|
|
248009
248114
|
provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
248010
248115
|
clientId: string2(),
|
|
@@ -248020,7 +248125,7 @@ var SSOConfigFileSchema = object({
|
|
|
248020
248125
|
ssoName: string2().optional()
|
|
248021
248126
|
});
|
|
248022
248127
|
async function loadSSOConfigFile(filePath) {
|
|
248023
|
-
const resolved =
|
|
248128
|
+
const resolved = resolve8(filePath);
|
|
248024
248129
|
const raw = await readJsonFile(resolved);
|
|
248025
248130
|
const result = SSOConfigFileSchema.safeParse(raw);
|
|
248026
248131
|
if (!result.success) {
|
|
@@ -248108,7 +248213,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248108
248213
|
}
|
|
248109
248214
|
let clientSecret;
|
|
248110
248215
|
if (merged.envFile && !merged.clientSecret) {
|
|
248111
|
-
const secrets = await parseEnvFile(
|
|
248216
|
+
const secrets = await parseEnvFile(resolve8(merged.envFile));
|
|
248112
248217
|
const value = secrets.sso_client_secret;
|
|
248113
248218
|
if (!value) {
|
|
248114
248219
|
throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
|
|
@@ -248167,8 +248272,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248167
248272
|
throw error;
|
|
248168
248273
|
}
|
|
248169
248274
|
const { project } = await readProjectConfig();
|
|
248170
|
-
const configDir =
|
|
248171
|
-
const authDir =
|
|
248275
|
+
const configDir = dirname19(project.configPath);
|
|
248276
|
+
const authDir = join25(configDir, project.authDir);
|
|
248172
248277
|
await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
|
|
248173
248278
|
await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
|
|
248174
248279
|
return {
|
|
@@ -248183,8 +248288,8 @@ async function ssoDisableAction({ log, runTask }, options) {
|
|
|
248183
248288
|
throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
|
|
248184
248289
|
}
|
|
248185
248290
|
const { project } = await readProjectConfig();
|
|
248186
|
-
const configDir =
|
|
248187
|
-
const authDir =
|
|
248291
|
+
const configDir = dirname19(project.configPath);
|
|
248292
|
+
const authDir = join25(configDir, project.authDir);
|
|
248188
248293
|
const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
|
|
248189
248294
|
await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
|
|
248190
248295
|
if (!hasAnyLoginMethod(updated)) {
|
|
@@ -249066,13 +249171,13 @@ function getConnectorsListAvailableCommand() {
|
|
|
249066
249171
|
}
|
|
249067
249172
|
|
|
249068
249173
|
// src/cli/commands/connectors/pull.ts
|
|
249069
|
-
import { dirname as
|
|
249174
|
+
import { dirname as dirname20, join as join26, resolve as resolve9 } from "node:path";
|
|
249070
249175
|
async function resolveConnectorsDir(options) {
|
|
249071
249176
|
if (!getAppContext().projectRoot) {
|
|
249072
|
-
return
|
|
249177
|
+
return resolve9(options.dir ?? "connectors");
|
|
249073
249178
|
}
|
|
249074
249179
|
const { project } = await readProjectConfig();
|
|
249075
|
-
return
|
|
249180
|
+
return join26(dirname20(project.configPath), project.connectorsDir);
|
|
249076
249181
|
}
|
|
249077
249182
|
async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
|
|
249078
249183
|
const connectorsDir = await resolveConnectorsDir(options);
|
|
@@ -249113,10 +249218,10 @@ function getConnectorsPullCommand() {
|
|
|
249113
249218
|
}
|
|
249114
249219
|
|
|
249115
249220
|
// src/cli/commands/connectors/push.ts
|
|
249116
|
-
import { resolve as
|
|
249221
|
+
import { resolve as resolve10 } from "node:path";
|
|
249117
249222
|
async function readConnectorsToPush(options) {
|
|
249118
249223
|
if (!getAppContext().projectRoot) {
|
|
249119
|
-
return readAllConnectors(
|
|
249224
|
+
return readAllConnectors(resolve10(options.dir ?? "connectors"));
|
|
249120
249225
|
}
|
|
249121
249226
|
const { connectors } = await readProjectConfig();
|
|
249122
249227
|
return connectors;
|
|
@@ -249459,11 +249564,11 @@ function getListCommand() {
|
|
|
249459
249564
|
}
|
|
249460
249565
|
|
|
249461
249566
|
// src/cli/commands/functions/pull.ts
|
|
249462
|
-
import { dirname as
|
|
249567
|
+
import { dirname as dirname21, join as join27 } from "node:path";
|
|
249463
249568
|
async function pullFunctionsAction({ log, runTask }, name) {
|
|
249464
249569
|
const { project, functions } = await readProjectConfig();
|
|
249465
|
-
const configDir =
|
|
249466
|
-
const functionsDir =
|
|
249570
|
+
const configDir = dirname21(project.configPath);
|
|
249571
|
+
const functionsDir = join27(configDir, project.functionsDir);
|
|
249467
249572
|
const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
|
|
249468
249573
|
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
249469
249574
|
const { functions } = await listDeployedFunctions();
|
|
@@ -249566,14 +249671,11 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
|
|
|
249566
249671
|
|
|
249567
249672
|
// src/cli/commands/project/build.ts
|
|
249568
249673
|
async function buildAction(ctx) {
|
|
249569
|
-
const
|
|
249570
|
-
|
|
249571
|
-
throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
|
|
249572
|
-
}
|
|
249573
|
-
const { project } = await readProjectConfig(app.projectRoot);
|
|
249674
|
+
const app = requireApp(ctx);
|
|
249675
|
+
const target = await resolveBuildTarget(app.projectRoot);
|
|
249574
249676
|
await runSiteBuild(ctx, {
|
|
249575
|
-
root:
|
|
249576
|
-
buildCommand:
|
|
249677
|
+
root: target.root,
|
|
249678
|
+
buildCommand: target.buildCommand,
|
|
249577
249679
|
appId: app.id
|
|
249578
249680
|
});
|
|
249579
249681
|
return {
|
|
@@ -249581,15 +249683,15 @@ async function buildAction(ctx) {
|
|
|
249581
249683
|
};
|
|
249582
249684
|
}
|
|
249583
249685
|
function getBuildCommand() {
|
|
249584
|
-
return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
|
|
249686
|
+
return new Base44Command("build", { requireAuth: false }).description("Build the site with the Base44 app id injected").action(buildAction);
|
|
249585
249687
|
}
|
|
249586
249688
|
|
|
249587
249689
|
// src/cli/commands/project/create.ts
|
|
249588
|
-
import { basename as basename6, resolve as
|
|
249690
|
+
import { basename as basename6, resolve as resolve11 } from "node:path";
|
|
249589
249691
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
249590
249692
|
|
|
249591
249693
|
// src/cli/commands/project/scaffold-shared.ts
|
|
249592
|
-
import { join as
|
|
249694
|
+
import { join as join28 } from "node:path";
|
|
249593
249695
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
249594
249696
|
async function getTemplateById(templateId) {
|
|
249595
249697
|
const templates = await listTemplates();
|
|
@@ -249652,7 +249754,7 @@ async function completeProjectSetup({
|
|
|
249652
249754
|
env: { VITE_BASE44_APP_ID: projectId }
|
|
249653
249755
|
})`${buildCommand}`;
|
|
249654
249756
|
updateMessage("Deploying site...");
|
|
249655
|
-
return await deploySite(
|
|
249757
|
+
return await deploySite(join28(resolvedPath, outputDirectory));
|
|
249656
249758
|
}, {
|
|
249657
249759
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
249658
249760
|
errorMessage: "Failed to deploy site"
|
|
@@ -249781,7 +249883,7 @@ async function createInteractive(options, ctx) {
|
|
|
249781
249883
|
}, ctx);
|
|
249782
249884
|
}
|
|
249783
249885
|
async function createNonInteractive(options, ctx) {
|
|
249784
|
-
ctx.log.info(`Creating a new project at ${
|
|
249886
|
+
ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
|
|
249785
249887
|
const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
|
|
249786
249888
|
return await executeCreate({
|
|
249787
249889
|
template,
|
|
@@ -249805,7 +249907,7 @@ async function executeCreate({
|
|
|
249805
249907
|
}, ctx) {
|
|
249806
249908
|
const { log, runTask } = ctx;
|
|
249807
249909
|
const name = rawName.trim();
|
|
249808
|
-
const resolvedPath =
|
|
249910
|
+
const resolvedPath = resolve11(projectPath);
|
|
249809
249911
|
const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
|
|
249810
249912
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
249811
249913
|
return await createProjectFiles({
|
|
@@ -250446,7 +250548,7 @@ function getLogsCommand() {
|
|
|
250446
250548
|
}
|
|
250447
250549
|
|
|
250448
250550
|
// src/cli/commands/project/scaffold.ts
|
|
250449
|
-
import { basename as basename7, resolve as
|
|
250551
|
+
import { basename as basename7, resolve as resolve12 } from "node:path";
|
|
250450
250552
|
function resolveAppId(options) {
|
|
250451
250553
|
const appId = options.appId;
|
|
250452
250554
|
if (!appId) {
|
|
@@ -250462,7 +250564,7 @@ function resolveAppId(options) {
|
|
|
250462
250564
|
async function scaffoldAction(ctx, name, options, command) {
|
|
250463
250565
|
const { log, runTask } = ctx;
|
|
250464
250566
|
const appId = resolveAppId(command.optsWithGlobals());
|
|
250465
|
-
const resolvedPath =
|
|
250567
|
+
const resolvedPath = resolve12("./");
|
|
250466
250568
|
const projectName = (name ?? basename7(resolvedPath)).trim();
|
|
250467
250569
|
const template = await getTemplateById("backend-only");
|
|
250468
250570
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
@@ -250510,6 +250612,321 @@ function getVisibilityCommand() {
|
|
|
250510
250612
|
])).action(setVisibility);
|
|
250511
250613
|
}
|
|
250512
250614
|
|
|
250615
|
+
// src/core/version/schema.ts
|
|
250616
|
+
var DeclareVersionResponseSchema = object({
|
|
250617
|
+
session_id: string2(),
|
|
250618
|
+
uploads: array(object({
|
|
250619
|
+
path: string2(),
|
|
250620
|
+
url: string2(),
|
|
250621
|
+
content_type: string2(),
|
|
250622
|
+
content_length: number2(),
|
|
250623
|
+
checksum_sha256: string2()
|
|
250624
|
+
}))
|
|
250625
|
+
}).transform((data) => ({
|
|
250626
|
+
sessionId: data.session_id,
|
|
250627
|
+
uploads: data.uploads.map((upload) => ({
|
|
250628
|
+
path: upload.path,
|
|
250629
|
+
url: upload.url,
|
|
250630
|
+
contentType: upload.content_type,
|
|
250631
|
+
contentLength: upload.content_length,
|
|
250632
|
+
checksumSha256: upload.checksum_sha256
|
|
250633
|
+
}))
|
|
250634
|
+
}));
|
|
250635
|
+
var CreateVersionResponseSchema = object({
|
|
250636
|
+
version_id: string2(),
|
|
250637
|
+
manifest_hash: string2()
|
|
250638
|
+
}).transform((data) => ({
|
|
250639
|
+
versionId: data.version_id,
|
|
250640
|
+
manifestHash: data.manifest_hash
|
|
250641
|
+
}));
|
|
250642
|
+
var EnvironmentResponseSchema = object({
|
|
250643
|
+
name: string2(),
|
|
250644
|
+
version_id: string2(),
|
|
250645
|
+
manifest_hash: string2(),
|
|
250646
|
+
deployment_id: string2()
|
|
250647
|
+
}).transform((data) => ({
|
|
250648
|
+
name: data.name,
|
|
250649
|
+
versionId: data.version_id,
|
|
250650
|
+
manifestHash: data.manifest_hash,
|
|
250651
|
+
deploymentId: data.deployment_id
|
|
250652
|
+
}));
|
|
250653
|
+
|
|
250654
|
+
// src/core/version/api.ts
|
|
250655
|
+
var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
|
|
250656
|
+
var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
|
|
250657
|
+
function declaredFile({ path, size, digest }) {
|
|
250658
|
+
return { path, size, digest };
|
|
250659
|
+
}
|
|
250660
|
+
function declaredModule(module) {
|
|
250661
|
+
return { ...declaredFile(module), type: module.type };
|
|
250662
|
+
}
|
|
250663
|
+
function declaredAssetsConfig(config) {
|
|
250664
|
+
const stated = {
|
|
250665
|
+
html_handling: config?.htmlHandling ?? null,
|
|
250666
|
+
not_found_handling: config?.notFoundHandling ?? null,
|
|
250667
|
+
run_worker_first: config?.runWorkerFirst ?? null,
|
|
250668
|
+
headers: config?.headers ?? null,
|
|
250669
|
+
redirects: config?.redirects ?? null
|
|
250670
|
+
};
|
|
250671
|
+
return Object.values(stated).every((v) => v === null) ? null : stated;
|
|
250672
|
+
}
|
|
250673
|
+
async function post(path, json, doing) {
|
|
250674
|
+
try {
|
|
250675
|
+
return await getAppClient().post(path, { json, timeout: 180000 });
|
|
250676
|
+
} catch (error) {
|
|
250677
|
+
throw await ApiError.fromHttpError(error, doing);
|
|
250678
|
+
}
|
|
250679
|
+
}
|
|
250680
|
+
var KEYED_RETRY = {
|
|
250681
|
+
limit: 3,
|
|
250682
|
+
methods: ["patch"],
|
|
250683
|
+
statusCodes: [408, 500, 502, 503, 504],
|
|
250684
|
+
retryOnTimeout: true
|
|
250685
|
+
};
|
|
250686
|
+
async function patch(path, json, doing, retry) {
|
|
250687
|
+
try {
|
|
250688
|
+
return await getAppClient().patch(path, {
|
|
250689
|
+
json,
|
|
250690
|
+
timeout: 180000,
|
|
250691
|
+
...retry ? { retry } : {}
|
|
250692
|
+
});
|
|
250693
|
+
} catch (error) {
|
|
250694
|
+
throw await ApiError.fromHttpError(error, doing);
|
|
250695
|
+
}
|
|
250696
|
+
}
|
|
250697
|
+
function parse10(schema, body, what) {
|
|
250698
|
+
const result = schema.safeParse(body);
|
|
250699
|
+
if (!result.success) {
|
|
250700
|
+
throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
|
|
250701
|
+
}
|
|
250702
|
+
return result.data;
|
|
250703
|
+
}
|
|
250704
|
+
async function createVersion(artifacts, options = {}) {
|
|
250705
|
+
const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
|
|
250706
|
+
static_bundle: artifacts.files.map(declaredFile),
|
|
250707
|
+
...artifacts.siteWorker ? {
|
|
250708
|
+
site_worker: {
|
|
250709
|
+
main: artifacts.siteWorker.main,
|
|
250710
|
+
modules: artifacts.siteWorker.modules.map(declaredModule),
|
|
250711
|
+
assets: artifacts.siteWorker.assets.map(declaredFile),
|
|
250712
|
+
compatibility_date: artifacts.siteWorker.compatibilityDate,
|
|
250713
|
+
compatibility_flags: artifacts.siteWorker.compatibilityFlags,
|
|
250714
|
+
assets_config: declaredAssetsConfig(artifacts.siteWorker.assetsConfig)
|
|
250715
|
+
}
|
|
250716
|
+
} : {},
|
|
250717
|
+
entities: artifacts.entities,
|
|
250718
|
+
agents: artifacts.agents,
|
|
250719
|
+
source_commit: options.sourceCommit
|
|
250720
|
+
}, "declaring a version")).json(), "declare");
|
|
250721
|
+
const declaredFiles = [
|
|
250722
|
+
...artifacts.files,
|
|
250723
|
+
...artifacts.siteWorker?.modules ?? [],
|
|
250724
|
+
...artifacts.siteWorker?.assets ?? []
|
|
250725
|
+
];
|
|
250726
|
+
options.progress?.onDeclared?.({ fileCount: declaredFiles.length });
|
|
250727
|
+
if (declared.uploads.length !== declaredFiles.length) {
|
|
250728
|
+
throw new InternalError(`Declared ${declaredFiles.length} files but the server signed ${declared.uploads.length} upload URLs.`);
|
|
250729
|
+
}
|
|
250730
|
+
const drifted = declared.uploads.findIndex((upload, index) => upload.path !== declaredFiles[index].path);
|
|
250731
|
+
if (drifted !== -1) {
|
|
250732
|
+
throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
|
|
250733
|
+
}
|
|
250734
|
+
let uploadedFiles = 0;
|
|
250735
|
+
await pMap(declared.uploads, async (upload, index) => {
|
|
250736
|
+
await putPresigned(upload, declaredFiles[index].absolutePath);
|
|
250737
|
+
uploadedFiles++;
|
|
250738
|
+
options.progress?.onUpload?.({
|
|
250739
|
+
uploadedFiles,
|
|
250740
|
+
totalFiles: declared.uploads.length
|
|
250741
|
+
});
|
|
250742
|
+
}, { concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY });
|
|
250743
|
+
return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
|
|
250744
|
+
}
|
|
250745
|
+
async function setEnvironmentVersion(environment, versionId, options = {}) {
|
|
250746
|
+
return parse10(EnvironmentResponseSchema, await (await patch(`environments/${encodeURIComponent(environment)}`, {
|
|
250747
|
+
version_id: versionId,
|
|
250748
|
+
...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
|
|
250749
|
+
}, "setting the environment's version", options.idempotencyKey ? KEYED_RETRY : undefined)).json(), "environment");
|
|
250750
|
+
}
|
|
250751
|
+
// src/core/version/artifacts.ts
|
|
250752
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
250753
|
+
import { join as join29, resolve as resolve13 } from "node:path";
|
|
250754
|
+
var MAX_FILE_COUNT = 50000;
|
|
250755
|
+
var HASH_CONCURRENCY = 32;
|
|
250756
|
+
var ENTRY2 = "index.html";
|
|
250757
|
+
async function digestFile(absolutePath) {
|
|
250758
|
+
const hash = await hashFileInto(createHash2("sha256"), absolutePath);
|
|
250759
|
+
return `sha256:${hash.digest("hex")}`;
|
|
250760
|
+
}
|
|
250761
|
+
async function collectBuildOutput(outputDir, options = {}) {
|
|
250762
|
+
const found = await describeBuildOutput(outputDir);
|
|
250763
|
+
if (found.length > MAX_FILE_COUNT) {
|
|
250764
|
+
throw new InvalidInputError(`Too many files: found ${found.length}, the limit is ${MAX_FILE_COUNT}.`);
|
|
250765
|
+
}
|
|
250766
|
+
if (options.entryFile) {
|
|
250767
|
+
if (found.length === 0) {
|
|
250768
|
+
throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
|
|
250769
|
+
hints: [
|
|
250770
|
+
{ message: "Run 'base44 build' first", command: "base44 build" }
|
|
250771
|
+
]
|
|
250772
|
+
});
|
|
250773
|
+
}
|
|
250774
|
+
if (!found.some((f) => f.path === options.entryFile)) {
|
|
250775
|
+
throw new InvalidInputError(`${outputDir} has no ${options.entryFile}, so nothing could enter the site.`);
|
|
250776
|
+
}
|
|
250777
|
+
}
|
|
250778
|
+
return await pMap(found, async (file) => ({ ...file, digest: await digestFile(file.absolutePath) }), { concurrency: HASH_CONCURRENCY });
|
|
250779
|
+
}
|
|
250780
|
+
async function collectSiteWorker(projectRoot) {
|
|
250781
|
+
const built = await resolveFullStackBuild(projectRoot);
|
|
250782
|
+
if (!built) {
|
|
250783
|
+
return null;
|
|
250784
|
+
}
|
|
250785
|
+
const { config, modules, assetsDir } = built;
|
|
250786
|
+
const entry = resolve13(config.configDir, config.main);
|
|
250787
|
+
const main = modules.find((m) => m.absolutePath === entry)?.name;
|
|
250788
|
+
if (!main) {
|
|
250789
|
+
throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
|
|
250790
|
+
}
|
|
250791
|
+
return {
|
|
250792
|
+
main,
|
|
250793
|
+
modules: await pMap(modules, async ({ name, absolutePath, size, type }) => ({
|
|
250794
|
+
path: name,
|
|
250795
|
+
absolutePath,
|
|
250796
|
+
size,
|
|
250797
|
+
digest: await digestFile(absolutePath),
|
|
250798
|
+
type
|
|
250799
|
+
}), { concurrency: HASH_CONCURRENCY }),
|
|
250800
|
+
assets: assetsDir ? await collectBuildOutput(assetsDir) : [],
|
|
250801
|
+
compatibilityDate: config.compatibilityDate,
|
|
250802
|
+
compatibilityFlags: config.compatibilityFlags,
|
|
250803
|
+
assetsConfig: config.assetsConfig
|
|
250804
|
+
};
|
|
250805
|
+
}
|
|
250806
|
+
async function readRawResources(dir) {
|
|
250807
|
+
if (!await pathExists(dir)) {
|
|
250808
|
+
return {};
|
|
250809
|
+
}
|
|
250810
|
+
const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
|
|
250811
|
+
cwd: dir,
|
|
250812
|
+
onlyFiles: true,
|
|
250813
|
+
followSymbolicLinks: false
|
|
250814
|
+
});
|
|
250815
|
+
const payloads = {};
|
|
250816
|
+
for (const relativePath of files.sort()) {
|
|
250817
|
+
const name = relativePath.replace(/\.jsonc?$/, "");
|
|
250818
|
+
payloads[name] = await readJsonFile(join29(dir, ...relativePath.split("/")));
|
|
250819
|
+
}
|
|
250820
|
+
return payloads;
|
|
250821
|
+
}
|
|
250822
|
+
async function collectResources(configDir, dirs) {
|
|
250823
|
+
const [entities, agents] = await Promise.all([
|
|
250824
|
+
readRawResources(join29(configDir, dirs.entitiesDir)),
|
|
250825
|
+
readRawResources(join29(configDir, dirs.agentsDir))
|
|
250826
|
+
]);
|
|
250827
|
+
return { entities, agents };
|
|
250828
|
+
}
|
|
250829
|
+
async function collectArtifacts(target) {
|
|
250830
|
+
const siteWorker = await collectSiteWorker(target.root);
|
|
250831
|
+
return {
|
|
250832
|
+
files: siteWorker ? [] : await collectBuildOutput(requireOutputDir(target), {
|
|
250833
|
+
entryFile: ENTRY2
|
|
250834
|
+
}),
|
|
250835
|
+
...siteWorker ? { siteWorker } : {},
|
|
250836
|
+
...await collectResources(target.configDir, target)
|
|
250837
|
+
};
|
|
250838
|
+
}
|
|
250839
|
+
// src/core/version/gate.ts
|
|
250840
|
+
var VERSIONS_API_ENV = "BASE44_VERSIONS_API";
|
|
250841
|
+
function versionsApiEnabled(env = process.env) {
|
|
250842
|
+
const value = env[VERSIONS_API_ENV];
|
|
250843
|
+
return value === "1" || value === "true";
|
|
250844
|
+
}
|
|
250845
|
+
// src/core/version/publish.ts
|
|
250846
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
250847
|
+
var DEFAULT_ENVIRONMENT = "production";
|
|
250848
|
+
async function tagStep2(step, run) {
|
|
250849
|
+
return await tagStep(step, run);
|
|
250850
|
+
}
|
|
250851
|
+
async function publishVersion(artifacts, options = {}) {
|
|
250852
|
+
const version = await tagStep2("create_version", () => createVersion(artifacts, {
|
|
250853
|
+
sourceCommit: options.sourceCommit,
|
|
250854
|
+
concurrency: options.concurrency,
|
|
250855
|
+
progress: options.progress
|
|
250856
|
+
}));
|
|
250857
|
+
const environment = await tagStep2("deploy", () => setEnvironmentVersion(options.target ?? DEFAULT_ENVIRONMENT, version.versionId, {
|
|
250858
|
+
idempotencyKey: randomUUID4()
|
|
250859
|
+
}));
|
|
250860
|
+
return {
|
|
250861
|
+
environment: environment.name,
|
|
250862
|
+
versionId: environment.versionId,
|
|
250863
|
+
manifestHash: environment.manifestHash,
|
|
250864
|
+
deploymentId: environment.deploymentId
|
|
250865
|
+
};
|
|
250866
|
+
}
|
|
250867
|
+
// src/cli/commands/versions/options.ts
|
|
250868
|
+
function outputDirOption() {
|
|
250869
|
+
return new Option2("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)");
|
|
250870
|
+
}
|
|
250871
|
+
function targetOption() {
|
|
250872
|
+
return new Option2("--target <name>", "Environment to serve the version at");
|
|
250873
|
+
}
|
|
250874
|
+
function gitHashOption() {
|
|
250875
|
+
return new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser((value) => {
|
|
250876
|
+
if (!isGitCommitHash(value)) {
|
|
250877
|
+
throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
|
|
250878
|
+
}
|
|
250879
|
+
return value;
|
|
250880
|
+
});
|
|
250881
|
+
}
|
|
250882
|
+
function concurrencyOption() {
|
|
250883
|
+
return new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser((value) => {
|
|
250884
|
+
const parsed = Number(value);
|
|
250885
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
|
|
250886
|
+
throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
|
|
250887
|
+
}
|
|
250888
|
+
return parsed;
|
|
250889
|
+
});
|
|
250890
|
+
}
|
|
250891
|
+
|
|
250892
|
+
// src/cli/commands/publish.ts
|
|
250893
|
+
async function publishAction(ctx, options) {
|
|
250894
|
+
const { runTask, log, jsonMode } = ctx;
|
|
250895
|
+
const app = requireApp(ctx);
|
|
250896
|
+
const target = await tagStep2("create_version", () => resolveBuildTarget(app.projectRoot, { outputDir: options.outputDir }));
|
|
250897
|
+
if (options.build !== false) {
|
|
250898
|
+
await tagStep2("build", () => runSiteBuild(ctx, {
|
|
250899
|
+
root: target.root,
|
|
250900
|
+
buildCommand: target.buildCommand,
|
|
250901
|
+
appId: app.id
|
|
250902
|
+
}));
|
|
250903
|
+
}
|
|
250904
|
+
const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
|
|
250905
|
+
const result = await runTask("Publishing...", async (updateMessage) => {
|
|
250906
|
+
const artifacts = await tagStep2("create_version", () => collectArtifacts(target));
|
|
250907
|
+
return await publishVersion(artifacts, {
|
|
250908
|
+
sourceCommit: gitHash,
|
|
250909
|
+
target: options.target,
|
|
250910
|
+
concurrency: options.concurrency,
|
|
250911
|
+
progress: {
|
|
250912
|
+
onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
|
|
250913
|
+
onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
|
|
250914
|
+
}
|
|
250915
|
+
});
|
|
250916
|
+
}, { successMessage: "Published", errorMessage: "Publish failed" });
|
|
250917
|
+
if (!jsonMode) {
|
|
250918
|
+
log.message(theme.styles.dim(`version ${result.versionId}`));
|
|
250919
|
+
}
|
|
250920
|
+
return {
|
|
250921
|
+
outroMessage: `${result.environment} now serves ${result.versionId}`,
|
|
250922
|
+
stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
|
|
250923
|
+
` : undefined
|
|
250924
|
+
};
|
|
250925
|
+
}
|
|
250926
|
+
function getPublishCommand() {
|
|
250927
|
+
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);
|
|
250928
|
+
}
|
|
250929
|
+
|
|
250513
250930
|
// src/core/resources/sandbox/schema.ts
|
|
250514
250931
|
var FileErrorSchema = object({
|
|
250515
250932
|
code: string2(),
|
|
@@ -250895,7 +251312,7 @@ function getSecretsListCommand() {
|
|
|
250895
251312
|
}
|
|
250896
251313
|
|
|
250897
251314
|
// src/cli/commands/secrets/set.ts
|
|
250898
|
-
import { resolve as
|
|
251315
|
+
import { resolve as resolve14 } from "node:path";
|
|
250899
251316
|
function parseEntries(entries) {
|
|
250900
251317
|
const secrets = {};
|
|
250901
251318
|
for (const entry of entries) {
|
|
@@ -250926,7 +251343,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
|
|
|
250926
251343
|
validateInput(entries, options);
|
|
250927
251344
|
let secrets;
|
|
250928
251345
|
if (options.envFile) {
|
|
250929
|
-
secrets = await parseEnvFile(
|
|
251346
|
+
secrets = await parseEnvFile(resolve14(options.envFile));
|
|
250930
251347
|
if (Object.keys(secrets).length === 0) {
|
|
250931
251348
|
throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
|
|
250932
251349
|
}
|
|
@@ -250955,7 +251372,7 @@ function getSecretsCommand() {
|
|
|
250955
251372
|
}
|
|
250956
251373
|
|
|
250957
251374
|
// src/cli/commands/site/deploy.ts
|
|
250958
|
-
import { resolve as
|
|
251375
|
+
import { resolve as resolve15 } from "node:path";
|
|
250959
251376
|
async function deployAction2(ctx, options) {
|
|
250960
251377
|
const { isNonInteractive } = ctx;
|
|
250961
251378
|
if (isNonInteractive && !options.yes) {
|
|
@@ -251033,7 +251450,7 @@ async function deployTarball({ runTask }, project) {
|
|
|
251033
251450
|
}
|
|
251034
251451
|
function siteOutputDir(project) {
|
|
251035
251452
|
const outputDirectory = project.site?.outputDirectory;
|
|
251036
|
-
return outputDirectory ?
|
|
251453
|
+
return outputDirectory ? resolve15(project.root, outputDirectory) : null;
|
|
251037
251454
|
}
|
|
251038
251455
|
function getSiteDeployCommand() {
|
|
251039
251456
|
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)");
|
|
@@ -251165,10 +251582,10 @@ function toPascalCase(name) {
|
|
|
251165
251582
|
return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
251166
251583
|
}
|
|
251167
251584
|
// src/core/types/update-project.ts
|
|
251168
|
-
import { join as
|
|
251585
|
+
import { join as join33 } from "node:path";
|
|
251169
251586
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
251170
251587
|
async function updateProjectConfig(projectRoot) {
|
|
251171
|
-
const tsconfigPath =
|
|
251588
|
+
const tsconfigPath = join33(projectRoot, "tsconfig.json");
|
|
251172
251589
|
if (!await pathExists(tsconfigPath)) {
|
|
251173
251590
|
return false;
|
|
251174
251591
|
}
|
|
@@ -251217,6 +251634,59 @@ function getTypesCommand() {
|
|
|
251217
251634
|
return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
251218
251635
|
}
|
|
251219
251636
|
|
|
251637
|
+
// src/cli/commands/versions/create.ts
|
|
251638
|
+
async function createAction2(ctx, options) {
|
|
251639
|
+
const { runTask, jsonMode } = ctx;
|
|
251640
|
+
const target = await resolveBuildTarget(requireApp(ctx).projectRoot, {
|
|
251641
|
+
outputDir: options.outputDir
|
|
251642
|
+
});
|
|
251643
|
+
const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
|
|
251644
|
+
const version = await runTask("Creating version...", async (updateMessage) => await createVersion(await collectArtifacts(target), {
|
|
251645
|
+
sourceCommit: gitHash,
|
|
251646
|
+
concurrency: options.concurrency,
|
|
251647
|
+
progress: {
|
|
251648
|
+
onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
|
|
251649
|
+
onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
|
|
251650
|
+
}
|
|
251651
|
+
}), {
|
|
251652
|
+
successMessage: "Version created",
|
|
251653
|
+
errorMessage: "Create version failed"
|
|
251654
|
+
});
|
|
251655
|
+
return {
|
|
251656
|
+
outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
|
|
251657
|
+
stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
|
|
251658
|
+
` : undefined
|
|
251659
|
+
};
|
|
251660
|
+
}
|
|
251661
|
+
function getVersionCreateCommand() {
|
|
251662
|
+
return new Base44Command("create").description("Record the built output as a version, without deploying it").addOption(outputDirOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(createAction2);
|
|
251663
|
+
}
|
|
251664
|
+
|
|
251665
|
+
// src/cli/commands/versions/deploy.ts
|
|
251666
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
251667
|
+
async function deployAction3({ runTask, jsonMode }, versionId, options) {
|
|
251668
|
+
const environment = options.target ?? DEFAULT_ENVIRONMENT;
|
|
251669
|
+
const result = await runTask(`Pointing ${environment} at ${versionId}...`, async () => await setEnvironmentVersion(environment, versionId, {
|
|
251670
|
+
idempotencyKey: randomUUID5()
|
|
251671
|
+
}), {
|
|
251672
|
+
successMessage: "Environment updated",
|
|
251673
|
+
errorMessage: "Could not update the environment"
|
|
251674
|
+
});
|
|
251675
|
+
return {
|
|
251676
|
+
outroMessage: `${result.name} now serves ${result.versionId}`,
|
|
251677
|
+
stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
|
|
251678
|
+
` : undefined
|
|
251679
|
+
};
|
|
251680
|
+
}
|
|
251681
|
+
function getVersionDeployCommand() {
|
|
251682
|
+
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);
|
|
251683
|
+
}
|
|
251684
|
+
|
|
251685
|
+
// src/cli/commands/versions/index.ts
|
|
251686
|
+
function getVersionsCommand() {
|
|
251687
|
+
return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
|
|
251688
|
+
}
|
|
251689
|
+
|
|
251220
251690
|
// src/core/resources/workflow/schema.ts
|
|
251221
251691
|
var WorkflowRunStatusSchema = _enum([
|
|
251222
251692
|
"running",
|
|
@@ -251633,7 +252103,7 @@ function createDevLogger(label, labelColor = theme.styles.dim) {
|
|
|
251633
252103
|
// src/cli/dev/dev-server/main.ts
|
|
251634
252104
|
var import_cors = __toESM(require_lib4(), 1);
|
|
251635
252105
|
var import_express6 = __toESM(require_express(), 1);
|
|
251636
|
-
import { dirname as
|
|
252106
|
+
import { dirname as dirname27, join as join38 } from "node:path";
|
|
251637
252107
|
|
|
251638
252108
|
// ../../node_modules/get-port/index.js
|
|
251639
252109
|
import net from "node:net";
|
|
@@ -251763,7 +252233,7 @@ var $tmpName = promisify11(tmp.tmpName);
|
|
|
251763
252233
|
|
|
251764
252234
|
// src/cli/dev/dev-server/function-manager.ts
|
|
251765
252235
|
import { spawn as spawn2 } from "node:child_process";
|
|
251766
|
-
import { dirname as
|
|
252236
|
+
import { dirname as dirname24, join as join34 } from "node:path";
|
|
251767
252237
|
import { pathToFileURL } from "node:url";
|
|
251768
252238
|
|
|
251769
252239
|
// src/cli/dev/dev-server/base-function-manager.ts
|
|
@@ -251868,7 +252338,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
251868
252338
|
}
|
|
251869
252339
|
spawnFunction(func, port) {
|
|
251870
252340
|
this.logger.log(`Spawning function "${func.name}" on port ${port}`);
|
|
251871
|
-
const importMapPath =
|
|
252341
|
+
const importMapPath = join34(dirname24(this.wrapperPath), "import-map.json");
|
|
251872
252342
|
const process2 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
|
|
251873
252343
|
env: {
|
|
251874
252344
|
...globalThis.process.env,
|
|
@@ -251942,7 +252412,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
251942
252412
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
251943
252413
|
import { isBuiltin } from "node:module";
|
|
251944
252414
|
import { homedir as homedir3 } from "node:os";
|
|
251945
|
-
import { join as
|
|
252415
|
+
import { join as join35 } from "node:path";
|
|
251946
252416
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
251947
252417
|
var depsPromise;
|
|
251948
252418
|
function loadDeps() {
|
|
@@ -252063,9 +252533,9 @@ export default {
|
|
|
252063
252533
|
};
|
|
252064
252534
|
`;
|
|
252065
252535
|
function ensureBundlerConfig() {
|
|
252066
|
-
const dir =
|
|
252536
|
+
const dir = join35(homedir3(), ".base44", "function-bundler");
|
|
252067
252537
|
mkdirSync2(dir, { recursive: true });
|
|
252068
|
-
const configPath =
|
|
252538
|
+
const configPath = join35(dir, "deno.json");
|
|
252069
252539
|
writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
|
|
252070
252540
|
`);
|
|
252071
252541
|
return configPath;
|
|
@@ -253446,11 +253916,11 @@ async function createEntityRoutes(db, logger, broadcast) {
|
|
|
253446
253916
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
253447
253917
|
var import_express5 = __toESM(require_express(), 1);
|
|
253448
253918
|
var import_multer = __toESM(require_multer(), 1);
|
|
253449
|
-
import { createHash as
|
|
253919
|
+
import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
|
|
253450
253920
|
import fs28 from "node:fs";
|
|
253451
253921
|
import path18 from "node:path";
|
|
253452
253922
|
function createFileToken(fileUri) {
|
|
253453
|
-
return
|
|
253923
|
+
return createHash3("sha256").update(fileUri).digest("hex");
|
|
253454
253924
|
}
|
|
253455
253925
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
253456
253926
|
const router = import_express5.Router({ mergeParams: true });
|
|
@@ -253463,14 +253933,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
253463
253933
|
destination: mediaFilesDir,
|
|
253464
253934
|
filename: (_req, file, cb) => {
|
|
253465
253935
|
const ext = path18.extname(file.originalname);
|
|
253466
|
-
cb(null, `${
|
|
253936
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253467
253937
|
}
|
|
253468
253938
|
});
|
|
253469
253939
|
const privateStorage = import_multer.default.diskStorage({
|
|
253470
253940
|
destination: privateFilesDir,
|
|
253471
253941
|
filename: (_req, file, cb) => {
|
|
253472
253942
|
const ext = path18.extname(file.originalname);
|
|
253473
|
-
cb(null, `${
|
|
253943
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253474
253944
|
}
|
|
253475
253945
|
});
|
|
253476
253946
|
const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
|
|
@@ -255332,8 +255802,8 @@ async function createDevServer(options) {
|
|
|
255332
255802
|
broadcastEntityEvent(io, appId, entityName, event);
|
|
255333
255803
|
};
|
|
255334
255804
|
const base44ConfigWatcher = new WatchBase44({
|
|
255335
|
-
functions:
|
|
255336
|
-
entities:
|
|
255805
|
+
functions: join38(dirname27(project.configPath), project.functionsDir),
|
|
255806
|
+
entities: join38(dirname27(project.configPath), project.entitiesDir)
|
|
255337
255807
|
}, devLogger);
|
|
255338
255808
|
base44ConfigWatcher.on("change", async (name) => {
|
|
255339
255809
|
try {
|
|
@@ -255730,7 +256200,7 @@ Examples:
|
|
|
255730
256200
|
}
|
|
255731
256201
|
|
|
255732
256202
|
// src/cli/commands/project/eject.ts
|
|
255733
|
-
import { resolve as
|
|
256203
|
+
import { resolve as resolve19 } from "node:path";
|
|
255734
256204
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
255735
256205
|
async function eject(ctx, options, command) {
|
|
255736
256206
|
const { log, runTask, isNonInteractive } = ctx;
|
|
@@ -255794,7 +256264,7 @@ async function eject(ctx, options, command) {
|
|
|
255794
256264
|
Ne("Operation cancelled.");
|
|
255795
256265
|
throw new CLIExitError(0);
|
|
255796
256266
|
}
|
|
255797
|
-
const resolvedPath =
|
|
256267
|
+
const resolvedPath = resolve19(selectedPath);
|
|
255798
256268
|
await runTask("Downloading your project's code...", async (updateMessage) => {
|
|
255799
256269
|
await createProjectFilesForExistingProject({
|
|
255800
256270
|
projectId,
|
|
@@ -255878,6 +256348,10 @@ function createProgram(context) {
|
|
|
255878
256348
|
program.addCommand(getBranchesCommand());
|
|
255879
256349
|
program.addCommand(getAuthCommand());
|
|
255880
256350
|
program.addCommand(getSiteCommand());
|
|
256351
|
+
if (versionsApiEnabled()) {
|
|
256352
|
+
program.addCommand(getPublishCommand());
|
|
256353
|
+
program.addCommand(getVersionsCommand());
|
|
256354
|
+
}
|
|
255881
256355
|
program.addCommand(getTypesCommand());
|
|
255882
256356
|
program.addCommand(getExecCommand());
|
|
255883
256357
|
program.addCommand(getDevCommand());
|
|
@@ -255890,7 +256364,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
255890
256364
|
import { release, type } from "node:os";
|
|
255891
256365
|
|
|
255892
256366
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
255893
|
-
import { dirname as
|
|
256367
|
+
import { dirname as dirname28, posix, sep as sep2 } from "path";
|
|
255894
256368
|
function createModulerModifier() {
|
|
255895
256369
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
255896
256370
|
return async (frames) => {
|
|
@@ -255899,7 +256373,7 @@ function createModulerModifier() {
|
|
|
255899
256373
|
return frames;
|
|
255900
256374
|
};
|
|
255901
256375
|
}
|
|
255902
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
256376
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname28(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
|
|
255903
256377
|
const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
|
|
255904
256378
|
return (filename) => {
|
|
255905
256379
|
if (!filename)
|
|
@@ -259888,9 +260362,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
|
|
|
259888
260362
|
});
|
|
259889
260363
|
}
|
|
259890
260364
|
// src/cli/index.ts
|
|
259891
|
-
var __dirname4 =
|
|
260365
|
+
var __dirname4 = dirname29(fileURLToPath6(import.meta.url));
|
|
259892
260366
|
async function runCLI(options) {
|
|
259893
|
-
ensureNpmAssets(
|
|
260367
|
+
ensureNpmAssets(join39(__dirname4, "../assets"));
|
|
259894
260368
|
const errorReporter = new ErrorReporter;
|
|
259895
260369
|
errorReporter.registerProcessErrorHandlers();
|
|
259896
260370
|
const jsonMode = process.argv.includes("--json");
|
|
@@ -259929,4 +260403,4 @@ export {
|
|
|
259929
260403
|
runCLI
|
|
259930
260404
|
};
|
|
259931
260405
|
|
|
259932
|
-
//# debugId=
|
|
260406
|
+
//# debugId=4A0444E0B8A1C5CD64756E2164756E21
|