@base44-preview/cli 0.1.18-pr.639.a559cb8 → 0.1.20-pr.640.0cb18d9
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 +1108 -603
- package/dist/cli/index.js.map +37 -22
- 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 process23 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) ?? process23.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 process24 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 : process24.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 (process24.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 } = process24);
|
|
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")) {
|
|
@@ -228670,6 +228670,20 @@ function isCLIError(error) {
|
|
|
228670
228670
|
function isUserError(error) {
|
|
228671
228671
|
return error instanceof UserError;
|
|
228672
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
|
+
}
|
|
228673
228687
|
|
|
228674
228688
|
// src/core/utils/fs.ts
|
|
228675
228689
|
async function pathExists(path) {
|
|
@@ -228796,7 +228810,7 @@ function normalizeBase44Env() {
|
|
|
228796
228810
|
loadProjectEnvFiles();
|
|
228797
228811
|
|
|
228798
228812
|
// src/cli/index.ts
|
|
228799
|
-
import { dirname as
|
|
228813
|
+
import { dirname as dirname29, join as join39 } from "node:path";
|
|
228800
228814
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
228801
228815
|
|
|
228802
228816
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -239251,7 +239265,7 @@ import { join as join13 } from "node:path";
|
|
|
239251
239265
|
// package.json
|
|
239252
239266
|
var package_default = {
|
|
239253
239267
|
name: "base44",
|
|
239254
|
-
version: "0.1.
|
|
239268
|
+
version: "0.1.20",
|
|
239255
239269
|
description: "Base44 CLI - Unified interface for managing Base44 applications",
|
|
239256
239270
|
type: "module",
|
|
239257
239271
|
bin: {
|
|
@@ -239605,11 +239619,325 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
239605
239619
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
239606
239620
|
import { join as join18 } from "node:path";
|
|
239607
239621
|
|
|
239622
|
+
// src/core/site/modules.ts
|
|
239623
|
+
import { stat } from "node:fs/promises";
|
|
239624
|
+
import { relative as relative5, resolve as resolve3, sep } from "node:path";
|
|
239625
|
+
var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
|
|
239626
|
+
var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
|
|
239627
|
+
var RULE_TYPE_TO_MODULE_TYPE = {
|
|
239628
|
+
ESModule: "esm",
|
|
239629
|
+
CompiledWasm: "wasm",
|
|
239630
|
+
Text: "text",
|
|
239631
|
+
Data: "data"
|
|
239632
|
+
};
|
|
239633
|
+
function toPosix(path) {
|
|
239634
|
+
return path.split(sep).join("/");
|
|
239635
|
+
}
|
|
239636
|
+
async function collectModules(config) {
|
|
239637
|
+
const entryPath = resolve3(config.configDir, config.main);
|
|
239638
|
+
if (!await pathExists(entryPath)) {
|
|
239639
|
+
throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config.configPath})`, {
|
|
239640
|
+
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
239641
|
+
});
|
|
239642
|
+
}
|
|
239643
|
+
const modulesByName = new Map;
|
|
239644
|
+
const entryName = toPosix(relative5(config.configDir, entryPath));
|
|
239645
|
+
modulesByName.set(entryName, {
|
|
239646
|
+
name: entryName,
|
|
239647
|
+
absolutePath: entryPath,
|
|
239648
|
+
size: 0,
|
|
239649
|
+
type: "esm"
|
|
239650
|
+
});
|
|
239651
|
+
const ignore = [...MODULE_IGNORE];
|
|
239652
|
+
if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
|
|
239653
|
+
ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
|
|
239654
|
+
}
|
|
239655
|
+
for (const rule of config.rules) {
|
|
239656
|
+
const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
|
|
239657
|
+
if (!type) {
|
|
239658
|
+
throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
|
|
239659
|
+
}
|
|
239660
|
+
const matches = await globby(rule.globs, {
|
|
239661
|
+
cwd: config.configDir,
|
|
239662
|
+
onlyFiles: true,
|
|
239663
|
+
dot: true,
|
|
239664
|
+
ignore
|
|
239665
|
+
});
|
|
239666
|
+
for (const match of matches.sort()) {
|
|
239667
|
+
if (!modulesByName.has(match)) {
|
|
239668
|
+
modulesByName.set(match, {
|
|
239669
|
+
name: match,
|
|
239670
|
+
absolutePath: resolve3(config.configDir, match),
|
|
239671
|
+
size: 0,
|
|
239672
|
+
type
|
|
239673
|
+
});
|
|
239674
|
+
}
|
|
239675
|
+
}
|
|
239676
|
+
}
|
|
239677
|
+
if (config.uploadSourceMaps) {
|
|
239678
|
+
const maps = await globby("**/*.map", {
|
|
239679
|
+
cwd: config.configDir,
|
|
239680
|
+
onlyFiles: true,
|
|
239681
|
+
dot: true,
|
|
239682
|
+
ignore
|
|
239683
|
+
});
|
|
239684
|
+
for (const map of maps.sort()) {
|
|
239685
|
+
addSourcemap(modulesByName, config.configDir, map);
|
|
239686
|
+
}
|
|
239687
|
+
} else {
|
|
239688
|
+
for (const name of [...modulesByName.keys()]) {
|
|
239689
|
+
const mapName = `${name}.map`;
|
|
239690
|
+
if (await pathExists(resolve3(config.configDir, mapName))) {
|
|
239691
|
+
addSourcemap(modulesByName, config.configDir, mapName);
|
|
239692
|
+
}
|
|
239693
|
+
}
|
|
239694
|
+
}
|
|
239695
|
+
const modules = [...modulesByName.values()];
|
|
239696
|
+
let totalBytes = 0;
|
|
239697
|
+
for (const module of modules) {
|
|
239698
|
+
module.size = (await stat(module.absolutePath)).size;
|
|
239699
|
+
totalBytes += module.size;
|
|
239700
|
+
}
|
|
239701
|
+
if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
|
|
239702
|
+
throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for a Base44 deploy.`);
|
|
239703
|
+
}
|
|
239704
|
+
return modules;
|
|
239705
|
+
}
|
|
239706
|
+
function addSourcemap(modulesByName, configDir, name) {
|
|
239707
|
+
if (modulesByName.has(name))
|
|
239708
|
+
return;
|
|
239709
|
+
modulesByName.set(name, {
|
|
239710
|
+
name,
|
|
239711
|
+
absolutePath: resolve3(configDir, name),
|
|
239712
|
+
size: 0,
|
|
239713
|
+
type: "sourcemap"
|
|
239714
|
+
});
|
|
239715
|
+
}
|
|
239716
|
+
|
|
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
|
+
|
|
239608
239810
|
// src/core/site/manifest.ts
|
|
239609
239811
|
import { createHash } from "node:crypto";
|
|
239610
239812
|
import { createReadStream } from "node:fs";
|
|
239611
|
-
import { stat } from "node:fs/promises";
|
|
239612
|
-
import { basename as basename5, extname, join as
|
|
239813
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
239814
|
+
import { basename as basename5, extname, join as join17 } from "node:path";
|
|
239815
|
+
|
|
239816
|
+
// ../../node_modules/p-map/index.js
|
|
239817
|
+
async function pMap(iterable, mapper, {
|
|
239818
|
+
concurrency = Number.POSITIVE_INFINITY,
|
|
239819
|
+
stopOnError = true,
|
|
239820
|
+
signal
|
|
239821
|
+
} = {}) {
|
|
239822
|
+
return new Promise((resolve_, reject_) => {
|
|
239823
|
+
if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
|
|
239824
|
+
throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
|
|
239825
|
+
}
|
|
239826
|
+
if (typeof mapper !== "function") {
|
|
239827
|
+
throw new TypeError("Mapper function is required");
|
|
239828
|
+
}
|
|
239829
|
+
if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
|
|
239830
|
+
throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
|
|
239831
|
+
}
|
|
239832
|
+
const result = [];
|
|
239833
|
+
const errors = [];
|
|
239834
|
+
const skippedIndexesMap = new Map;
|
|
239835
|
+
let isRejected = false;
|
|
239836
|
+
let isResolved = false;
|
|
239837
|
+
let isIterableDone = false;
|
|
239838
|
+
let resolvingCount = 0;
|
|
239839
|
+
let currentIndex = 0;
|
|
239840
|
+
const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
|
|
239841
|
+
const signalListener = () => {
|
|
239842
|
+
reject(signal.reason);
|
|
239843
|
+
};
|
|
239844
|
+
const cleanup = () => {
|
|
239845
|
+
signal?.removeEventListener("abort", signalListener);
|
|
239846
|
+
};
|
|
239847
|
+
const resolve = (value) => {
|
|
239848
|
+
resolve_(value);
|
|
239849
|
+
cleanup();
|
|
239850
|
+
};
|
|
239851
|
+
const reject = (reason) => {
|
|
239852
|
+
isRejected = true;
|
|
239853
|
+
isResolved = true;
|
|
239854
|
+
reject_(reason);
|
|
239855
|
+
cleanup();
|
|
239856
|
+
};
|
|
239857
|
+
if (signal) {
|
|
239858
|
+
if (signal.aborted) {
|
|
239859
|
+
reject(signal.reason);
|
|
239860
|
+
return;
|
|
239861
|
+
}
|
|
239862
|
+
signal.addEventListener("abort", signalListener, { once: true });
|
|
239863
|
+
}
|
|
239864
|
+
const next = async () => {
|
|
239865
|
+
if (isResolved) {
|
|
239866
|
+
return;
|
|
239867
|
+
}
|
|
239868
|
+
const nextItem = await iterator.next();
|
|
239869
|
+
const index = currentIndex;
|
|
239870
|
+
currentIndex++;
|
|
239871
|
+
if (nextItem.done) {
|
|
239872
|
+
isIterableDone = true;
|
|
239873
|
+
if (resolvingCount === 0 && !isResolved) {
|
|
239874
|
+
if (!stopOnError && errors.length > 0) {
|
|
239875
|
+
reject(new AggregateError(errors));
|
|
239876
|
+
return;
|
|
239877
|
+
}
|
|
239878
|
+
isResolved = true;
|
|
239879
|
+
if (skippedIndexesMap.size === 0) {
|
|
239880
|
+
resolve(result);
|
|
239881
|
+
return;
|
|
239882
|
+
}
|
|
239883
|
+
const pureResult = [];
|
|
239884
|
+
for (const [index, value] of result.entries()) {
|
|
239885
|
+
if (skippedIndexesMap.get(index) === pMapSkip) {
|
|
239886
|
+
continue;
|
|
239887
|
+
}
|
|
239888
|
+
pureResult.push(value);
|
|
239889
|
+
}
|
|
239890
|
+
resolve(pureResult);
|
|
239891
|
+
}
|
|
239892
|
+
return;
|
|
239893
|
+
}
|
|
239894
|
+
resolvingCount++;
|
|
239895
|
+
(async () => {
|
|
239896
|
+
try {
|
|
239897
|
+
const element = await nextItem.value;
|
|
239898
|
+
if (isResolved) {
|
|
239899
|
+
return;
|
|
239900
|
+
}
|
|
239901
|
+
const value = await mapper(element, index);
|
|
239902
|
+
if (value === pMapSkip) {
|
|
239903
|
+
skippedIndexesMap.set(index, value);
|
|
239904
|
+
}
|
|
239905
|
+
result[index] = value;
|
|
239906
|
+
resolvingCount--;
|
|
239907
|
+
await next();
|
|
239908
|
+
} catch (error) {
|
|
239909
|
+
if (stopOnError) {
|
|
239910
|
+
reject(error);
|
|
239911
|
+
} else {
|
|
239912
|
+
errors.push(error);
|
|
239913
|
+
resolvingCount--;
|
|
239914
|
+
try {
|
|
239915
|
+
await next();
|
|
239916
|
+
} catch (error) {
|
|
239917
|
+
reject(error);
|
|
239918
|
+
}
|
|
239919
|
+
}
|
|
239920
|
+
}
|
|
239921
|
+
})();
|
|
239922
|
+
};
|
|
239923
|
+
(async () => {
|
|
239924
|
+
for (let index = 0;index < concurrency; index++) {
|
|
239925
|
+
try {
|
|
239926
|
+
await next();
|
|
239927
|
+
} catch (error) {
|
|
239928
|
+
reject(error);
|
|
239929
|
+
break;
|
|
239930
|
+
}
|
|
239931
|
+
if (isIterableDone || isRejected) {
|
|
239932
|
+
break;
|
|
239933
|
+
}
|
|
239934
|
+
}
|
|
239935
|
+
})();
|
|
239936
|
+
});
|
|
239937
|
+
}
|
|
239938
|
+
var pMapSkip = Symbol("skip");
|
|
239939
|
+
|
|
239940
|
+
// src/core/site/manifest.ts
|
|
239613
239941
|
var MAX_ASSET_COUNT = 1e5;
|
|
239614
239942
|
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
239615
239943
|
var ALWAYS_IGNORED = new Set([
|
|
@@ -239650,30 +239978,42 @@ var MIME_TYPES = {
|
|
|
239650
239978
|
function getAssetContentType(filePath) {
|
|
239651
239979
|
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
239652
239980
|
}
|
|
239653
|
-
async function
|
|
239654
|
-
const
|
|
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) {
|
|
239655
240000
|
for await (const chunk of createReadStream(absolutePath)) {
|
|
239656
240001
|
hash.update(chunk);
|
|
239657
240002
|
}
|
|
240003
|
+
return hash;
|
|
240004
|
+
}
|
|
240005
|
+
async function hashAssetFile(appId, absolutePath) {
|
|
240006
|
+
const hash = await hashFileInto(createHash("sha256").update(Buffer.from(appId, "utf8")), absolutePath);
|
|
239658
240007
|
return hash.digest("hex").slice(0, 32);
|
|
239659
240008
|
}
|
|
239660
240009
|
async function buildAssetManifest(assetsDir, appId) {
|
|
239661
240010
|
const manifest = {};
|
|
239662
240011
|
const filesByHash = new Map;
|
|
239663
|
-
const
|
|
239664
|
-
|
|
239665
|
-
|
|
239666
|
-
onlyFiles: true,
|
|
239667
|
-
followSymbolicLinks: false,
|
|
239668
|
-
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
239669
|
-
});
|
|
239670
|
-
const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
|
|
239671
|
-
if (relativeFilePaths.length > MAX_ASSET_COUNT) {
|
|
239672
|
-
throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
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.`);
|
|
239673
240015
|
}
|
|
239674
|
-
for (const relativePath of
|
|
239675
|
-
const absolutePath = join16(assetsDir, ...relativePath.split("/"));
|
|
239676
|
-
const { size } = await stat(absolutePath);
|
|
240016
|
+
for (const { path: relativePath, absolutePath, size } of files) {
|
|
239677
240017
|
const hash = await hashAssetFile(appId, absolutePath);
|
|
239678
240018
|
manifest[`/${relativePath}`] = { hash, size };
|
|
239679
240019
|
if (!filesByHash.has(hash)) {
|
|
@@ -239688,229 +240028,8 @@ async function buildAssetManifest(assetsDir, appId) {
|
|
|
239688
240028
|
return { manifest, filesByHash };
|
|
239689
240029
|
}
|
|
239690
240030
|
|
|
239691
|
-
// src/core/site/modules.ts
|
|
239692
|
-
import { stat as stat2 } from "node:fs/promises";
|
|
239693
|
-
import { relative as relative5, resolve as resolve3, sep } from "node:path";
|
|
239694
|
-
var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
|
|
239695
|
-
var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
|
|
239696
|
-
var RULE_TYPE_TO_MODULE_TYPE = {
|
|
239697
|
-
ESModule: "esm",
|
|
239698
|
-
CompiledWasm: "wasm",
|
|
239699
|
-
Text: "text",
|
|
239700
|
-
Data: "data"
|
|
239701
|
-
};
|
|
239702
|
-
function toPosix(path) {
|
|
239703
|
-
return path.split(sep).join("/");
|
|
239704
|
-
}
|
|
239705
|
-
async function collectModules(config) {
|
|
239706
|
-
const entryPath = resolve3(config.configDir, config.main);
|
|
239707
|
-
if (!await pathExists(entryPath)) {
|
|
239708
|
-
throw new InvalidInputError(`Worker entry module does not exist: ${entryPath} (from "main" in ${config.configPath})`, {
|
|
239709
|
-
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
239710
|
-
});
|
|
239711
|
-
}
|
|
239712
|
-
const modulesByName = new Map;
|
|
239713
|
-
const entryName = toPosix(relative5(config.configDir, entryPath));
|
|
239714
|
-
modulesByName.set(entryName, {
|
|
239715
|
-
name: entryName,
|
|
239716
|
-
absolutePath: entryPath,
|
|
239717
|
-
size: 0,
|
|
239718
|
-
type: "esm"
|
|
239719
|
-
});
|
|
239720
|
-
const ignore = [...MODULE_IGNORE];
|
|
239721
|
-
if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
|
|
239722
|
-
ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
|
|
239723
|
-
}
|
|
239724
|
-
for (const rule of config.rules) {
|
|
239725
|
-
const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
|
|
239726
|
-
if (!type) {
|
|
239727
|
-
throw new InvalidInputError(`Unsupported module rule type "${rule.type}" in ${config.configPath}. Supported: ${Object.keys(RULE_TYPE_TO_MODULE_TYPE).join(", ")}.`);
|
|
239728
|
-
}
|
|
239729
|
-
const matches = await globby(rule.globs, {
|
|
239730
|
-
cwd: config.configDir,
|
|
239731
|
-
onlyFiles: true,
|
|
239732
|
-
dot: true,
|
|
239733
|
-
ignore
|
|
239734
|
-
});
|
|
239735
|
-
for (const match of matches.sort()) {
|
|
239736
|
-
if (!modulesByName.has(match)) {
|
|
239737
|
-
modulesByName.set(match, {
|
|
239738
|
-
name: match,
|
|
239739
|
-
absolutePath: resolve3(config.configDir, match),
|
|
239740
|
-
size: 0,
|
|
239741
|
-
type
|
|
239742
|
-
});
|
|
239743
|
-
}
|
|
239744
|
-
}
|
|
239745
|
-
}
|
|
239746
|
-
if (config.uploadSourceMaps) {
|
|
239747
|
-
const maps = await globby("**/*.map", {
|
|
239748
|
-
cwd: config.configDir,
|
|
239749
|
-
onlyFiles: true,
|
|
239750
|
-
dot: true,
|
|
239751
|
-
ignore
|
|
239752
|
-
});
|
|
239753
|
-
for (const map of maps.sort()) {
|
|
239754
|
-
addSourcemap(modulesByName, config.configDir, map);
|
|
239755
|
-
}
|
|
239756
|
-
} else {
|
|
239757
|
-
for (const name of [...modulesByName.keys()]) {
|
|
239758
|
-
const mapName = `${name}.map`;
|
|
239759
|
-
if (await pathExists(resolve3(config.configDir, mapName))) {
|
|
239760
|
-
addSourcemap(modulesByName, config.configDir, mapName);
|
|
239761
|
-
}
|
|
239762
|
-
}
|
|
239763
|
-
}
|
|
239764
|
-
const modules = [...modulesByName.values()];
|
|
239765
|
-
let totalBytes = 0;
|
|
239766
|
-
for (const module of modules) {
|
|
239767
|
-
module.size = (await stat2(module.absolutePath)).size;
|
|
239768
|
-
totalBytes += module.size;
|
|
239769
|
-
}
|
|
239770
|
-
if (totalBytes > MAX_TOTAL_MODULE_BYTES) {
|
|
239771
|
-
throw new InvalidInputError(`Worker modules total ${totalBytes} bytes, which exceeds the 40 MB limit for a Base44 deploy.`);
|
|
239772
|
-
}
|
|
239773
|
-
return modules;
|
|
239774
|
-
}
|
|
239775
|
-
function addSourcemap(modulesByName, configDir, name) {
|
|
239776
|
-
if (modulesByName.has(name))
|
|
239777
|
-
return;
|
|
239778
|
-
modulesByName.set(name, {
|
|
239779
|
-
name,
|
|
239780
|
-
absolutePath: resolve3(configDir, name),
|
|
239781
|
-
size: 0,
|
|
239782
|
-
type: "sourcemap"
|
|
239783
|
-
});
|
|
239784
|
-
}
|
|
239785
|
-
|
|
239786
240031
|
// src/core/site/upload.ts
|
|
239787
240032
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
239788
|
-
|
|
239789
|
-
// ../../node_modules/p-map/index.js
|
|
239790
|
-
async function pMap(iterable, mapper, {
|
|
239791
|
-
concurrency = Number.POSITIVE_INFINITY,
|
|
239792
|
-
stopOnError = true,
|
|
239793
|
-
signal
|
|
239794
|
-
} = {}) {
|
|
239795
|
-
return new Promise((resolve_, reject_) => {
|
|
239796
|
-
if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
|
|
239797
|
-
throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
|
|
239798
|
-
}
|
|
239799
|
-
if (typeof mapper !== "function") {
|
|
239800
|
-
throw new TypeError("Mapper function is required");
|
|
239801
|
-
}
|
|
239802
|
-
if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
|
|
239803
|
-
throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
|
|
239804
|
-
}
|
|
239805
|
-
const result = [];
|
|
239806
|
-
const errors = [];
|
|
239807
|
-
const skippedIndexesMap = new Map;
|
|
239808
|
-
let isRejected = false;
|
|
239809
|
-
let isResolved = false;
|
|
239810
|
-
let isIterableDone = false;
|
|
239811
|
-
let resolvingCount = 0;
|
|
239812
|
-
let currentIndex = 0;
|
|
239813
|
-
const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
|
|
239814
|
-
const signalListener = () => {
|
|
239815
|
-
reject(signal.reason);
|
|
239816
|
-
};
|
|
239817
|
-
const cleanup = () => {
|
|
239818
|
-
signal?.removeEventListener("abort", signalListener);
|
|
239819
|
-
};
|
|
239820
|
-
const resolve = (value) => {
|
|
239821
|
-
resolve_(value);
|
|
239822
|
-
cleanup();
|
|
239823
|
-
};
|
|
239824
|
-
const reject = (reason) => {
|
|
239825
|
-
isRejected = true;
|
|
239826
|
-
isResolved = true;
|
|
239827
|
-
reject_(reason);
|
|
239828
|
-
cleanup();
|
|
239829
|
-
};
|
|
239830
|
-
if (signal) {
|
|
239831
|
-
if (signal.aborted) {
|
|
239832
|
-
reject(signal.reason);
|
|
239833
|
-
return;
|
|
239834
|
-
}
|
|
239835
|
-
signal.addEventListener("abort", signalListener, { once: true });
|
|
239836
|
-
}
|
|
239837
|
-
const next = async () => {
|
|
239838
|
-
if (isResolved) {
|
|
239839
|
-
return;
|
|
239840
|
-
}
|
|
239841
|
-
const nextItem = await iterator.next();
|
|
239842
|
-
const index = currentIndex;
|
|
239843
|
-
currentIndex++;
|
|
239844
|
-
if (nextItem.done) {
|
|
239845
|
-
isIterableDone = true;
|
|
239846
|
-
if (resolvingCount === 0 && !isResolved) {
|
|
239847
|
-
if (!stopOnError && errors.length > 0) {
|
|
239848
|
-
reject(new AggregateError(errors));
|
|
239849
|
-
return;
|
|
239850
|
-
}
|
|
239851
|
-
isResolved = true;
|
|
239852
|
-
if (skippedIndexesMap.size === 0) {
|
|
239853
|
-
resolve(result);
|
|
239854
|
-
return;
|
|
239855
|
-
}
|
|
239856
|
-
const pureResult = [];
|
|
239857
|
-
for (const [index, value] of result.entries()) {
|
|
239858
|
-
if (skippedIndexesMap.get(index) === pMapSkip) {
|
|
239859
|
-
continue;
|
|
239860
|
-
}
|
|
239861
|
-
pureResult.push(value);
|
|
239862
|
-
}
|
|
239863
|
-
resolve(pureResult);
|
|
239864
|
-
}
|
|
239865
|
-
return;
|
|
239866
|
-
}
|
|
239867
|
-
resolvingCount++;
|
|
239868
|
-
(async () => {
|
|
239869
|
-
try {
|
|
239870
|
-
const element = await nextItem.value;
|
|
239871
|
-
if (isResolved) {
|
|
239872
|
-
return;
|
|
239873
|
-
}
|
|
239874
|
-
const value = await mapper(element, index);
|
|
239875
|
-
if (value === pMapSkip) {
|
|
239876
|
-
skippedIndexesMap.set(index, value);
|
|
239877
|
-
}
|
|
239878
|
-
result[index] = value;
|
|
239879
|
-
resolvingCount--;
|
|
239880
|
-
await next();
|
|
239881
|
-
} catch (error) {
|
|
239882
|
-
if (stopOnError) {
|
|
239883
|
-
reject(error);
|
|
239884
|
-
} else {
|
|
239885
|
-
errors.push(error);
|
|
239886
|
-
resolvingCount--;
|
|
239887
|
-
try {
|
|
239888
|
-
await next();
|
|
239889
|
-
} catch (error) {
|
|
239890
|
-
reject(error);
|
|
239891
|
-
}
|
|
239892
|
-
}
|
|
239893
|
-
}
|
|
239894
|
-
})();
|
|
239895
|
-
};
|
|
239896
|
-
(async () => {
|
|
239897
|
-
for (let index = 0;index < concurrency; index++) {
|
|
239898
|
-
try {
|
|
239899
|
-
await next();
|
|
239900
|
-
} catch (error) {
|
|
239901
|
-
reject(error);
|
|
239902
|
-
break;
|
|
239903
|
-
}
|
|
239904
|
-
if (isIterableDone || isRejected) {
|
|
239905
|
-
break;
|
|
239906
|
-
}
|
|
239907
|
-
}
|
|
239908
|
-
})();
|
|
239909
|
-
});
|
|
239910
|
-
}
|
|
239911
|
-
var pMapSkip = Symbol("skip");
|
|
239912
|
-
|
|
239913
|
-
// src/core/site/upload.ts
|
|
239914
240033
|
var DEFAULT_UPLOAD_CONCURRENCY = 3;
|
|
239915
240034
|
var MAX_UPLOAD_CONCURRENCY = 50;
|
|
239916
240035
|
var MAX_UPLOAD_ATTEMPTS = 3;
|
|
@@ -240009,11 +240128,17 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
240009
240128
|
if (!file) {
|
|
240010
240129
|
throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
|
|
240011
240130
|
}
|
|
240012
|
-
|
|
240131
|
+
await putPresigned(upload, file.absolutePath);
|
|
240132
|
+
}
|
|
240133
|
+
async function putPresigned(upload, absolutePath) {
|
|
240134
|
+
const content = await readFile2(absolutePath);
|
|
240013
240135
|
try {
|
|
240014
240136
|
await distribution_default.put(upload.url, {
|
|
240015
240137
|
body: new Uint8Array(content),
|
|
240016
|
-
headers: {
|
|
240138
|
+
headers: {
|
|
240139
|
+
"Content-Type": upload.contentType,
|
|
240140
|
+
...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
|
|
240141
|
+
},
|
|
240017
240142
|
timeout: 120000,
|
|
240018
240143
|
retry: UPLOAD_RETRY
|
|
240019
240144
|
});
|
|
@@ -240022,85 +240147,6 @@ async function uploadPresignedAsset(upload, assets) {
|
|
|
240022
240147
|
}
|
|
240023
240148
|
}
|
|
240024
240149
|
|
|
240025
|
-
// src/core/site/wrangler-config.ts
|
|
240026
|
-
import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
|
|
240027
|
-
var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
|
|
240028
|
-
var RedirectConfigSchema = looseObject({
|
|
240029
|
-
configPath: string2().min(1)
|
|
240030
|
-
});
|
|
240031
|
-
var WranglerConfigSchema = looseObject({
|
|
240032
|
-
main: string2().min(1, "wrangler config is missing a 'main' entry module"),
|
|
240033
|
-
no_bundle: boolean2().optional(),
|
|
240034
|
-
rules: array(looseObject({ type: string2(), globs: array(string2()) })).optional(),
|
|
240035
|
-
assets: looseObject({
|
|
240036
|
-
directory: string2().optional(),
|
|
240037
|
-
html_handling: string2().optional(),
|
|
240038
|
-
not_found_handling: string2().optional(),
|
|
240039
|
-
run_worker_first: union([boolean2(), array(string2())]).optional(),
|
|
240040
|
-
headers: string2().optional(),
|
|
240041
|
-
redirects: string2().optional()
|
|
240042
|
-
}).optional(),
|
|
240043
|
-
compatibility_date: string2().optional(),
|
|
240044
|
-
compatibility_flags: array(string2()).optional(),
|
|
240045
|
-
vars: record(string2(), unknown()).optional(),
|
|
240046
|
-
upload_source_maps: boolean2().optional()
|
|
240047
|
-
});
|
|
240048
|
-
async function detectFullStackArtifact(projectRoot) {
|
|
240049
|
-
const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
|
|
240050
|
-
return await pathExists(redirectPath) ? redirectPath : null;
|
|
240051
|
-
}
|
|
240052
|
-
async function resolveWranglerConfig(redirectPath) {
|
|
240053
|
-
const configPath = await resolveRedirectedConfigPath(redirectPath);
|
|
240054
|
-
const parsed = await readJsonFile(configPath);
|
|
240055
|
-
const result = WranglerConfigSchema.safeParse(parsed);
|
|
240056
|
-
if (!result.success) {
|
|
240057
|
-
throw new ConfigInvalidError(`Invalid wrangler config: ${prettifyError(result.error)}`, configPath);
|
|
240058
|
-
}
|
|
240059
|
-
const config = result.data;
|
|
240060
|
-
if (config.no_bundle !== true) {
|
|
240061
|
-
throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
|
|
240062
|
-
}
|
|
240063
|
-
const configDir = dirname12(configPath);
|
|
240064
|
-
const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
|
|
240065
|
-
return {
|
|
240066
|
-
configPath,
|
|
240067
|
-
configDir,
|
|
240068
|
-
main: config.main,
|
|
240069
|
-
assetsDirectory,
|
|
240070
|
-
assetsConfig: config.assets ? toResolvedAssetsConfig(config.assets) : null,
|
|
240071
|
-
compatibilityDate: config.compatibility_date ?? null,
|
|
240072
|
-
compatibilityFlags: config.compatibility_flags ?? [],
|
|
240073
|
-
rules: (config.rules ?? []).map((rule) => ({
|
|
240074
|
-
type: rule.type,
|
|
240075
|
-
globs: rule.globs
|
|
240076
|
-
})),
|
|
240077
|
-
uploadSourceMaps: config.upload_source_maps ?? false
|
|
240078
|
-
};
|
|
240079
|
-
}
|
|
240080
|
-
async function resolveRedirectedConfigPath(redirectPath) {
|
|
240081
|
-
const parsed = await readJsonFile(redirectPath);
|
|
240082
|
-
const result = RedirectConfigSchema.safeParse(parsed);
|
|
240083
|
-
if (!result.success) {
|
|
240084
|
-
throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
|
|
240085
|
-
}
|
|
240086
|
-
const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
|
|
240087
|
-
if (!await pathExists(configPath)) {
|
|
240088
|
-
throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
|
|
240089
|
-
hints: [{ message: "Rebuild the project to regenerate the artifact" }]
|
|
240090
|
-
});
|
|
240091
|
-
}
|
|
240092
|
-
return configPath;
|
|
240093
|
-
}
|
|
240094
|
-
function toResolvedAssetsConfig(assets) {
|
|
240095
|
-
return {
|
|
240096
|
-
htmlHandling: assets.html_handling,
|
|
240097
|
-
notFoundHandling: assets.not_found_handling,
|
|
240098
|
-
runWorkerFirst: assets.run_worker_first,
|
|
240099
|
-
headers: assets.headers,
|
|
240100
|
-
redirects: assets.redirects
|
|
240101
|
-
};
|
|
240102
|
-
}
|
|
240103
|
-
|
|
240104
240150
|
// src/core/site/deployment.ts
|
|
240105
240151
|
var NO_ASSETS = { manifest: {}, filesByHash: new Map };
|
|
240106
240152
|
var DEPLOYMENTS_API_ENV = "BASE44_DEPLOYMENTS_API";
|
|
@@ -240108,9 +240154,6 @@ function deploymentsApiEnabled(env = process.env) {
|
|
|
240108
240154
|
const value = env[DEPLOYMENTS_API_ENV];
|
|
240109
240155
|
return value === "1" || value === "true";
|
|
240110
240156
|
}
|
|
240111
|
-
async function hasWorkerBuild(projectRoot) {
|
|
240112
|
-
return await detectFullStackArtifact(projectRoot) !== null;
|
|
240113
|
-
}
|
|
240114
240157
|
async function deployToDeployments(options) {
|
|
240115
240158
|
const { projectRoot, outputDir, gitHash, concurrency, progress } = options;
|
|
240116
240159
|
const worker = await resolveWorkerBuild(projectRoot, progress);
|
|
@@ -240133,12 +240176,11 @@ async function deployToDeployments(options) {
|
|
|
240133
240176
|
return { deploymentId: finalized.deploymentId, gitHash };
|
|
240134
240177
|
}
|
|
240135
240178
|
async function resolveWorkerBuild(projectRoot, progress) {
|
|
240136
|
-
const
|
|
240137
|
-
if (!
|
|
240179
|
+
const built = await resolveFullStackBuild(projectRoot);
|
|
240180
|
+
if (!built) {
|
|
240138
240181
|
return null;
|
|
240139
240182
|
}
|
|
240140
|
-
const config =
|
|
240141
|
-
const assetsDir = config.assetsDirectory && await pathExists(config.assetsDirectory) ? config.assetsDirectory : null;
|
|
240183
|
+
const { config, modules, assetsDir } = built;
|
|
240142
240184
|
return {
|
|
240143
240185
|
config: {
|
|
240144
240186
|
main: config.main,
|
|
@@ -240146,7 +240188,7 @@ async function resolveWorkerBuild(projectRoot, progress) {
|
|
|
240146
240188
|
compatibility_flags: config.compatibilityFlags,
|
|
240147
240189
|
assets: buildAssetsConfig(config.assetsConfig, progress)
|
|
240148
240190
|
},
|
|
240149
|
-
modules
|
|
240191
|
+
modules,
|
|
240150
240192
|
assetsDir
|
|
240151
240193
|
};
|
|
240152
240194
|
}
|
|
@@ -246699,6 +246741,13 @@ async function resolveGitHash(projectRoot, explicit) {
|
|
|
246699
246741
|
}
|
|
246700
246742
|
return hash;
|
|
246701
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
|
+
}
|
|
246702
246751
|
async function gitHead(projectRoot) {
|
|
246703
246752
|
try {
|
|
246704
246753
|
const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
|
|
@@ -246710,7 +246759,7 @@ async function gitHead(projectRoot) {
|
|
|
246710
246759
|
}
|
|
246711
246760
|
}
|
|
246712
246761
|
// src/core/project/deploy.ts
|
|
246713
|
-
function hasResourcesToDeploy(projectData
|
|
246762
|
+
function hasResourcesToDeploy(projectData) {
|
|
246714
246763
|
const {
|
|
246715
246764
|
project,
|
|
246716
246765
|
entities,
|
|
@@ -246721,7 +246770,7 @@ function hasResourcesToDeploy(projectData, options = {}) {
|
|
|
246721
246770
|
connectors,
|
|
246722
246771
|
authConfig
|
|
246723
246772
|
} = projectData;
|
|
246724
|
-
const hasSite = Boolean(project.site?.outputDirectory)
|
|
246773
|
+
const hasSite = Boolean(project.site?.outputDirectory);
|
|
246725
246774
|
const hasEntities = entities.length > 0;
|
|
246726
246775
|
const hasFunctions = functions.length > 0;
|
|
246727
246776
|
const hasActors = actors.length > 0;
|
|
@@ -246743,7 +246792,6 @@ async function deployAll(projectData, options) {
|
|
|
246743
246792
|
connectors,
|
|
246744
246793
|
authConfig
|
|
246745
246794
|
} = projectData;
|
|
246746
|
-
const workerGitHash = await hasWorkerBuild(project.root) ? await resolveGitHash(project.root) : null;
|
|
246747
246795
|
await setAppVisibility(project.visibility);
|
|
246748
246796
|
if (project.visibility) {
|
|
246749
246797
|
options?.onVisibilitySet?.(project.visibility);
|
|
@@ -246781,24 +246829,56 @@ async function deployAll(projectData, options) {
|
|
|
246781
246829
|
await authConfigResource.push(authConfig);
|
|
246782
246830
|
const skipConnectorSync = connectors.length === 0 && hasWorkspaceApiKeyAuth();
|
|
246783
246831
|
const connectorResults = skipConnectorSync ? [] : (await pushConnectors(connectors)).results;
|
|
246784
|
-
|
|
246785
|
-
|
|
246786
|
-
const { deploymentId } = await deployToDeployments({
|
|
246787
|
-
projectRoot: project.root,
|
|
246788
|
-
outputDir,
|
|
246789
|
-
gitHash: workerGitHash
|
|
246790
|
-
});
|
|
246791
|
-
return {
|
|
246792
|
-
deployment: { deploymentId, gitHash: workerGitHash },
|
|
246793
|
-
connectorResults
|
|
246794
|
-
};
|
|
246795
|
-
}
|
|
246796
|
-
if (outputDir) {
|
|
246832
|
+
if (project.site?.outputDirectory) {
|
|
246833
|
+
const outputDir = resolve5(project.root, project.site.outputDirectory);
|
|
246797
246834
|
const { appUrl } = await deploySite(outputDir);
|
|
246798
246835
|
return { appUrl, connectorResults };
|
|
246799
246836
|
}
|
|
246800
246837
|
return { connectorResults };
|
|
246801
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
|
+
}
|
|
246802
246882
|
// src/core/clients/base44-client.ts
|
|
246803
246883
|
var retriedRequests = new WeakSet;
|
|
246804
246884
|
async function captureRequestBody(request, options) {
|
|
@@ -247080,6 +247160,12 @@ async function ensureAppContext(ctx, options = {}) {
|
|
|
247080
247160
|
ctx.app = appContext;
|
|
247081
247161
|
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
247082
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
|
+
}
|
|
247083
247169
|
|
|
247084
247170
|
// src/cli/utils/version-check.ts
|
|
247085
247171
|
async function checkForUpgrade() {
|
|
@@ -247263,6 +247349,10 @@ function writeJsonError(error) {
|
|
|
247263
247349
|
const envelope = {
|
|
247264
247350
|
error: error instanceof Error ? error.message : String(error)
|
|
247265
247351
|
};
|
|
247352
|
+
const step = stepOf(error);
|
|
247353
|
+
if (step !== undefined) {
|
|
247354
|
+
envelope.step = step;
|
|
247355
|
+
}
|
|
247266
247356
|
if (isCLIError(error)) {
|
|
247267
247357
|
envelope.code = error.code;
|
|
247268
247358
|
if (error.details.length > 0) {
|
|
@@ -247632,7 +247722,7 @@ function getActorsCommand() {
|
|
|
247632
247722
|
}
|
|
247633
247723
|
|
|
247634
247724
|
// src/cli/commands/agent-skills/pull.ts
|
|
247635
|
-
import { dirname as
|
|
247725
|
+
import { dirname as dirname14, join as join20 } from "node:path";
|
|
247636
247726
|
// src/core/utils/dependencies.ts
|
|
247637
247727
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
247638
247728
|
function verifyDenoInstalled(context) {
|
|
@@ -247721,7 +247811,7 @@ async function pullAction({
|
|
|
247721
247811
|
runTask
|
|
247722
247812
|
}) {
|
|
247723
247813
|
const { project } = await readProjectConfig();
|
|
247724
|
-
const dir =
|
|
247814
|
+
const dir = join20(dirname14(project.configPath), project.agentSkillsDir);
|
|
247725
247815
|
const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
|
|
247726
247816
|
successMessage: "Agent skills fetched successfully",
|
|
247727
247817
|
errorMessage: "Failed to fetch agent skills"
|
|
@@ -247777,14 +247867,14 @@ function getAgentSkillsCommand() {
|
|
|
247777
247867
|
}
|
|
247778
247868
|
|
|
247779
247869
|
// src/cli/commands/agents/pull.ts
|
|
247780
|
-
import { dirname as
|
|
247870
|
+
import { dirname as dirname15, join as join21 } from "node:path";
|
|
247781
247871
|
async function pullAgentsAction({
|
|
247782
247872
|
log,
|
|
247783
247873
|
runTask
|
|
247784
247874
|
}) {
|
|
247785
247875
|
const { project } = await readProjectConfig();
|
|
247786
|
-
const configDir =
|
|
247787
|
-
const agentsDir =
|
|
247876
|
+
const configDir = dirname15(project.configPath);
|
|
247877
|
+
const agentsDir = join21(configDir, project.agentsDir);
|
|
247788
247878
|
const remoteAgents = await runTask("Fetching agents from Base44", async () => {
|
|
247789
247879
|
return await fetchAgents();
|
|
247790
247880
|
}, {
|
|
@@ -247854,12 +247944,12 @@ function getAgentsCommand() {
|
|
|
247854
247944
|
}
|
|
247855
247945
|
|
|
247856
247946
|
// src/cli/commands/auth/password-login.ts
|
|
247857
|
-
import { dirname as
|
|
247947
|
+
import { dirname as dirname16, join as join22 } from "node:path";
|
|
247858
247948
|
async function passwordLoginAction({ log, runTask }, action) {
|
|
247859
247949
|
const shouldEnable = action === "enable";
|
|
247860
247950
|
const { project } = await readProjectConfig();
|
|
247861
|
-
const configDir =
|
|
247862
|
-
const authDir =
|
|
247951
|
+
const configDir = dirname16(project.configPath);
|
|
247952
|
+
const authDir = join22(configDir, project.authDir);
|
|
247863
247953
|
const updated = await runTask("Updating local auth config", async () => {
|
|
247864
247954
|
const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
|
|
247865
247955
|
const merged = { ...current, enableUsernamePassword: shouldEnable };
|
|
@@ -247879,14 +247969,14 @@ function getPasswordLoginCommand() {
|
|
|
247879
247969
|
}
|
|
247880
247970
|
|
|
247881
247971
|
// src/cli/commands/auth/pull.ts
|
|
247882
|
-
import { dirname as
|
|
247972
|
+
import { dirname as dirname17, join as join23 } from "node:path";
|
|
247883
247973
|
async function pullAuthAction({
|
|
247884
247974
|
log,
|
|
247885
247975
|
runTask
|
|
247886
247976
|
}) {
|
|
247887
247977
|
const { project } = await readProjectConfig();
|
|
247888
|
-
const configDir =
|
|
247889
|
-
const authDir =
|
|
247978
|
+
const configDir = dirname17(project.configPath);
|
|
247979
|
+
const authDir = join23(configDir, project.authDir);
|
|
247890
247980
|
const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
|
|
247891
247981
|
return await pullAuthConfig();
|
|
247892
247982
|
}, {
|
|
@@ -247950,7 +248040,7 @@ function getAuthPushCommand() {
|
|
|
247950
248040
|
}
|
|
247951
248041
|
|
|
247952
248042
|
// src/cli/commands/auth/social-login.ts
|
|
247953
|
-
import { dirname as
|
|
248043
|
+
import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
|
|
247954
248044
|
var PROVIDER_LABELS = {
|
|
247955
248045
|
google: "Google",
|
|
247956
248046
|
microsoft: "Microsoft",
|
|
@@ -247990,7 +248080,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
247990
248080
|
let clientSecret;
|
|
247991
248081
|
if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
|
|
247992
248082
|
if (options.envFile) {
|
|
247993
|
-
const secrets = await parseEnvFile(
|
|
248083
|
+
const secrets = await parseEnvFile(resolve7(options.envFile));
|
|
247994
248084
|
const value = secrets[oauthCli.envVar];
|
|
247995
248085
|
if (!value) {
|
|
247996
248086
|
throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
|
|
@@ -248020,8 +248110,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
248020
248110
|
}
|
|
248021
248111
|
}
|
|
248022
248112
|
const { project } = await readProjectConfig();
|
|
248023
|
-
const configDir =
|
|
248024
|
-
const authDir =
|
|
248113
|
+
const configDir = dirname18(project.configPath);
|
|
248114
|
+
const authDir = join24(configDir, project.authDir);
|
|
248025
248115
|
const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
|
|
248026
248116
|
if (clientSecret) {
|
|
248027
248117
|
await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
|
|
@@ -248046,7 +248136,7 @@ function getSocialLoginCommand() {
|
|
|
248046
248136
|
}
|
|
248047
248137
|
|
|
248048
248138
|
// src/cli/commands/auth/sso.ts
|
|
248049
|
-
import { dirname as
|
|
248139
|
+
import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
|
|
248050
248140
|
var SSOConfigFileSchema = object({
|
|
248051
248141
|
provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
248052
248142
|
clientId: string2(),
|
|
@@ -248062,7 +248152,7 @@ var SSOConfigFileSchema = object({
|
|
|
248062
248152
|
ssoName: string2().optional()
|
|
248063
248153
|
});
|
|
248064
248154
|
async function loadSSOConfigFile(filePath) {
|
|
248065
|
-
const resolved =
|
|
248155
|
+
const resolved = resolve8(filePath);
|
|
248066
248156
|
const raw = await readJsonFile(resolved);
|
|
248067
248157
|
const result = SSOConfigFileSchema.safeParse(raw);
|
|
248068
248158
|
if (!result.success) {
|
|
@@ -248150,7 +248240,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248150
248240
|
}
|
|
248151
248241
|
let clientSecret;
|
|
248152
248242
|
if (merged.envFile && !merged.clientSecret) {
|
|
248153
|
-
const secrets = await parseEnvFile(
|
|
248243
|
+
const secrets = await parseEnvFile(resolve8(merged.envFile));
|
|
248154
248244
|
const value = secrets.sso_client_secret;
|
|
248155
248245
|
if (!value) {
|
|
248156
248246
|
throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
|
|
@@ -248209,8 +248299,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248209
248299
|
throw error;
|
|
248210
248300
|
}
|
|
248211
248301
|
const { project } = await readProjectConfig();
|
|
248212
|
-
const configDir =
|
|
248213
|
-
const authDir =
|
|
248302
|
+
const configDir = dirname19(project.configPath);
|
|
248303
|
+
const authDir = join25(configDir, project.authDir);
|
|
248214
248304
|
await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
|
|
248215
248305
|
await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
|
|
248216
248306
|
return {
|
|
@@ -248225,8 +248315,8 @@ async function ssoDisableAction({ log, runTask }, options) {
|
|
|
248225
248315
|
throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
|
|
248226
248316
|
}
|
|
248227
248317
|
const { project } = await readProjectConfig();
|
|
248228
|
-
const configDir =
|
|
248229
|
-
const authDir =
|
|
248318
|
+
const configDir = dirname19(project.configPath);
|
|
248319
|
+
const authDir = join25(configDir, project.authDir);
|
|
248230
248320
|
const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
|
|
248231
248321
|
await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
|
|
248232
248322
|
if (!hasAnyLoginMethod(updated)) {
|
|
@@ -249108,13 +249198,13 @@ function getConnectorsListAvailableCommand() {
|
|
|
249108
249198
|
}
|
|
249109
249199
|
|
|
249110
249200
|
// src/cli/commands/connectors/pull.ts
|
|
249111
|
-
import { dirname as
|
|
249201
|
+
import { dirname as dirname20, join as join26, resolve as resolve9 } from "node:path";
|
|
249112
249202
|
async function resolveConnectorsDir(options) {
|
|
249113
249203
|
if (!getAppContext().projectRoot) {
|
|
249114
|
-
return
|
|
249204
|
+
return resolve9(options.dir ?? "connectors");
|
|
249115
249205
|
}
|
|
249116
249206
|
const { project } = await readProjectConfig();
|
|
249117
|
-
return
|
|
249207
|
+
return join26(dirname20(project.configPath), project.connectorsDir);
|
|
249118
249208
|
}
|
|
249119
249209
|
async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
|
|
249120
249210
|
const connectorsDir = await resolveConnectorsDir(options);
|
|
@@ -249155,10 +249245,10 @@ function getConnectorsPullCommand() {
|
|
|
249155
249245
|
}
|
|
249156
249246
|
|
|
249157
249247
|
// src/cli/commands/connectors/push.ts
|
|
249158
|
-
import { resolve as
|
|
249248
|
+
import { resolve as resolve10 } from "node:path";
|
|
249159
249249
|
async function readConnectorsToPush(options) {
|
|
249160
249250
|
if (!getAppContext().projectRoot) {
|
|
249161
|
-
return readAllConnectors(
|
|
249251
|
+
return readAllConnectors(resolve10(options.dir ?? "connectors"));
|
|
249162
249252
|
}
|
|
249163
249253
|
const { connectors } = await readProjectConfig();
|
|
249164
249254
|
return connectors;
|
|
@@ -249501,11 +249591,11 @@ function getListCommand() {
|
|
|
249501
249591
|
}
|
|
249502
249592
|
|
|
249503
249593
|
// src/cli/commands/functions/pull.ts
|
|
249504
|
-
import { dirname as
|
|
249594
|
+
import { dirname as dirname21, join as join27 } from "node:path";
|
|
249505
249595
|
async function pullFunctionsAction({ log, runTask }, name) {
|
|
249506
249596
|
const { project, functions } = await readProjectConfig();
|
|
249507
|
-
const configDir =
|
|
249508
|
-
const functionsDir =
|
|
249597
|
+
const configDir = dirname21(project.configPath);
|
|
249598
|
+
const functionsDir = join27(configDir, project.functionsDir);
|
|
249509
249599
|
const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
|
|
249510
249600
|
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
249511
249601
|
const { functions } = await listDeployedFunctions();
|
|
@@ -249608,14 +249698,11 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
|
|
|
249608
249698
|
|
|
249609
249699
|
// src/cli/commands/project/build.ts
|
|
249610
249700
|
async function buildAction(ctx) {
|
|
249611
|
-
const
|
|
249612
|
-
|
|
249613
|
-
throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
|
|
249614
|
-
}
|
|
249615
|
-
const { project } = await readProjectConfig(app.projectRoot);
|
|
249701
|
+
const app = requireApp(ctx);
|
|
249702
|
+
const target = await resolveBuildTarget(app.projectRoot);
|
|
249616
249703
|
await runSiteBuild(ctx, {
|
|
249617
|
-
root:
|
|
249618
|
-
buildCommand:
|
|
249704
|
+
root: target.root,
|
|
249705
|
+
buildCommand: target.buildCommand,
|
|
249619
249706
|
appId: app.id
|
|
249620
249707
|
});
|
|
249621
249708
|
return {
|
|
@@ -249623,15 +249710,15 @@ async function buildAction(ctx) {
|
|
|
249623
249710
|
};
|
|
249624
249711
|
}
|
|
249625
249712
|
function getBuildCommand() {
|
|
249626
|
-
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);
|
|
249627
249714
|
}
|
|
249628
249715
|
|
|
249629
249716
|
// src/cli/commands/project/create.ts
|
|
249630
|
-
import { basename as basename6, resolve as
|
|
249717
|
+
import { basename as basename6, resolve as resolve11 } from "node:path";
|
|
249631
249718
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
249632
249719
|
|
|
249633
249720
|
// src/cli/commands/project/scaffold-shared.ts
|
|
249634
|
-
import { join as
|
|
249721
|
+
import { join as join28 } from "node:path";
|
|
249635
249722
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
249636
249723
|
async function getTemplateById(templateId) {
|
|
249637
249724
|
const templates = await listTemplates();
|
|
@@ -249694,7 +249781,7 @@ async function completeProjectSetup({
|
|
|
249694
249781
|
env: { VITE_BASE44_APP_ID: projectId }
|
|
249695
249782
|
})`${buildCommand}`;
|
|
249696
249783
|
updateMessage("Deploying site...");
|
|
249697
|
-
return await deploySite(
|
|
249784
|
+
return await deploySite(join28(resolvedPath, outputDirectory));
|
|
249698
249785
|
}, {
|
|
249699
249786
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
249700
249787
|
errorMessage: "Failed to deploy site"
|
|
@@ -249823,7 +249910,7 @@ async function createInteractive(options, ctx) {
|
|
|
249823
249910
|
}, ctx);
|
|
249824
249911
|
}
|
|
249825
249912
|
async function createNonInteractive(options, ctx) {
|
|
249826
|
-
ctx.log.info(`Creating a new project at ${
|
|
249913
|
+
ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
|
|
249827
249914
|
const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
|
|
249828
249915
|
return await executeCreate({
|
|
249829
249916
|
template,
|
|
@@ -249847,7 +249934,7 @@ async function executeCreate({
|
|
|
249847
249934
|
}, ctx) {
|
|
249848
249935
|
const { log, runTask } = ctx;
|
|
249849
249936
|
const name = rawName.trim();
|
|
249850
|
-
const resolvedPath =
|
|
249937
|
+
const resolvedPath = resolve11(projectPath);
|
|
249851
249938
|
const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
|
|
249852
249939
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
249853
249940
|
return await createProjectFiles({
|
|
@@ -249904,8 +249991,7 @@ async function deployAction(ctx, options = {}) {
|
|
|
249904
249991
|
throw new InvalidInputError("--yes is required in non-interactive mode");
|
|
249905
249992
|
}
|
|
249906
249993
|
const projectData = await readProjectConfig(options.projectRoot);
|
|
249907
|
-
|
|
249908
|
-
if (!hasResourcesToDeploy(projectData, { workerBuild })) {
|
|
249994
|
+
if (!hasResourcesToDeploy(projectData)) {
|
|
249909
249995
|
return {
|
|
249910
249996
|
outroMessage: "No resources found to deploy"
|
|
249911
249997
|
};
|
|
@@ -249941,9 +250027,7 @@ async function deployAction(ctx, options = {}) {
|
|
|
249941
250027
|
if (project.visibility) {
|
|
249942
250028
|
summaryLines.push(` - Visibility: ${project.visibility}`);
|
|
249943
250029
|
}
|
|
249944
|
-
if (
|
|
249945
|
-
summaryLines.push(" - Site");
|
|
249946
|
-
} else if (project.site?.outputDirectory) {
|
|
250030
|
+
if (project.site?.outputDirectory) {
|
|
249947
250031
|
summaryLines.push(` - Site from ${project.site.outputDirectory}`);
|
|
249948
250032
|
}
|
|
249949
250033
|
if (!options.yes) {
|
|
@@ -249998,10 +250082,6 @@ ${summaryLines.join(`
|
|
|
249998
250082
|
if (result.appUrl) {
|
|
249999
250083
|
log.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
|
|
250000
250084
|
}
|
|
250001
|
-
if (result.deployment) {
|
|
250002
|
-
const { deploymentId, gitHash } = result.deployment;
|
|
250003
|
-
log.message(`${theme.styles.header("Deployment")}: ${deploymentId} (commit ${gitHash.slice(0, 12)})`);
|
|
250004
|
-
}
|
|
250005
250085
|
return { outroMessage: "App deployed successfully" };
|
|
250006
250086
|
}
|
|
250007
250087
|
function getDeployCommand3() {
|
|
@@ -250495,7 +250575,7 @@ function getLogsCommand() {
|
|
|
250495
250575
|
}
|
|
250496
250576
|
|
|
250497
250577
|
// src/cli/commands/project/scaffold.ts
|
|
250498
|
-
import { basename as basename7, resolve as
|
|
250578
|
+
import { basename as basename7, resolve as resolve12 } from "node:path";
|
|
250499
250579
|
function resolveAppId(options) {
|
|
250500
250580
|
const appId = options.appId;
|
|
250501
250581
|
if (!appId) {
|
|
@@ -250511,7 +250591,7 @@ function resolveAppId(options) {
|
|
|
250511
250591
|
async function scaffoldAction(ctx, name, options, command) {
|
|
250512
250592
|
const { log, runTask } = ctx;
|
|
250513
250593
|
const appId = resolveAppId(command.optsWithGlobals());
|
|
250514
|
-
const resolvedPath =
|
|
250594
|
+
const resolvedPath = resolve12("./");
|
|
250515
250595
|
const projectName = (name ?? basename7(resolvedPath)).trim();
|
|
250516
250596
|
const template = await getTemplateById("backend-only");
|
|
250517
250597
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
@@ -250559,6 +250639,315 @@ function getVisibilityCommand() {
|
|
|
250559
250639
|
])).action(setVisibility);
|
|
250560
250640
|
}
|
|
250561
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
|
+
|
|
250562
250951
|
// src/core/resources/sandbox/schema.ts
|
|
250563
250952
|
var FileErrorSchema = object({
|
|
250564
250953
|
code: string2(),
|
|
@@ -250944,7 +251333,7 @@ function getSecretsListCommand() {
|
|
|
250944
251333
|
}
|
|
250945
251334
|
|
|
250946
251335
|
// src/cli/commands/secrets/set.ts
|
|
250947
|
-
import { resolve as
|
|
251336
|
+
import { resolve as resolve14 } from "node:path";
|
|
250948
251337
|
function parseEntries(entries) {
|
|
250949
251338
|
const secrets = {};
|
|
250950
251339
|
for (const entry of entries) {
|
|
@@ -250975,7 +251364,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
|
|
|
250975
251364
|
validateInput(entries, options);
|
|
250976
251365
|
let secrets;
|
|
250977
251366
|
if (options.envFile) {
|
|
250978
|
-
secrets = await parseEnvFile(
|
|
251367
|
+
secrets = await parseEnvFile(resolve14(options.envFile));
|
|
250979
251368
|
if (Object.keys(secrets).length === 0) {
|
|
250980
251369
|
throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
|
|
250981
251370
|
}
|
|
@@ -251004,7 +251393,7 @@ function getSecretsCommand() {
|
|
|
251004
251393
|
}
|
|
251005
251394
|
|
|
251006
251395
|
// src/cli/commands/site/deploy.ts
|
|
251007
|
-
import { resolve as
|
|
251396
|
+
import { resolve as resolve15 } from "node:path";
|
|
251008
251397
|
async function deployAction2(ctx, options) {
|
|
251009
251398
|
const { isNonInteractive } = ctx;
|
|
251010
251399
|
if (isNonInteractive && !options.yes) {
|
|
@@ -251012,17 +251401,16 @@ async function deployAction2(ctx, options) {
|
|
|
251012
251401
|
}
|
|
251013
251402
|
const project = await readProjectSettings();
|
|
251014
251403
|
await maybeBuildBeforeDeploy(ctx, project, options.build);
|
|
251015
|
-
const workerBuild = await hasWorkerBuild(project.root);
|
|
251016
251404
|
if (!options.yes) {
|
|
251017
251405
|
const outputDirectory = project.site?.outputDirectory;
|
|
251018
251406
|
const shouldDeploy = await Re({
|
|
251019
|
-
message: outputDirectory
|
|
251407
|
+
message: outputDirectory ? `Deploy site from ${outputDirectory}?` : "Deploy site?"
|
|
251020
251408
|
});
|
|
251021
251409
|
if (Ct(shouldDeploy) || !shouldDeploy) {
|
|
251022
251410
|
return { outroMessage: "Deployment cancelled" };
|
|
251023
251411
|
}
|
|
251024
251412
|
}
|
|
251025
|
-
return
|
|
251413
|
+
return deploymentsApiEnabled() ? await deployToDeploymentsApi(ctx, project, options) : await deployTarball(ctx, project);
|
|
251026
251414
|
}
|
|
251027
251415
|
async function deployToDeploymentsApi(ctx, project, options) {
|
|
251028
251416
|
const { runTask, log, jsonMode } = ctx;
|
|
@@ -251083,7 +251471,7 @@ async function deployTarball({ runTask }, project) {
|
|
|
251083
251471
|
}
|
|
251084
251472
|
function siteOutputDir(project) {
|
|
251085
251473
|
const outputDirectory = project.site?.outputDirectory;
|
|
251086
|
-
return outputDirectory ?
|
|
251474
|
+
return outputDirectory ? resolve15(project.root, outputDirectory) : null;
|
|
251087
251475
|
}
|
|
251088
251476
|
function getSiteDeployCommand() {
|
|
251089
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)");
|
|
@@ -251107,6 +251495,229 @@ function parseConcurrency(value) {
|
|
|
251107
251495
|
return parsed;
|
|
251108
251496
|
}
|
|
251109
251497
|
|
|
251498
|
+
// src/cli/dev/createDevLogger.ts
|
|
251499
|
+
var colorByType = {
|
|
251500
|
+
error: theme.styles.error,
|
|
251501
|
+
warn: theme.styles.warn,
|
|
251502
|
+
log: (input) => input
|
|
251503
|
+
};
|
|
251504
|
+
var stringify = (item) => {
|
|
251505
|
+
if (typeof item === "string") {
|
|
251506
|
+
return item;
|
|
251507
|
+
}
|
|
251508
|
+
if (item instanceof Error) {
|
|
251509
|
+
return item.toString();
|
|
251510
|
+
}
|
|
251511
|
+
try {
|
|
251512
|
+
return JSON.stringify(item, null, 2) ?? String(item);
|
|
251513
|
+
} catch {
|
|
251514
|
+
return String(item);
|
|
251515
|
+
}
|
|
251516
|
+
};
|
|
251517
|
+
function createDevLogger(label, labelColor = theme.styles.dim) {
|
|
251518
|
+
const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
|
|
251519
|
+
const print = (type, ...args) => {
|
|
251520
|
+
const colorize = colorByType[type];
|
|
251521
|
+
console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
|
|
251522
|
+
};
|
|
251523
|
+
return {
|
|
251524
|
+
log: (...args) => print("log", ...args),
|
|
251525
|
+
error: (msg, err) => {
|
|
251526
|
+
print("error", msg);
|
|
251527
|
+
if (err) {
|
|
251528
|
+
print("error", err);
|
|
251529
|
+
}
|
|
251530
|
+
},
|
|
251531
|
+
warn: (...args) => print("warn", ...args)
|
|
251532
|
+
};
|
|
251533
|
+
}
|
|
251534
|
+
|
|
251535
|
+
// src/cli/dev/dev-server/serve-runner.ts
|
|
251536
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
251537
|
+
import process21 from "node:process";
|
|
251538
|
+
|
|
251539
|
+
class ServeRunner {
|
|
251540
|
+
command;
|
|
251541
|
+
cwd;
|
|
251542
|
+
env;
|
|
251543
|
+
logger;
|
|
251544
|
+
child;
|
|
251545
|
+
stopping = false;
|
|
251546
|
+
stopPromise;
|
|
251547
|
+
exitListeners = [];
|
|
251548
|
+
constructor(options) {
|
|
251549
|
+
this.command = options.command;
|
|
251550
|
+
this.cwd = options.cwd;
|
|
251551
|
+
this.env = options.env;
|
|
251552
|
+
this.logger = options.logger;
|
|
251553
|
+
}
|
|
251554
|
+
start() {
|
|
251555
|
+
if (this.child) {
|
|
251556
|
+
return;
|
|
251557
|
+
}
|
|
251558
|
+
const stdin = process21.platform === "win32" ? "ignore" : "inherit";
|
|
251559
|
+
const child = spawn2(this.command, {
|
|
251560
|
+
cwd: this.cwd,
|
|
251561
|
+
shell: true,
|
|
251562
|
+
detached: process21.platform !== "win32",
|
|
251563
|
+
env: { ...process21.env, ...this.env },
|
|
251564
|
+
stdio: [stdin, "pipe", "pipe"],
|
|
251565
|
+
windowsHide: true
|
|
251566
|
+
});
|
|
251567
|
+
this.child = child;
|
|
251568
|
+
this.setupHandlers(child);
|
|
251569
|
+
}
|
|
251570
|
+
onExit(listener) {
|
|
251571
|
+
this.exitListeners.push(listener);
|
|
251572
|
+
}
|
|
251573
|
+
async stop() {
|
|
251574
|
+
if (this.stopPromise) {
|
|
251575
|
+
return this.stopPromise;
|
|
251576
|
+
}
|
|
251577
|
+
this.stopPromise = this.stopChild();
|
|
251578
|
+
return this.stopPromise;
|
|
251579
|
+
}
|
|
251580
|
+
async stopChild() {
|
|
251581
|
+
const child = this.child;
|
|
251582
|
+
if (!child || child.exitCode !== null) {
|
|
251583
|
+
return;
|
|
251584
|
+
}
|
|
251585
|
+
this.stopping = true;
|
|
251586
|
+
const exited = new Promise((resolve) => child.once("exit", () => resolve()));
|
|
251587
|
+
if (process21.platform === "win32" && child.pid) {
|
|
251588
|
+
const taskkill = spawn2("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
251589
|
+
stdio: "ignore",
|
|
251590
|
+
windowsHide: true
|
|
251591
|
+
});
|
|
251592
|
+
await new Promise((resolve) => {
|
|
251593
|
+
taskkill.once("exit", () => resolve());
|
|
251594
|
+
taskkill.once("error", () => resolve());
|
|
251595
|
+
});
|
|
251596
|
+
} else if (child.pid) {
|
|
251597
|
+
try {
|
|
251598
|
+
process21.kill(-child.pid, "SIGTERM");
|
|
251599
|
+
} catch {
|
|
251600
|
+
child.kill();
|
|
251601
|
+
}
|
|
251602
|
+
}
|
|
251603
|
+
await exited;
|
|
251604
|
+
}
|
|
251605
|
+
setupHandlers(child) {
|
|
251606
|
+
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
251607
|
+
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
251608
|
+
child.on("error", (error) => {
|
|
251609
|
+
this.logger.error("Frontend dev server failed to start:", error);
|
|
251610
|
+
this.notifyExit(null);
|
|
251611
|
+
});
|
|
251612
|
+
child.on("exit", (code) => {
|
|
251613
|
+
if (this.stopping) {
|
|
251614
|
+
return;
|
|
251615
|
+
}
|
|
251616
|
+
this.logger.error(`Frontend dev server exited with code ${code}`);
|
|
251617
|
+
this.notifyExit(code);
|
|
251618
|
+
});
|
|
251619
|
+
}
|
|
251620
|
+
notifyExit(code) {
|
|
251621
|
+
for (const listener of this.exitListeners) {
|
|
251622
|
+
listener(code);
|
|
251623
|
+
}
|
|
251624
|
+
}
|
|
251625
|
+
emitLines(data, type) {
|
|
251626
|
+
const lines = data.toString().trimEnd().split(`
|
|
251627
|
+
`);
|
|
251628
|
+
for (const line of lines) {
|
|
251629
|
+
if (type === "error") {
|
|
251630
|
+
this.logger.error(line);
|
|
251631
|
+
} else {
|
|
251632
|
+
this.logger.log(line);
|
|
251633
|
+
}
|
|
251634
|
+
}
|
|
251635
|
+
}
|
|
251636
|
+
}
|
|
251637
|
+
|
|
251638
|
+
// src/cli/dev/serve-command-runner.ts
|
|
251639
|
+
function createServeCommandRunner({
|
|
251640
|
+
serveCommand,
|
|
251641
|
+
projectRoot,
|
|
251642
|
+
appId,
|
|
251643
|
+
appBaseUrl
|
|
251644
|
+
}) {
|
|
251645
|
+
return new ServeRunner({
|
|
251646
|
+
command: serveCommand,
|
|
251647
|
+
cwd: projectRoot,
|
|
251648
|
+
env: {
|
|
251649
|
+
VITE_BASE44_APP_ID: appId,
|
|
251650
|
+
...appBaseUrl ? { VITE_BASE44_APP_BASE_URL: appBaseUrl } : {}
|
|
251651
|
+
},
|
|
251652
|
+
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
251653
|
+
});
|
|
251654
|
+
}
|
|
251655
|
+
|
|
251656
|
+
// src/cli/dev/stop-runner-on-signals.ts
|
|
251657
|
+
import process22 from "node:process";
|
|
251658
|
+
function stopRunnerOnProcessSignals(runner) {
|
|
251659
|
+
const stop = () => void runner.stop();
|
|
251660
|
+
process22.on("SIGINT", stop);
|
|
251661
|
+
process22.on("SIGTERM", stop);
|
|
251662
|
+
}
|
|
251663
|
+
|
|
251664
|
+
// src/cli/commands/site/dev.ts
|
|
251665
|
+
var DEFAULT_SERVE_COMMAND = "npm run dev";
|
|
251666
|
+
async function siteDevAction(ctx) {
|
|
251667
|
+
const { app } = ctx;
|
|
251668
|
+
if (!app?.projectRoot) {
|
|
251669
|
+
throw new ConfigInvalidError("base44 site dev requires a linked local project. Run it from a project with base44/.app.jsonc.");
|
|
251670
|
+
}
|
|
251671
|
+
const { project } = await readProjectConfig(app.projectRoot);
|
|
251672
|
+
const site = project.site;
|
|
251673
|
+
if (!site) {
|
|
251674
|
+
throw new InvalidInputError(`This project has no 'site' block in base44/config.jsonc, so there is no frontend to serve. Add one naming its serveCommand; site dev falls back to "npm run dev".`);
|
|
251675
|
+
}
|
|
251676
|
+
const command = site.serveCommand ?? DEFAULT_SERVE_COMMAND;
|
|
251677
|
+
const runner = createServeCommandRunner({
|
|
251678
|
+
serveCommand: command,
|
|
251679
|
+
projectRoot: project.root,
|
|
251680
|
+
appId: app.id
|
|
251681
|
+
});
|
|
251682
|
+
stopRunnerOnProcessSignals(runner);
|
|
251683
|
+
runner.onExit((code) => process.exit(code ?? 1));
|
|
251684
|
+
runner.start();
|
|
251685
|
+
return { outroMessage: `Frontend dev server running '${command}'` };
|
|
251686
|
+
}
|
|
251687
|
+
function getSiteDevCommand() {
|
|
251688
|
+
return new Base44Command("dev", { requireAuth: false }).description("Run the site's dev server, with no local backend").action(siteDevAction);
|
|
251689
|
+
}
|
|
251690
|
+
|
|
251691
|
+
// src/cli/commands/site/install.ts
|
|
251692
|
+
async function installAction({
|
|
251693
|
+
runTask
|
|
251694
|
+
}) {
|
|
251695
|
+
const { project } = await readProjectConfig();
|
|
251696
|
+
const installCommand = project.site?.installCommand;
|
|
251697
|
+
if (!installCommand) {
|
|
251698
|
+
throw new ConfigNotFoundError("No site install command found.", {
|
|
251699
|
+
hints: [
|
|
251700
|
+
{
|
|
251701
|
+
message: `Add a 'site' block to your config.jsonc (e.g., "site": { "installCommand": "npm ci" }). Inside one, installCommand defaults to "npm install".`
|
|
251702
|
+
}
|
|
251703
|
+
]
|
|
251704
|
+
});
|
|
251705
|
+
}
|
|
251706
|
+
await runTask("Installing site dependencies...", () => execa({ cwd: project.root, shell: true })`${installCommand}`, {
|
|
251707
|
+
successMessage: "Dependencies installed",
|
|
251708
|
+
errorMessage: "Install failed"
|
|
251709
|
+
});
|
|
251710
|
+
return {
|
|
251711
|
+
outroMessage: `Installed with ${theme.styles.bold(installCommand)}`
|
|
251712
|
+
};
|
|
251713
|
+
}
|
|
251714
|
+
function getSiteInstallCommand() {
|
|
251715
|
+
return new Base44Command("install", {
|
|
251716
|
+
requireAuth: false,
|
|
251717
|
+
requireAppContext: false
|
|
251718
|
+
}).description("Install the site's dependencies with its configured command").action(installAction);
|
|
251719
|
+
}
|
|
251720
|
+
|
|
251110
251721
|
// src/cli/commands/site/open.ts
|
|
251111
251722
|
async function openAction({
|
|
251112
251723
|
isNonInteractive
|
|
@@ -251123,7 +251734,7 @@ function getSiteOpenCommand() {
|
|
|
251123
251734
|
|
|
251124
251735
|
// src/cli/commands/site/index.ts
|
|
251125
251736
|
function getSiteCommand() {
|
|
251126
|
-
return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteOpenCommand());
|
|
251737
|
+
return new Command2("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteDevCommand()).addCommand(getSiteInstallCommand()).addCommand(getSiteOpenCommand());
|
|
251127
251738
|
}
|
|
251128
251739
|
|
|
251129
251740
|
// src/core/types/generator.ts
|
|
@@ -251215,10 +251826,10 @@ function toPascalCase(name) {
|
|
|
251215
251826
|
return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
251216
251827
|
}
|
|
251217
251828
|
// src/core/types/update-project.ts
|
|
251218
|
-
import { join as
|
|
251829
|
+
import { join as join33 } from "node:path";
|
|
251219
251830
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
251220
251831
|
async function updateProjectConfig(projectRoot) {
|
|
251221
|
-
const tsconfigPath =
|
|
251832
|
+
const tsconfigPath = join33(projectRoot, "tsconfig.json");
|
|
251222
251833
|
if (!await pathExists(tsconfigPath)) {
|
|
251223
251834
|
return false;
|
|
251224
251835
|
}
|
|
@@ -251267,6 +251878,59 @@ function getTypesCommand() {
|
|
|
251267
251878
|
return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
251268
251879
|
}
|
|
251269
251880
|
|
|
251881
|
+
// src/cli/commands/versions/create.ts
|
|
251882
|
+
async function createAction2(ctx, options) {
|
|
251883
|
+
const { runTask, jsonMode } = ctx;
|
|
251884
|
+
const target = await resolveBuildTarget(requireApp(ctx).projectRoot, {
|
|
251885
|
+
outputDir: options.outputDir
|
|
251886
|
+
});
|
|
251887
|
+
const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
|
|
251888
|
+
const version = await runTask("Creating version...", async (updateMessage) => await createVersion(await collectArtifacts(target), {
|
|
251889
|
+
sourceCommit: gitHash,
|
|
251890
|
+
concurrency: options.concurrency,
|
|
251891
|
+
progress: {
|
|
251892
|
+
onDeclared: ({ fileCount }) => updateMessage(`Uploading ${fileCount} files`),
|
|
251893
|
+
onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
|
|
251894
|
+
}
|
|
251895
|
+
}), {
|
|
251896
|
+
successMessage: "Version created",
|
|
251897
|
+
errorMessage: "Create version failed"
|
|
251898
|
+
});
|
|
251899
|
+
return {
|
|
251900
|
+
outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
|
|
251901
|
+
stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
|
|
251902
|
+
` : undefined
|
|
251903
|
+
};
|
|
251904
|
+
}
|
|
251905
|
+
function getVersionCreateCommand() {
|
|
251906
|
+
return new Base44Command("create").description("Record the built output as a version, without deploying it").addOption(outputDirOption()).addOption(gitHashOption()).addOption(concurrencyOption()).action(createAction2);
|
|
251907
|
+
}
|
|
251908
|
+
|
|
251909
|
+
// src/cli/commands/versions/deploy.ts
|
|
251910
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
251911
|
+
async function deployAction3({ runTask, jsonMode }, versionId, options) {
|
|
251912
|
+
const environment = options.target ?? DEFAULT_ENVIRONMENT;
|
|
251913
|
+
const result = await runTask(`Pointing ${environment} at ${versionId}...`, async () => await setEnvironmentVersion(environment, versionId, {
|
|
251914
|
+
idempotencyKey: randomUUID5()
|
|
251915
|
+
}), {
|
|
251916
|
+
successMessage: "Environment updated",
|
|
251917
|
+
errorMessage: "Could not update the environment"
|
|
251918
|
+
});
|
|
251919
|
+
return {
|
|
251920
|
+
outroMessage: `${result.name} now serves ${result.versionId}`,
|
|
251921
|
+
stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
|
|
251922
|
+
` : undefined
|
|
251923
|
+
};
|
|
251924
|
+
}
|
|
251925
|
+
function getVersionDeployCommand() {
|
|
251926
|
+
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);
|
|
251927
|
+
}
|
|
251928
|
+
|
|
251929
|
+
// src/cli/commands/versions/index.ts
|
|
251930
|
+
function getVersionsCommand() {
|
|
251931
|
+
return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
|
|
251932
|
+
}
|
|
251933
|
+
|
|
251270
251934
|
// src/core/resources/workflow/schema.ts
|
|
251271
251935
|
var WorkflowRunStatusSchema = _enum([
|
|
251272
251936
|
"running",
|
|
@@ -251643,47 +252307,10 @@ function getWorkspaceCommand() {
|
|
|
251643
252307
|
return new Command2("workspace").description("List workspaces, inspect one, and move apps between them").addCommand(getWorkspaceListCommand()).addCommand(getWorkspaceGetCommand()).addCommand(getWorkspaceMoveCommand());
|
|
251644
252308
|
}
|
|
251645
252309
|
|
|
251646
|
-
// src/cli/dev/createDevLogger.ts
|
|
251647
|
-
var colorByType = {
|
|
251648
|
-
error: theme.styles.error,
|
|
251649
|
-
warn: theme.styles.warn,
|
|
251650
|
-
log: (input) => input
|
|
251651
|
-
};
|
|
251652
|
-
var stringify = (item) => {
|
|
251653
|
-
if (typeof item === "string") {
|
|
251654
|
-
return item;
|
|
251655
|
-
}
|
|
251656
|
-
if (item instanceof Error) {
|
|
251657
|
-
return item.toString();
|
|
251658
|
-
}
|
|
251659
|
-
try {
|
|
251660
|
-
return JSON.stringify(item, null, 2) ?? String(item);
|
|
251661
|
-
} catch {
|
|
251662
|
-
return String(item);
|
|
251663
|
-
}
|
|
251664
|
-
};
|
|
251665
|
-
function createDevLogger(label, labelColor = theme.styles.dim) {
|
|
251666
|
-
const prefix = label ? `${labelColor(`[${label}]`)} ` : "";
|
|
251667
|
-
const print = (type, ...args) => {
|
|
251668
|
-
const colorize = colorByType[type];
|
|
251669
|
-
console[type](prefix + args.map((item) => colorize(stringify(item))).join(" "));
|
|
251670
|
-
};
|
|
251671
|
-
return {
|
|
251672
|
-
log: (...args) => print("log", ...args),
|
|
251673
|
-
error: (msg, err) => {
|
|
251674
|
-
print("error", msg);
|
|
251675
|
-
if (err) {
|
|
251676
|
-
print("error", err);
|
|
251677
|
-
}
|
|
251678
|
-
},
|
|
251679
|
-
warn: (...args) => print("warn", ...args)
|
|
251680
|
-
};
|
|
251681
|
-
}
|
|
251682
|
-
|
|
251683
252310
|
// src/cli/dev/dev-server/main.ts
|
|
251684
252311
|
var import_cors = __toESM(require_lib4(), 1);
|
|
251685
252312
|
var import_express6 = __toESM(require_express(), 1);
|
|
251686
|
-
import { dirname as
|
|
252313
|
+
import { dirname as dirname27, join as join38 } from "node:path";
|
|
251687
252314
|
|
|
251688
252315
|
// ../../node_modules/get-port/index.js
|
|
251689
252316
|
import net from "node:net";
|
|
@@ -251812,8 +252439,8 @@ var $dir = async (options) => dirWithOptions(options);
|
|
|
251812
252439
|
var $tmpName = promisify11(tmp.tmpName);
|
|
251813
252440
|
|
|
251814
252441
|
// src/cli/dev/dev-server/function-manager.ts
|
|
251815
|
-
import { spawn as
|
|
251816
|
-
import { dirname as
|
|
252442
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
252443
|
+
import { dirname as dirname24, join as join34 } from "node:path";
|
|
251817
252444
|
import { pathToFileURL } from "node:url";
|
|
251818
252445
|
|
|
251819
252446
|
// src/cli/dev/dev-server/base-function-manager.ts
|
|
@@ -251910,7 +252537,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
251910
252537
|
async stopFunction(_name, { process: proc }) {
|
|
251911
252538
|
const exited = new Promise((r) => proc.once("exit", () => r()));
|
|
251912
252539
|
if (process.platform === "win32" && proc.pid) {
|
|
251913
|
-
|
|
252540
|
+
spawn3("taskkill", ["/pid", String(proc.pid), "/T", "/F"]);
|
|
251914
252541
|
} else {
|
|
251915
252542
|
proc.kill();
|
|
251916
252543
|
}
|
|
@@ -251918,8 +252545,8 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
251918
252545
|
}
|
|
251919
252546
|
spawnFunction(func, port) {
|
|
251920
252547
|
this.logger.log(`Spawning function "${func.name}" on port ${port}`);
|
|
251921
|
-
const importMapPath =
|
|
251922
|
-
const process2 =
|
|
252548
|
+
const importMapPath = join34(dirname24(this.wrapperPath), "import-map.json");
|
|
252549
|
+
const process2 = spawn3("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
|
|
251923
252550
|
env: {
|
|
251924
252551
|
...globalThis.process.env,
|
|
251925
252552
|
FUNCTION_PATH: pathToFileURL(func.entryPath).href,
|
|
@@ -251992,7 +252619,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
251992
252619
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
251993
252620
|
import { isBuiltin } from "node:module";
|
|
251994
252621
|
import { homedir as homedir3 } from "node:os";
|
|
251995
|
-
import { join as
|
|
252622
|
+
import { join as join35 } from "node:path";
|
|
251996
252623
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
251997
252624
|
var depsPromise;
|
|
251998
252625
|
function loadDeps() {
|
|
@@ -252113,9 +252740,9 @@ export default {
|
|
|
252113
252740
|
};
|
|
252114
252741
|
`;
|
|
252115
252742
|
function ensureBundlerConfig() {
|
|
252116
|
-
const dir =
|
|
252743
|
+
const dir = join35(homedir3(), ".base44", "function-bundler");
|
|
252117
252744
|
mkdirSync2(dir, { recursive: true });
|
|
252118
|
-
const configPath =
|
|
252745
|
+
const configPath = join35(dir, "deno.json");
|
|
252119
252746
|
writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
|
|
252120
252747
|
`);
|
|
252121
252748
|
return configPath;
|
|
@@ -253496,11 +254123,11 @@ async function createEntityRoutes(db, logger, broadcast) {
|
|
|
253496
254123
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
253497
254124
|
var import_express5 = __toESM(require_express(), 1);
|
|
253498
254125
|
var import_multer = __toESM(require_multer(), 1);
|
|
253499
|
-
import { createHash as
|
|
254126
|
+
import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
|
|
253500
254127
|
import fs28 from "node:fs";
|
|
253501
254128
|
import path18 from "node:path";
|
|
253502
254129
|
function createFileToken(fileUri) {
|
|
253503
|
-
return
|
|
254130
|
+
return createHash3("sha256").update(fileUri).digest("hex");
|
|
253504
254131
|
}
|
|
253505
254132
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
253506
254133
|
const router = import_express5.Router({ mergeParams: true });
|
|
@@ -253513,14 +254140,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
|
|
|
253513
254140
|
destination: mediaFilesDir,
|
|
253514
254141
|
filename: (_req, file, cb) => {
|
|
253515
254142
|
const ext = path18.extname(file.originalname);
|
|
253516
|
-
cb(null, `${
|
|
254143
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253517
254144
|
}
|
|
253518
254145
|
});
|
|
253519
254146
|
const privateStorage = import_multer.default.diskStorage({
|
|
253520
254147
|
destination: privateFilesDir,
|
|
253521
254148
|
filename: (_req, file, cb) => {
|
|
253522
254149
|
const ext = path18.extname(file.originalname);
|
|
253523
|
-
cb(null, `${
|
|
254150
|
+
cb(null, `${randomUUID6()}${ext}`);
|
|
253524
254151
|
}
|
|
253525
254152
|
});
|
|
253526
254153
|
const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
|
|
@@ -255382,8 +256009,8 @@ async function createDevServer(options) {
|
|
|
255382
256009
|
broadcastEntityEvent(io, appId, entityName, event);
|
|
255383
256010
|
};
|
|
255384
256011
|
const base44ConfigWatcher = new WatchBase44({
|
|
255385
|
-
functions:
|
|
255386
|
-
entities:
|
|
256012
|
+
functions: join38(dirname27(project.configPath), project.functionsDir),
|
|
256013
|
+
entities: join38(dirname27(project.configPath), project.entitiesDir)
|
|
255387
256014
|
}, devLogger);
|
|
255388
256015
|
base44ConfigWatcher.on("change", async (name) => {
|
|
255389
256016
|
try {
|
|
@@ -255449,127 +256076,6 @@ async function createDevServer(options) {
|
|
|
255449
256076
|
return { port, server, shutdown };
|
|
255450
256077
|
}
|
|
255451
256078
|
|
|
255452
|
-
// src/cli/dev/dev-server/serve-runner.ts
|
|
255453
|
-
import { spawn as spawn3 } from "node:child_process";
|
|
255454
|
-
import process23 from "node:process";
|
|
255455
|
-
|
|
255456
|
-
class ServeRunner {
|
|
255457
|
-
command;
|
|
255458
|
-
cwd;
|
|
255459
|
-
env;
|
|
255460
|
-
logger;
|
|
255461
|
-
child;
|
|
255462
|
-
stopping = false;
|
|
255463
|
-
stopPromise;
|
|
255464
|
-
exitListeners = [];
|
|
255465
|
-
constructor(options) {
|
|
255466
|
-
this.command = options.command;
|
|
255467
|
-
this.cwd = options.cwd;
|
|
255468
|
-
this.env = options.env;
|
|
255469
|
-
this.logger = options.logger;
|
|
255470
|
-
}
|
|
255471
|
-
start() {
|
|
255472
|
-
if (this.child) {
|
|
255473
|
-
return;
|
|
255474
|
-
}
|
|
255475
|
-
const stdin = process23.platform === "win32" ? "ignore" : "inherit";
|
|
255476
|
-
const child = spawn3(this.command, {
|
|
255477
|
-
cwd: this.cwd,
|
|
255478
|
-
shell: true,
|
|
255479
|
-
detached: process23.platform !== "win32",
|
|
255480
|
-
env: { ...process23.env, ...this.env },
|
|
255481
|
-
stdio: [stdin, "pipe", "pipe"],
|
|
255482
|
-
windowsHide: true
|
|
255483
|
-
});
|
|
255484
|
-
this.child = child;
|
|
255485
|
-
this.setupHandlers(child);
|
|
255486
|
-
}
|
|
255487
|
-
onExit(listener) {
|
|
255488
|
-
this.exitListeners.push(listener);
|
|
255489
|
-
}
|
|
255490
|
-
async stop() {
|
|
255491
|
-
if (this.stopPromise) {
|
|
255492
|
-
return this.stopPromise;
|
|
255493
|
-
}
|
|
255494
|
-
this.stopPromise = this.stopChild();
|
|
255495
|
-
return this.stopPromise;
|
|
255496
|
-
}
|
|
255497
|
-
async stopChild() {
|
|
255498
|
-
const child = this.child;
|
|
255499
|
-
if (!child || child.exitCode !== null) {
|
|
255500
|
-
return;
|
|
255501
|
-
}
|
|
255502
|
-
this.stopping = true;
|
|
255503
|
-
const exited = new Promise((resolve) => child.once("exit", () => resolve()));
|
|
255504
|
-
if (process23.platform === "win32" && child.pid) {
|
|
255505
|
-
const taskkill = spawn3("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
255506
|
-
stdio: "ignore",
|
|
255507
|
-
windowsHide: true
|
|
255508
|
-
});
|
|
255509
|
-
await new Promise((resolve) => {
|
|
255510
|
-
taskkill.once("exit", () => resolve());
|
|
255511
|
-
taskkill.once("error", () => resolve());
|
|
255512
|
-
});
|
|
255513
|
-
} else if (child.pid) {
|
|
255514
|
-
try {
|
|
255515
|
-
process23.kill(-child.pid, "SIGTERM");
|
|
255516
|
-
} catch {
|
|
255517
|
-
child.kill();
|
|
255518
|
-
}
|
|
255519
|
-
}
|
|
255520
|
-
await exited;
|
|
255521
|
-
}
|
|
255522
|
-
setupHandlers(child) {
|
|
255523
|
-
child.stdout?.on("data", (data) => this.emitLines(data, "log"));
|
|
255524
|
-
child.stderr?.on("data", (data) => this.emitLines(data, "error"));
|
|
255525
|
-
child.on("error", (error) => {
|
|
255526
|
-
this.logger.error("Frontend dev server failed to start:", error);
|
|
255527
|
-
this.notifyExit(null);
|
|
255528
|
-
});
|
|
255529
|
-
child.on("exit", (code) => {
|
|
255530
|
-
if (this.stopping) {
|
|
255531
|
-
return;
|
|
255532
|
-
}
|
|
255533
|
-
this.logger.error(`Frontend dev server exited with code ${code}`);
|
|
255534
|
-
this.notifyExit(code);
|
|
255535
|
-
});
|
|
255536
|
-
}
|
|
255537
|
-
notifyExit(code) {
|
|
255538
|
-
for (const listener of this.exitListeners) {
|
|
255539
|
-
listener(code);
|
|
255540
|
-
}
|
|
255541
|
-
}
|
|
255542
|
-
emitLines(data, type) {
|
|
255543
|
-
const lines = data.toString().trimEnd().split(`
|
|
255544
|
-
`);
|
|
255545
|
-
for (const line of lines) {
|
|
255546
|
-
if (type === "error") {
|
|
255547
|
-
this.logger.error(line);
|
|
255548
|
-
} else {
|
|
255549
|
-
this.logger.log(line);
|
|
255550
|
-
}
|
|
255551
|
-
}
|
|
255552
|
-
}
|
|
255553
|
-
}
|
|
255554
|
-
|
|
255555
|
-
// src/cli/dev/serve-command-runner.ts
|
|
255556
|
-
function createServeCommandRunner({
|
|
255557
|
-
serveCommand,
|
|
255558
|
-
projectRoot,
|
|
255559
|
-
appId,
|
|
255560
|
-
appBaseUrl
|
|
255561
|
-
}) {
|
|
255562
|
-
return new ServeRunner({
|
|
255563
|
-
command: serveCommand,
|
|
255564
|
-
cwd: projectRoot,
|
|
255565
|
-
env: {
|
|
255566
|
-
VITE_BASE44_APP_ID: appId,
|
|
255567
|
-
VITE_BASE44_APP_BASE_URL: appBaseUrl
|
|
255568
|
-
},
|
|
255569
|
-
logger: createDevLogger("frontend", theme.colors.base44Orange)
|
|
255570
|
-
});
|
|
255571
|
-
}
|
|
255572
|
-
|
|
255573
256079
|
// src/cli/commands/dev.ts
|
|
255574
256080
|
function localServerUrl(port) {
|
|
255575
256081
|
return `http://localhost:${port}`;
|
|
@@ -255595,11 +256101,6 @@ async function resolveConfiguredSite(app) {
|
|
|
255595
256101
|
const serveCommand = project.site?.serveCommand;
|
|
255596
256102
|
return serveCommand ? { serveCommand, projectRoot: project.root } : undefined;
|
|
255597
256103
|
}
|
|
255598
|
-
function stopRunnerOnProcessSignals(runner) {
|
|
255599
|
-
const stop = () => void runner.stop();
|
|
255600
|
-
process.on("SIGINT", stop);
|
|
255601
|
-
process.on("SIGTERM", stop);
|
|
255602
|
-
}
|
|
255603
256104
|
function startServeCommand(runner, backend) {
|
|
255604
256105
|
stopRunnerOnProcessSignals(runner);
|
|
255605
256106
|
runner.onExit(() => {
|
|
@@ -255780,7 +256281,7 @@ Examples:
|
|
|
255780
256281
|
}
|
|
255781
256282
|
|
|
255782
256283
|
// src/cli/commands/project/eject.ts
|
|
255783
|
-
import { resolve as
|
|
256284
|
+
import { resolve as resolve19 } from "node:path";
|
|
255784
256285
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
255785
256286
|
async function eject(ctx, options, command) {
|
|
255786
256287
|
const { log, runTask, isNonInteractive } = ctx;
|
|
@@ -255844,7 +256345,7 @@ async function eject(ctx, options, command) {
|
|
|
255844
256345
|
Ne("Operation cancelled.");
|
|
255845
256346
|
throw new CLIExitError(0);
|
|
255846
256347
|
}
|
|
255847
|
-
const resolvedPath =
|
|
256348
|
+
const resolvedPath = resolve19(selectedPath);
|
|
255848
256349
|
await runTask("Downloading your project's code...", async (updateMessage) => {
|
|
255849
256350
|
await createProjectFilesForExistingProject({
|
|
255850
256351
|
projectId,
|
|
@@ -255933,6 +256434,10 @@ function createProgram(context) {
|
|
|
255933
256434
|
program.addCommand(getBranchesCommand());
|
|
255934
256435
|
program.addCommand(getAuthCommand());
|
|
255935
256436
|
program.addCommand(getSiteCommand());
|
|
256437
|
+
if (versionsApiEnabled()) {
|
|
256438
|
+
program.addCommand(getPublishCommand());
|
|
256439
|
+
program.addCommand(getVersionsCommand());
|
|
256440
|
+
}
|
|
255936
256441
|
program.addCommand(getTypesCommand());
|
|
255937
256442
|
program.addCommand(getExecCommand());
|
|
255938
256443
|
program.addCommand(getDevCommand());
|
|
@@ -255945,7 +256450,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
255945
256450
|
import { release, type } from "node:os";
|
|
255946
256451
|
|
|
255947
256452
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
255948
|
-
import { dirname as
|
|
256453
|
+
import { dirname as dirname28, posix, sep as sep2 } from "path";
|
|
255949
256454
|
function createModulerModifier() {
|
|
255950
256455
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
255951
256456
|
return async (frames) => {
|
|
@@ -255954,7 +256459,7 @@ function createModulerModifier() {
|
|
|
255954
256459
|
return frames;
|
|
255955
256460
|
};
|
|
255956
256461
|
}
|
|
255957
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ?
|
|
256462
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname28(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
|
|
255958
256463
|
const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
|
|
255959
256464
|
return (filename) => {
|
|
255960
256465
|
if (!filename)
|
|
@@ -259943,9 +260448,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
|
|
|
259943
260448
|
});
|
|
259944
260449
|
}
|
|
259945
260450
|
// src/cli/index.ts
|
|
259946
|
-
var __dirname4 =
|
|
260451
|
+
var __dirname4 = dirname29(fileURLToPath6(import.meta.url));
|
|
259947
260452
|
async function runCLI(options) {
|
|
259948
|
-
ensureNpmAssets(
|
|
260453
|
+
ensureNpmAssets(join39(__dirname4, "../assets"));
|
|
259949
260454
|
const errorReporter = new ErrorReporter;
|
|
259950
260455
|
errorReporter.registerProcessErrorHandlers();
|
|
259951
260456
|
const jsonMode = process.argv.includes("--json");
|
|
@@ -259984,4 +260489,4 @@ export {
|
|
|
259984
260489
|
runCLI
|
|
259985
260490
|
};
|
|
259986
260491
|
|
|
259987
|
-
//# debugId=
|
|
260492
|
+
//# debugId=2C8B0BDEF35B5BA464756E2164756E21
|