@base44-preview/cli 0.1.7-pr.585.a27bb8a → 0.1.7-pr.585.ca3aebe
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 +697 -664
- package/dist/cli/index.js.map +20 -22
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -23352,15 +23352,15 @@ var require_windows = __commonJS((exports, module) => {
|
|
|
23352
23352
|
}
|
|
23353
23353
|
return false;
|
|
23354
23354
|
}
|
|
23355
|
-
function checkStat(
|
|
23356
|
-
if (!
|
|
23355
|
+
function checkStat(stat2, path11, options) {
|
|
23356
|
+
if (!stat2.isSymbolicLink() && !stat2.isFile()) {
|
|
23357
23357
|
return false;
|
|
23358
23358
|
}
|
|
23359
23359
|
return checkPathExt(path11, options);
|
|
23360
23360
|
}
|
|
23361
23361
|
function isexe(path11, options, cb) {
|
|
23362
|
-
fs14.stat(path11, function(er,
|
|
23363
|
-
cb(er, er ? false : checkStat(
|
|
23362
|
+
fs14.stat(path11, function(er, stat2) {
|
|
23363
|
+
cb(er, er ? false : checkStat(stat2, path11, options));
|
|
23364
23364
|
});
|
|
23365
23365
|
}
|
|
23366
23366
|
function sync(path11, options) {
|
|
@@ -23374,20 +23374,20 @@ var require_mode = __commonJS((exports, module) => {
|
|
|
23374
23374
|
isexe.sync = sync;
|
|
23375
23375
|
var fs14 = __require("fs");
|
|
23376
23376
|
function isexe(path11, options, cb) {
|
|
23377
|
-
fs14.stat(path11, function(er,
|
|
23378
|
-
cb(er, er ? false : checkStat(
|
|
23377
|
+
fs14.stat(path11, function(er, stat2) {
|
|
23378
|
+
cb(er, er ? false : checkStat(stat2, options));
|
|
23379
23379
|
});
|
|
23380
23380
|
}
|
|
23381
23381
|
function sync(path11, options) {
|
|
23382
23382
|
return checkStat(fs14.statSync(path11), options);
|
|
23383
23383
|
}
|
|
23384
|
-
function checkStat(
|
|
23385
|
-
return
|
|
23384
|
+
function checkStat(stat2, options) {
|
|
23385
|
+
return stat2.isFile() && checkMode(stat2, options);
|
|
23386
23386
|
}
|
|
23387
|
-
function checkMode(
|
|
23388
|
-
var mod =
|
|
23389
|
-
var uid =
|
|
23390
|
-
var gid =
|
|
23387
|
+
function checkMode(stat2, options) {
|
|
23388
|
+
var mod = stat2.mode;
|
|
23389
|
+
var uid = stat2.uid;
|
|
23390
|
+
var gid = stat2.gid;
|
|
23391
23391
|
var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
|
|
23392
23392
|
var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
|
|
23393
23393
|
var u = parseInt("100", 8);
|
|
@@ -23419,12 +23419,12 @@ var require_isexe = __commonJS((exports, module) => {
|
|
|
23419
23419
|
if (typeof Promise !== "function") {
|
|
23420
23420
|
throw new TypeError("callback not provided");
|
|
23421
23421
|
}
|
|
23422
|
-
return new Promise(function(
|
|
23422
|
+
return new Promise(function(resolve4, reject) {
|
|
23423
23423
|
isexe(path11, options || {}, function(er, is) {
|
|
23424
23424
|
if (er) {
|
|
23425
23425
|
reject(er);
|
|
23426
23426
|
} else {
|
|
23427
|
-
|
|
23427
|
+
resolve4(is);
|
|
23428
23428
|
}
|
|
23429
23429
|
});
|
|
23430
23430
|
});
|
|
@@ -23486,27 +23486,27 @@ var require_which = __commonJS((exports, module) => {
|
|
|
23486
23486
|
opt = {};
|
|
23487
23487
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
23488
23488
|
const found = [];
|
|
23489
|
-
const step = (i) => new Promise((
|
|
23489
|
+
const step = (i) => new Promise((resolve4, reject) => {
|
|
23490
23490
|
if (i === pathEnv.length)
|
|
23491
|
-
return opt.all && found.length ?
|
|
23491
|
+
return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
|
|
23492
23492
|
const ppRaw = pathEnv[i];
|
|
23493
23493
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
23494
23494
|
const pCmd = path11.join(pathPart, cmd);
|
|
23495
23495
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
23496
|
-
|
|
23496
|
+
resolve4(subStep(p, i, 0));
|
|
23497
23497
|
});
|
|
23498
|
-
const subStep = (p, i, ii) => new Promise((
|
|
23498
|
+
const subStep = (p, i, ii) => new Promise((resolve4, reject) => {
|
|
23499
23499
|
if (ii === pathExt.length)
|
|
23500
|
-
return
|
|
23500
|
+
return resolve4(step(i + 1));
|
|
23501
23501
|
const ext = pathExt[ii];
|
|
23502
23502
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
23503
23503
|
if (!er && is) {
|
|
23504
23504
|
if (opt.all)
|
|
23505
23505
|
found.push(p + ext);
|
|
23506
23506
|
else
|
|
23507
|
-
return
|
|
23507
|
+
return resolve4(p + ext);
|
|
23508
23508
|
}
|
|
23509
|
-
return
|
|
23509
|
+
return resolve4(subStep(p, i, ii + 1));
|
|
23510
23510
|
});
|
|
23511
23511
|
});
|
|
23512
23512
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -248113,6 +248113,7 @@ var package_default = {
|
|
|
248113
248113
|
nanoid: "^5.1.6",
|
|
248114
248114
|
open: "^11.0.0",
|
|
248115
248115
|
outdent: "^0.8.0",
|
|
248116
|
+
"p-map": "^7.0.6",
|
|
248116
248117
|
"p-wait-for": "^6.0.0",
|
|
248117
248118
|
"posthog-node": "5.21.2",
|
|
248118
248119
|
qs: "^6.12.3",
|
|
@@ -248258,7 +248259,7 @@ async function createProjectFilesForExistingProject(options) {
|
|
|
248258
248259
|
};
|
|
248259
248260
|
}
|
|
248260
248261
|
// src/core/project/deploy.ts
|
|
248261
|
-
import { resolve as
|
|
248262
|
+
import { resolve as resolve3 } from "node:path";
|
|
248262
248263
|
|
|
248263
248264
|
// src/core/site/api.ts
|
|
248264
248265
|
async function uploadSite(archivePath) {
|
|
@@ -248361,13 +248362,576 @@ async function createArchive(pathToArchive, targetArchivePath) {
|
|
|
248361
248362
|
cwd: pathToArchive
|
|
248362
248363
|
}, ["."]);
|
|
248363
248364
|
}
|
|
248364
|
-
// src/core/site/
|
|
248365
|
-
import {
|
|
248366
|
-
|
|
248365
|
+
// src/core/site/manifest.ts
|
|
248366
|
+
import { createHash } from "node:crypto";
|
|
248367
|
+
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
248368
|
+
import { basename as basename4, join as join15 } from "node:path";
|
|
248369
|
+
var MAX_ASSET_SIZE_BYTES = 25 * 1024 * 1024;
|
|
248370
|
+
var MAX_ASSET_COUNT = 1e5;
|
|
248371
|
+
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
248372
|
+
var ALWAYS_IGNORED = new Set([
|
|
248373
|
+
ASSETS_IGNORE_FILE,
|
|
248374
|
+
"wrangler.json",
|
|
248375
|
+
".dev.vars"
|
|
248376
|
+
]);
|
|
248377
|
+
function hashAsset(appId, content) {
|
|
248378
|
+
return createHash("sha256").update(Buffer.from(appId, "utf8")).update(content).digest("hex").slice(0, 32);
|
|
248379
|
+
}
|
|
248380
|
+
async function buildAssetManifest(assetsDir, appId) {
|
|
248381
|
+
const manifest = {};
|
|
248382
|
+
const filesByHash = new Map;
|
|
248383
|
+
const found = await globby("**/*", {
|
|
248384
|
+
cwd: assetsDir,
|
|
248385
|
+
dot: true,
|
|
248386
|
+
onlyFiles: true,
|
|
248387
|
+
followSymbolicLinks: false,
|
|
248388
|
+
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
248389
|
+
});
|
|
248390
|
+
const relativeFilePaths = found.filter((path11) => !ALWAYS_IGNORED.has(basename4(path11)));
|
|
248391
|
+
if (relativeFilePaths.length > MAX_ASSET_COUNT) {
|
|
248392
|
+
throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
248393
|
+
}
|
|
248394
|
+
for (const relativePath of relativeFilePaths.sort()) {
|
|
248395
|
+
const absolutePath = join15(assetsDir, ...relativePath.split("/"));
|
|
248396
|
+
const { size } = await stat(absolutePath);
|
|
248397
|
+
if (size > MAX_ASSET_SIZE_BYTES) {
|
|
248398
|
+
throw new InvalidInputError(`Static asset "${relativePath}" is ${size} bytes, which exceeds the 25 MiB per-file limit.`);
|
|
248399
|
+
}
|
|
248400
|
+
const content = await readFile2(absolutePath);
|
|
248401
|
+
const hash2 = hashAsset(appId, content);
|
|
248402
|
+
manifest[`/${relativePath}`] = { hash: hash2, size };
|
|
248403
|
+
if (!filesByHash.has(hash2)) {
|
|
248404
|
+
filesByHash.set(hash2, { absolutePath, hash: hash2, size });
|
|
248405
|
+
}
|
|
248406
|
+
}
|
|
248407
|
+
return { manifest, filesByHash };
|
|
248408
|
+
}
|
|
248367
248409
|
// src/core/site/static-site.ts
|
|
248368
248410
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
248369
248411
|
import { join as join16 } from "node:path";
|
|
248370
248412
|
|
|
248413
|
+
// src/core/site/upload.ts
|
|
248414
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
248415
|
+
|
|
248416
|
+
// ../../node_modules/p-map/index.js
|
|
248417
|
+
async function pMap(iterable, mapper, {
|
|
248418
|
+
concurrency = Number.POSITIVE_INFINITY,
|
|
248419
|
+
stopOnError = true,
|
|
248420
|
+
signal
|
|
248421
|
+
} = {}) {
|
|
248422
|
+
return new Promise((resolve_, reject_) => {
|
|
248423
|
+
if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) {
|
|
248424
|
+
throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`);
|
|
248425
|
+
}
|
|
248426
|
+
if (typeof mapper !== "function") {
|
|
248427
|
+
throw new TypeError("Mapper function is required");
|
|
248428
|
+
}
|
|
248429
|
+
if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) {
|
|
248430
|
+
throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`);
|
|
248431
|
+
}
|
|
248432
|
+
const result = [];
|
|
248433
|
+
const errors4 = [];
|
|
248434
|
+
const skippedIndexesMap = new Map;
|
|
248435
|
+
let isRejected = false;
|
|
248436
|
+
let isResolved = false;
|
|
248437
|
+
let isIterableDone = false;
|
|
248438
|
+
let resolvingCount = 0;
|
|
248439
|
+
let currentIndex = 0;
|
|
248440
|
+
const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
|
|
248441
|
+
const signalListener = () => {
|
|
248442
|
+
reject(signal.reason);
|
|
248443
|
+
};
|
|
248444
|
+
const cleanup = () => {
|
|
248445
|
+
signal?.removeEventListener("abort", signalListener);
|
|
248446
|
+
};
|
|
248447
|
+
const resolve3 = (value) => {
|
|
248448
|
+
resolve_(value);
|
|
248449
|
+
cleanup();
|
|
248450
|
+
};
|
|
248451
|
+
const reject = (reason) => {
|
|
248452
|
+
isRejected = true;
|
|
248453
|
+
isResolved = true;
|
|
248454
|
+
reject_(reason);
|
|
248455
|
+
cleanup();
|
|
248456
|
+
};
|
|
248457
|
+
if (signal) {
|
|
248458
|
+
if (signal.aborted) {
|
|
248459
|
+
reject(signal.reason);
|
|
248460
|
+
return;
|
|
248461
|
+
}
|
|
248462
|
+
signal.addEventListener("abort", signalListener, { once: true });
|
|
248463
|
+
}
|
|
248464
|
+
const next = async () => {
|
|
248465
|
+
if (isResolved) {
|
|
248466
|
+
return;
|
|
248467
|
+
}
|
|
248468
|
+
const nextItem = await iterator.next();
|
|
248469
|
+
const index = currentIndex;
|
|
248470
|
+
currentIndex++;
|
|
248471
|
+
if (nextItem.done) {
|
|
248472
|
+
isIterableDone = true;
|
|
248473
|
+
if (resolvingCount === 0 && !isResolved) {
|
|
248474
|
+
if (!stopOnError && errors4.length > 0) {
|
|
248475
|
+
reject(new AggregateError(errors4));
|
|
248476
|
+
return;
|
|
248477
|
+
}
|
|
248478
|
+
isResolved = true;
|
|
248479
|
+
if (skippedIndexesMap.size === 0) {
|
|
248480
|
+
resolve3(result);
|
|
248481
|
+
return;
|
|
248482
|
+
}
|
|
248483
|
+
const pureResult = [];
|
|
248484
|
+
for (const [index2, value] of result.entries()) {
|
|
248485
|
+
if (skippedIndexesMap.get(index2) === pMapSkip) {
|
|
248486
|
+
continue;
|
|
248487
|
+
}
|
|
248488
|
+
pureResult.push(value);
|
|
248489
|
+
}
|
|
248490
|
+
resolve3(pureResult);
|
|
248491
|
+
}
|
|
248492
|
+
return;
|
|
248493
|
+
}
|
|
248494
|
+
resolvingCount++;
|
|
248495
|
+
(async () => {
|
|
248496
|
+
try {
|
|
248497
|
+
const element = await nextItem.value;
|
|
248498
|
+
if (isResolved) {
|
|
248499
|
+
return;
|
|
248500
|
+
}
|
|
248501
|
+
const value = await mapper(element, index);
|
|
248502
|
+
if (value === pMapSkip) {
|
|
248503
|
+
skippedIndexesMap.set(index, value);
|
|
248504
|
+
}
|
|
248505
|
+
result[index] = value;
|
|
248506
|
+
resolvingCount--;
|
|
248507
|
+
await next();
|
|
248508
|
+
} catch (error48) {
|
|
248509
|
+
if (stopOnError) {
|
|
248510
|
+
reject(error48);
|
|
248511
|
+
} else {
|
|
248512
|
+
errors4.push(error48);
|
|
248513
|
+
resolvingCount--;
|
|
248514
|
+
try {
|
|
248515
|
+
await next();
|
|
248516
|
+
} catch (error49) {
|
|
248517
|
+
reject(error49);
|
|
248518
|
+
}
|
|
248519
|
+
}
|
|
248520
|
+
}
|
|
248521
|
+
})();
|
|
248522
|
+
};
|
|
248523
|
+
(async () => {
|
|
248524
|
+
for (let index = 0;index < concurrency; index++) {
|
|
248525
|
+
try {
|
|
248526
|
+
await next();
|
|
248527
|
+
} catch (error48) {
|
|
248528
|
+
reject(error48);
|
|
248529
|
+
break;
|
|
248530
|
+
}
|
|
248531
|
+
if (isIterableDone || isRejected) {
|
|
248532
|
+
break;
|
|
248533
|
+
}
|
|
248534
|
+
}
|
|
248535
|
+
})();
|
|
248536
|
+
});
|
|
248537
|
+
}
|
|
248538
|
+
var pMapSkip = Symbol("skip");
|
|
248539
|
+
|
|
248540
|
+
// src/core/site/upload.ts
|
|
248541
|
+
var DEFAULT_UPLOAD_CONCURRENCY = 3;
|
|
248542
|
+
var MAX_UPLOAD_CONCURRENCY = 50;
|
|
248543
|
+
var MAX_UPLOAD_ATTEMPTS = 3;
|
|
248544
|
+
var RETRY_BASE_DELAY_MS = 500;
|
|
248545
|
+
async function uploadPresignedAssets(uploads, assets, options = {}) {
|
|
248546
|
+
const { concurrency = DEFAULT_UPLOAD_CONCURRENCY, onProgress } = options;
|
|
248547
|
+
let uploadedFiles = 0;
|
|
248548
|
+
await pMap(uploads, async (upload) => {
|
|
248549
|
+
await uploadPresignedAsset(upload, assets);
|
|
248550
|
+
uploadedFiles++;
|
|
248551
|
+
onProgress?.({ uploadedFiles, totalFiles: uploads.length });
|
|
248552
|
+
}, { concurrency });
|
|
248553
|
+
}
|
|
248554
|
+
async function uploadPresignedAsset(upload, assets) {
|
|
248555
|
+
const entry = assets.manifest[upload.path];
|
|
248556
|
+
const file2 = entry && assets.filesByHash.get(entry.hash);
|
|
248557
|
+
if (!file2) {
|
|
248558
|
+
throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
|
|
248559
|
+
}
|
|
248560
|
+
const content = await readFile3(file2.absolutePath);
|
|
248561
|
+
try {
|
|
248562
|
+
await distribution_default.put(upload.url, {
|
|
248563
|
+
body: new Uint8Array(content),
|
|
248564
|
+
headers: { "Content-Type": upload.contentType },
|
|
248565
|
+
timeout: 120000,
|
|
248566
|
+
retry: {
|
|
248567
|
+
limit: MAX_UPLOAD_ATTEMPTS - 1,
|
|
248568
|
+
delay: (attempt) => RETRY_BASE_DELAY_MS * 2 ** (attempt - 1)
|
|
248569
|
+
}
|
|
248570
|
+
});
|
|
248571
|
+
} catch (error48) {
|
|
248572
|
+
throw await ApiError.fromHttpError(error48, "uploading static assets");
|
|
248573
|
+
}
|
|
248574
|
+
}
|
|
248575
|
+
|
|
248576
|
+
// src/core/site/static-site.ts
|
|
248577
|
+
async function deployStaticSite(options) {
|
|
248578
|
+
const { outputDir, gitHash, concurrency, progress } = options;
|
|
248579
|
+
const assets = await buildAssetManifest(outputDir, getAppContext().id);
|
|
248580
|
+
if (!assets.manifest["/index.html"]) {
|
|
248581
|
+
throw new InvalidInputError(`No index.html found in "${outputDir}" — a static site needs one at the output directory root.`);
|
|
248582
|
+
}
|
|
248583
|
+
const created = await createDeployment({
|
|
248584
|
+
git_hash: gitHash,
|
|
248585
|
+
asset_manifest: assets.manifest
|
|
248586
|
+
});
|
|
248587
|
+
progress?.onAssets?.({
|
|
248588
|
+
totalAssets: Object.keys(assets.manifest).length,
|
|
248589
|
+
newAssets: created.assetUploads?.uploads.length ?? 0
|
|
248590
|
+
});
|
|
248591
|
+
if (created.assetUploads) {
|
|
248592
|
+
await uploadPresignedAssets(created.assetUploads.uploads, assets, {
|
|
248593
|
+
concurrency,
|
|
248594
|
+
onProgress: progress?.onAssetUpload
|
|
248595
|
+
});
|
|
248596
|
+
}
|
|
248597
|
+
const indexHtml = await readFile4(join16(outputDir, "index.html"));
|
|
248598
|
+
const finalized = await finalizeStaticDeployment(created.deploymentId, new Uint8Array(indexHtml));
|
|
248599
|
+
return { deploymentId: finalized.deploymentId };
|
|
248600
|
+
}
|
|
248601
|
+
// src/core/project/deploy.ts
|
|
248602
|
+
function hasResourcesToDeploy(projectData) {
|
|
248603
|
+
const {
|
|
248604
|
+
project,
|
|
248605
|
+
entities,
|
|
248606
|
+
functions,
|
|
248607
|
+
agents,
|
|
248608
|
+
agentSkills,
|
|
248609
|
+
connectors,
|
|
248610
|
+
authConfig
|
|
248611
|
+
} = projectData;
|
|
248612
|
+
const hasSite = Boolean(project.site?.outputDirectory);
|
|
248613
|
+
const hasEntities = entities.length > 0;
|
|
248614
|
+
const hasFunctions = functions.length > 0;
|
|
248615
|
+
const hasAgents = agents.length > 0;
|
|
248616
|
+
const hasAgentSkills = agentSkills.length > 0;
|
|
248617
|
+
const hasConnectors = connectors.length > 0;
|
|
248618
|
+
const hasAuthConfig = authConfig.length > 0;
|
|
248619
|
+
const hasVisibility = Boolean(project.visibility);
|
|
248620
|
+
return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
|
|
248621
|
+
}
|
|
248622
|
+
async function deployAll(projectData, options) {
|
|
248623
|
+
const {
|
|
248624
|
+
project,
|
|
248625
|
+
entities,
|
|
248626
|
+
functions,
|
|
248627
|
+
agents,
|
|
248628
|
+
agentSkills,
|
|
248629
|
+
connectors,
|
|
248630
|
+
authConfig
|
|
248631
|
+
} = projectData;
|
|
248632
|
+
await setAppVisibility(project.visibility);
|
|
248633
|
+
if (project.visibility) {
|
|
248634
|
+
options?.onVisibilitySet?.(project.visibility);
|
|
248635
|
+
}
|
|
248636
|
+
await entityResource.push(entities);
|
|
248637
|
+
await deployFunctionsSequentially(functions, {
|
|
248638
|
+
onStart: options?.onFunctionStart,
|
|
248639
|
+
onResult: options?.onFunctionResult
|
|
248640
|
+
});
|
|
248641
|
+
await agentSkillResource.push(agentSkills);
|
|
248642
|
+
await agentResource.push(agents);
|
|
248643
|
+
await authConfigResource.push(authConfig);
|
|
248644
|
+
const skipConnectorSync = connectors.length === 0 && hasWorkspaceApiKeyAuth();
|
|
248645
|
+
const connectorResults = skipConnectorSync ? [] : (await pushConnectors(connectors)).results;
|
|
248646
|
+
if (project.site?.outputDirectory) {
|
|
248647
|
+
const outputDir = resolve3(project.root, project.site.outputDirectory);
|
|
248648
|
+
const { appUrl } = await deploySite(outputDir);
|
|
248649
|
+
return { appUrl, connectorResults };
|
|
248650
|
+
}
|
|
248651
|
+
return { connectorResults };
|
|
248652
|
+
}
|
|
248653
|
+
// src/core/clients/base44-client.ts
|
|
248654
|
+
var retriedRequests = new WeakSet;
|
|
248655
|
+
async function captureRequestBody(request, options) {
|
|
248656
|
+
if (request.body == null) {
|
|
248657
|
+
return;
|
|
248658
|
+
}
|
|
248659
|
+
try {
|
|
248660
|
+
const cloned = request.clone();
|
|
248661
|
+
const text = await cloned.text();
|
|
248662
|
+
options.context.__requestBody = text;
|
|
248663
|
+
} catch {}
|
|
248664
|
+
}
|
|
248665
|
+
async function handleUnauthorized(request, _options, response) {
|
|
248666
|
+
if (response.status !== 401) {
|
|
248667
|
+
return;
|
|
248668
|
+
}
|
|
248669
|
+
if (hasWorkspaceApiKeyAuth()) {
|
|
248670
|
+
return;
|
|
248671
|
+
}
|
|
248672
|
+
if (retriedRequests.has(request)) {
|
|
248673
|
+
return;
|
|
248674
|
+
}
|
|
248675
|
+
const newAccessToken = await refreshAndSaveTokens();
|
|
248676
|
+
if (!newAccessToken) {
|
|
248677
|
+
return;
|
|
248678
|
+
}
|
|
248679
|
+
retriedRequests.add(request);
|
|
248680
|
+
const requestId = request.headers.get("X-Request-ID");
|
|
248681
|
+
return distribution_default(request.clone(), {
|
|
248682
|
+
headers: {
|
|
248683
|
+
...requestId && { "X-Request-ID": requestId },
|
|
248684
|
+
Authorization: `Bearer ${newAccessToken}`
|
|
248685
|
+
}
|
|
248686
|
+
});
|
|
248687
|
+
}
|
|
248688
|
+
var base44Client = distribution_default.create({
|
|
248689
|
+
prefixUrl: getBase44ApiUrl(),
|
|
248690
|
+
headers: {
|
|
248691
|
+
"User-Agent": "Base44 CLI"
|
|
248692
|
+
},
|
|
248693
|
+
hooks: {
|
|
248694
|
+
beforeRequest: [
|
|
248695
|
+
(request) => {
|
|
248696
|
+
request.headers.set("X-Request-ID", randomUUID2());
|
|
248697
|
+
},
|
|
248698
|
+
captureRequestBody,
|
|
248699
|
+
async (request) => {
|
|
248700
|
+
const workspaceApiKey = getWorkspaceApiKeyFromEnv();
|
|
248701
|
+
if (workspaceApiKey && isWorkspaceApiKey(workspaceApiKey)) {
|
|
248702
|
+
request.headers.set("api_key", workspaceApiKey);
|
|
248703
|
+
return;
|
|
248704
|
+
}
|
|
248705
|
+
try {
|
|
248706
|
+
const auth = await readAuth();
|
|
248707
|
+
if (isTokenExpired(auth)) {
|
|
248708
|
+
const newAccessToken = await refreshAndSaveTokens();
|
|
248709
|
+
if (newAccessToken) {
|
|
248710
|
+
request.headers.set("Authorization", `Bearer ${newAccessToken}`);
|
|
248711
|
+
return;
|
|
248712
|
+
}
|
|
248713
|
+
}
|
|
248714
|
+
request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
|
|
248715
|
+
} catch {}
|
|
248716
|
+
}
|
|
248717
|
+
],
|
|
248718
|
+
afterResponse: [handleUnauthorized]
|
|
248719
|
+
}
|
|
248720
|
+
});
|
|
248721
|
+
function getAppClient() {
|
|
248722
|
+
const { id } = getAppContext();
|
|
248723
|
+
return base44Client.extend({
|
|
248724
|
+
prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
|
|
248725
|
+
});
|
|
248726
|
+
}
|
|
248727
|
+
function getSandboxClient(appId) {
|
|
248728
|
+
return base44Client.extend({
|
|
248729
|
+
prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
|
|
248730
|
+
});
|
|
248731
|
+
}
|
|
248732
|
+
// src/core/clients/oauth-client.ts
|
|
248733
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
248734
|
+
var oauthClient = distribution_default.create({
|
|
248735
|
+
prefixUrl: getBase44ApiUrl(),
|
|
248736
|
+
headers: {
|
|
248737
|
+
"User-Agent": "Base44 CLI"
|
|
248738
|
+
},
|
|
248739
|
+
hooks: {
|
|
248740
|
+
beforeRequest: [
|
|
248741
|
+
(request) => {
|
|
248742
|
+
request.headers.set("X-Request-ID", randomUUID3());
|
|
248743
|
+
}
|
|
248744
|
+
]
|
|
248745
|
+
}
|
|
248746
|
+
});
|
|
248747
|
+
// src/core/auth/api.ts
|
|
248748
|
+
async function generateDeviceCode() {
|
|
248749
|
+
const response = await oauthClient.post("oauth/device/code", {
|
|
248750
|
+
json: {
|
|
248751
|
+
client_id: AUTH_CLIENT_ID,
|
|
248752
|
+
scope: "apps:read apps:write sandbox:write"
|
|
248753
|
+
},
|
|
248754
|
+
throwHttpErrors: false
|
|
248755
|
+
});
|
|
248756
|
+
if (!response.ok) {
|
|
248757
|
+
throw new ApiError(`Failed to generate device code: ${response.status} ${response.statusText}`, { statusCode: response.status });
|
|
248758
|
+
}
|
|
248759
|
+
const result = DeviceCodeResponseSchema.safeParse(await response.json());
|
|
248760
|
+
if (!result.success) {
|
|
248761
|
+
throw new SchemaValidationError("Invalid device code response from server", result.error);
|
|
248762
|
+
}
|
|
248763
|
+
return result.data;
|
|
248764
|
+
}
|
|
248765
|
+
async function getTokenFromDeviceCode(deviceCode) {
|
|
248766
|
+
const searchParams = new URLSearchParams;
|
|
248767
|
+
searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
|
|
248768
|
+
searchParams.set("device_code", deviceCode);
|
|
248769
|
+
searchParams.set("client_id", AUTH_CLIENT_ID);
|
|
248770
|
+
const response = await oauthClient.post("oauth/token", {
|
|
248771
|
+
body: searchParams.toString(),
|
|
248772
|
+
headers: {
|
|
248773
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
248774
|
+
},
|
|
248775
|
+
throwHttpErrors: false
|
|
248776
|
+
});
|
|
248777
|
+
const json2 = await response.json();
|
|
248778
|
+
if (!response.ok) {
|
|
248779
|
+
const errorResult = OAuthErrorSchema.safeParse(json2);
|
|
248780
|
+
if (!errorResult.success) {
|
|
248781
|
+
throw new SchemaValidationError("Token request failed", errorResult.error);
|
|
248782
|
+
}
|
|
248783
|
+
const { error: error48, error_description } = errorResult.data;
|
|
248784
|
+
if (error48 === "authorization_pending" || error48 === "slow_down") {
|
|
248785
|
+
return null;
|
|
248786
|
+
}
|
|
248787
|
+
throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
|
|
248788
|
+
statusCode: response.status
|
|
248789
|
+
});
|
|
248790
|
+
}
|
|
248791
|
+
const result = TokenResponseSchema.safeParse(json2);
|
|
248792
|
+
if (!result.success) {
|
|
248793
|
+
throw new SchemaValidationError("Invalid token response from server", result.error);
|
|
248794
|
+
}
|
|
248795
|
+
return result.data;
|
|
248796
|
+
}
|
|
248797
|
+
async function renewAccessToken(refreshToken) {
|
|
248798
|
+
const searchParams = new URLSearchParams;
|
|
248799
|
+
searchParams.set("grant_type", "refresh_token");
|
|
248800
|
+
searchParams.set("refresh_token", refreshToken);
|
|
248801
|
+
searchParams.set("client_id", AUTH_CLIENT_ID);
|
|
248802
|
+
const response = await oauthClient.post("oauth/token", {
|
|
248803
|
+
body: searchParams.toString(),
|
|
248804
|
+
headers: {
|
|
248805
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
248806
|
+
},
|
|
248807
|
+
throwHttpErrors: false
|
|
248808
|
+
});
|
|
248809
|
+
const json2 = await response.json();
|
|
248810
|
+
if (!response.ok) {
|
|
248811
|
+
const errorResult = OAuthErrorSchema.safeParse(json2);
|
|
248812
|
+
if (!errorResult.success) {
|
|
248813
|
+
throw new ApiError(`Token refresh failed: ${response.statusText}`, {
|
|
248814
|
+
statusCode: response.status
|
|
248815
|
+
});
|
|
248816
|
+
}
|
|
248817
|
+
const { error: error48, error_description } = errorResult.data;
|
|
248818
|
+
throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
|
|
248819
|
+
statusCode: response.status
|
|
248820
|
+
});
|
|
248821
|
+
}
|
|
248822
|
+
const result = TokenResponseSchema.safeParse(json2);
|
|
248823
|
+
if (!result.success) {
|
|
248824
|
+
throw new SchemaValidationError("Invalid token response from server", result.error);
|
|
248825
|
+
}
|
|
248826
|
+
return result.data;
|
|
248827
|
+
}
|
|
248828
|
+
async function getUserInfo(accessToken) {
|
|
248829
|
+
const response = await oauthClient.get("oauth/userinfo", {
|
|
248830
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
248831
|
+
});
|
|
248832
|
+
if (!response.ok) {
|
|
248833
|
+
throw new ApiError(`Failed to fetch user info: ${response.status}`, {
|
|
248834
|
+
statusCode: response.status
|
|
248835
|
+
});
|
|
248836
|
+
}
|
|
248837
|
+
const result = UserInfoSchema.safeParse(await response.json());
|
|
248838
|
+
if (!result.success) {
|
|
248839
|
+
throw new SchemaValidationError("Invalid UserInfo response from server", result.error);
|
|
248840
|
+
}
|
|
248841
|
+
return result.data;
|
|
248842
|
+
}
|
|
248843
|
+
// src/cli/commands/auth/login-flow.ts
|
|
248844
|
+
async function generateAndDisplayDeviceCode(log, runTask) {
|
|
248845
|
+
const deviceCodeResponse = await runTask("Generating device code...", async () => {
|
|
248846
|
+
return await generateDeviceCode();
|
|
248847
|
+
}, {
|
|
248848
|
+
successMessage: "Device code generated",
|
|
248849
|
+
errorMessage: "Failed to generate device code"
|
|
248850
|
+
});
|
|
248851
|
+
log.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}` + `
|
|
248852
|
+
Please confirm this code at: ${deviceCodeResponse.verificationUri}`);
|
|
248853
|
+
return deviceCodeResponse;
|
|
248854
|
+
}
|
|
248855
|
+
async function waitForAuthentication(deviceCode, expiresIn, interval, runTask) {
|
|
248856
|
+
let tokenResponse;
|
|
248857
|
+
try {
|
|
248858
|
+
await runTask("Waiting for authentication...", async () => {
|
|
248859
|
+
await pWaitFor(async () => {
|
|
248860
|
+
const result = await getTokenFromDeviceCode(deviceCode);
|
|
248861
|
+
if (result !== null) {
|
|
248862
|
+
tokenResponse = result;
|
|
248863
|
+
return true;
|
|
248864
|
+
}
|
|
248865
|
+
return false;
|
|
248866
|
+
}, {
|
|
248867
|
+
interval: interval * 1000,
|
|
248868
|
+
timeout: expiresIn * 1000
|
|
248869
|
+
});
|
|
248870
|
+
}, {
|
|
248871
|
+
successMessage: "Authentication completed!",
|
|
248872
|
+
errorMessage: "Authentication failed"
|
|
248873
|
+
});
|
|
248874
|
+
} catch (error48) {
|
|
248875
|
+
if (error48 instanceof Error && error48.message.includes("timed out")) {
|
|
248876
|
+
throw new AuthExpiredError("Authentication timed out. Please try again.");
|
|
248877
|
+
}
|
|
248878
|
+
throw error48;
|
|
248879
|
+
}
|
|
248880
|
+
if (tokenResponse === undefined) {
|
|
248881
|
+
throw new InternalError("Failed to retrieve authentication token.");
|
|
248882
|
+
}
|
|
248883
|
+
return tokenResponse;
|
|
248884
|
+
}
|
|
248885
|
+
async function saveAuthData(response, userInfo) {
|
|
248886
|
+
const expiresAt = Date.now() + response.expiresIn * 1000;
|
|
248887
|
+
await writeAuth({
|
|
248888
|
+
accessToken: response.accessToken,
|
|
248889
|
+
refreshToken: response.refreshToken,
|
|
248890
|
+
expiresAt,
|
|
248891
|
+
email: userInfo.email,
|
|
248892
|
+
name: userInfo.name
|
|
248893
|
+
});
|
|
248894
|
+
}
|
|
248895
|
+
async function login({
|
|
248896
|
+
log,
|
|
248897
|
+
runTask
|
|
248898
|
+
}) {
|
|
248899
|
+
const deviceCodeResponse = await generateAndDisplayDeviceCode(log, runTask);
|
|
248900
|
+
const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval, runTask);
|
|
248901
|
+
const userInfo = await getUserInfo(token.accessToken);
|
|
248902
|
+
await saveAuthData(token, userInfo);
|
|
248903
|
+
return {
|
|
248904
|
+
outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}`
|
|
248905
|
+
};
|
|
248906
|
+
}
|
|
248907
|
+
|
|
248908
|
+
// src/cli/utils/command/middleware.ts
|
|
248909
|
+
async function ensureAuth(ctx) {
|
|
248910
|
+
if (hasWorkspaceApiKeyAuth()) {
|
|
248911
|
+
ctx.errorReporter.setContext({
|
|
248912
|
+
user: { email: "workspace-api-key", name: "Workspace API key" }
|
|
248913
|
+
});
|
|
248914
|
+
return;
|
|
248915
|
+
}
|
|
248916
|
+
await seedAuthFromEnv();
|
|
248917
|
+
const loggedIn = await isLoggedIn();
|
|
248918
|
+
if (!loggedIn) {
|
|
248919
|
+
ctx.log.info("You need to login first to continue.");
|
|
248920
|
+
await login(ctx);
|
|
248921
|
+
}
|
|
248922
|
+
try {
|
|
248923
|
+
const userInfo = await readAuth();
|
|
248924
|
+
ctx.errorReporter.setContext({
|
|
248925
|
+
user: { email: userInfo.email, name: userInfo.name }
|
|
248926
|
+
});
|
|
248927
|
+
} catch {}
|
|
248928
|
+
}
|
|
248929
|
+
async function ensureAppContext(ctx, options = {}) {
|
|
248930
|
+
const appContext = await initAppContext(options);
|
|
248931
|
+
ctx.app = appContext;
|
|
248932
|
+
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
248933
|
+
}
|
|
248934
|
+
|
|
248371
248935
|
// ../../node_modules/is-plain-obj/index.js
|
|
248372
248936
|
function isPlainObject2(value) {
|
|
248373
248937
|
if (typeof value !== "object" || value === null) {
|
|
@@ -248465,13 +249029,13 @@ var getJoinLength = (uint8Arrays) => {
|
|
|
248465
249029
|
var isTemplateString = (templates) => Array.isArray(templates) && Array.isArray(templates.raw);
|
|
248466
249030
|
var parseTemplates = (templates, expressions) => {
|
|
248467
249031
|
let tokens = [];
|
|
248468
|
-
for (const [index,
|
|
249032
|
+
for (const [index, template2] of templates.entries()) {
|
|
248469
249033
|
tokens = parseTemplate({
|
|
248470
249034
|
templates,
|
|
248471
249035
|
expressions,
|
|
248472
249036
|
tokens,
|
|
248473
249037
|
index,
|
|
248474
|
-
template
|
|
249038
|
+
template: template2
|
|
248475
249039
|
});
|
|
248476
249040
|
}
|
|
248477
249041
|
if (tokens.length === 0) {
|
|
@@ -248480,11 +249044,11 @@ var parseTemplates = (templates, expressions) => {
|
|
|
248480
249044
|
const [file2, ...commandArguments] = tokens;
|
|
248481
249045
|
return [file2, commandArguments, {}];
|
|
248482
249046
|
};
|
|
248483
|
-
var parseTemplate = ({ templates, expressions, tokens, index, template }) => {
|
|
248484
|
-
if (
|
|
249047
|
+
var parseTemplate = ({ templates, expressions, tokens, index, template: template2 }) => {
|
|
249048
|
+
if (template2 === undefined) {
|
|
248485
249049
|
throw new TypeError(`Invalid backslash sequence: ${templates.raw[index]}`);
|
|
248486
249050
|
}
|
|
248487
|
-
const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(
|
|
249051
|
+
const { nextTokens, leadingWhitespaces, trailingWhitespaces } = splitByWhitespaces(template2, templates.raw[index]);
|
|
248488
249052
|
const newTokens = concatTokens(tokens, nextTokens, leadingWhitespaces);
|
|
248489
249053
|
if (index === expressions.length) {
|
|
248490
249054
|
return newTokens;
|
|
@@ -248493,18 +249057,18 @@ var parseTemplate = ({ templates, expressions, tokens, index, template }) => {
|
|
|
248493
249057
|
const expressionTokens = Array.isArray(expression) ? expression.map((expression2) => parseExpression(expression2)) : [parseExpression(expression)];
|
|
248494
249058
|
return concatTokens(newTokens, expressionTokens, trailingWhitespaces);
|
|
248495
249059
|
};
|
|
248496
|
-
var splitByWhitespaces = (
|
|
249060
|
+
var splitByWhitespaces = (template2, rawTemplate) => {
|
|
248497
249061
|
if (rawTemplate.length === 0) {
|
|
248498
249062
|
return { nextTokens: [], leadingWhitespaces: false, trailingWhitespaces: false };
|
|
248499
249063
|
}
|
|
248500
249064
|
const nextTokens = [];
|
|
248501
249065
|
let templateStart = 0;
|
|
248502
249066
|
const leadingWhitespaces = DELIMITERS.has(rawTemplate[0]);
|
|
248503
|
-
for (let templateIndex = 0, rawIndex = 0;templateIndex <
|
|
249067
|
+
for (let templateIndex = 0, rawIndex = 0;templateIndex < template2.length; templateIndex += 1, rawIndex += 1) {
|
|
248504
249068
|
const rawCharacter = rawTemplate[rawIndex];
|
|
248505
249069
|
if (DELIMITERS.has(rawCharacter)) {
|
|
248506
249070
|
if (templateStart !== templateIndex) {
|
|
248507
|
-
nextTokens.push(
|
|
249071
|
+
nextTokens.push(template2.slice(templateStart, templateIndex));
|
|
248508
249072
|
}
|
|
248509
249073
|
templateStart = templateIndex + 1;
|
|
248510
249074
|
} else if (rawCharacter === "\\") {
|
|
@@ -248520,9 +249084,9 @@ var splitByWhitespaces = (template, rawTemplate) => {
|
|
|
248520
249084
|
}
|
|
248521
249085
|
}
|
|
248522
249086
|
}
|
|
248523
|
-
const trailingWhitespaces = templateStart ===
|
|
249087
|
+
const trailingWhitespaces = templateStart === template2.length;
|
|
248524
249088
|
if (!trailingWhitespaces) {
|
|
248525
|
-
nextTokens.push(
|
|
249089
|
+
nextTokens.push(template2.slice(templateStart));
|
|
248526
249090
|
}
|
|
248527
249091
|
return { nextTokens, leadingWhitespaces, trailingWhitespaces };
|
|
248528
249092
|
};
|
|
@@ -249916,8 +250480,8 @@ var disconnect = (anyProcess) => {
|
|
|
249916
250480
|
// ../../node_modules/execa/lib/utils/deferred.js
|
|
249917
250481
|
var createDeferred = () => {
|
|
249918
250482
|
const methods = {};
|
|
249919
|
-
const promise2 = new Promise((
|
|
249920
|
-
Object.assign(methods, { resolve:
|
|
250483
|
+
const promise2 = new Promise((resolve4, reject) => {
|
|
250484
|
+
Object.assign(methods, { resolve: resolve4, reject });
|
|
249921
250485
|
});
|
|
249922
250486
|
return Object.assign(promise2, methods);
|
|
249923
250487
|
};
|
|
@@ -254281,11 +254845,11 @@ var addConcurrentStream = (concurrentStreams, stream, waitName) => {
|
|
|
254281
254845
|
const promises = weakMap.get(stream);
|
|
254282
254846
|
const promise2 = createDeferred();
|
|
254283
254847
|
promises.push(promise2);
|
|
254284
|
-
const
|
|
254285
|
-
return { resolve:
|
|
254848
|
+
const resolve4 = promise2.resolve.bind(promise2);
|
|
254849
|
+
return { resolve: resolve4, promises };
|
|
254286
254850
|
};
|
|
254287
|
-
var waitForConcurrentStreams = async ({ resolve:
|
|
254288
|
-
|
|
254851
|
+
var waitForConcurrentStreams = async ({ resolve: resolve4, promises }, subprocess) => {
|
|
254852
|
+
resolve4();
|
|
254289
254853
|
const [isSubprocessExit] = await Promise.race([
|
|
254290
254854
|
Promise.allSettled([true, subprocess]),
|
|
254291
254855
|
Promise.all([false, ...promises])
|
|
@@ -254864,523 +255428,6 @@ var {
|
|
|
254864
255428
|
getCancelSignal: getCancelSignal2
|
|
254865
255429
|
} = getIpcExport();
|
|
254866
255430
|
|
|
254867
|
-
// src/core/utils/git.ts
|
|
254868
|
-
var GIT_HASH_PATTERN = /^[a-fA-F0-9]{7,64}$/;
|
|
254869
|
-
function isGitCommitHash(value) {
|
|
254870
|
-
return GIT_HASH_PATTERN.test(value);
|
|
254871
|
-
}
|
|
254872
|
-
async function getGitHead(cwd) {
|
|
254873
|
-
try {
|
|
254874
|
-
const { stdout } = await execa("git", ["rev-parse", "HEAD"], { cwd });
|
|
254875
|
-
return stdout.trim();
|
|
254876
|
-
} catch {
|
|
254877
|
-
return null;
|
|
254878
|
-
}
|
|
254879
|
-
}
|
|
254880
|
-
|
|
254881
|
-
// src/core/site/manifest.ts
|
|
254882
|
-
import { createHash } from "node:crypto";
|
|
254883
|
-
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
254884
|
-
import { basename as basename4, join as join15 } from "node:path";
|
|
254885
|
-
var MAX_ASSET_SIZE_BYTES = 25 * 1024 * 1024;
|
|
254886
|
-
var MAX_ASSET_COUNT = 1e5;
|
|
254887
|
-
var ASSETS_IGNORE_FILE = ".assetsignore";
|
|
254888
|
-
var ALWAYS_IGNORED = new Set([
|
|
254889
|
-
ASSETS_IGNORE_FILE,
|
|
254890
|
-
"wrangler.json",
|
|
254891
|
-
".dev.vars"
|
|
254892
|
-
]);
|
|
254893
|
-
function hashAsset(appId, content) {
|
|
254894
|
-
return createHash("sha256").update(Buffer.from(appId, "utf8")).update(content).digest("hex").slice(0, 32);
|
|
254895
|
-
}
|
|
254896
|
-
async function buildAssetManifest(assetsDir, appId) {
|
|
254897
|
-
const manifest = {};
|
|
254898
|
-
const filesByHash = new Map;
|
|
254899
|
-
const found = await globby("**/*", {
|
|
254900
|
-
cwd: assetsDir,
|
|
254901
|
-
dot: true,
|
|
254902
|
-
onlyFiles: true,
|
|
254903
|
-
followSymbolicLinks: false,
|
|
254904
|
-
ignoreFiles: [ASSETS_IGNORE_FILE]
|
|
254905
|
-
});
|
|
254906
|
-
const relativeFilePaths = found.filter((path16) => !ALWAYS_IGNORED.has(basename4(path16)));
|
|
254907
|
-
if (relativeFilePaths.length > MAX_ASSET_COUNT) {
|
|
254908
|
-
throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
|
|
254909
|
-
}
|
|
254910
|
-
for (const relativePath of relativeFilePaths.sort()) {
|
|
254911
|
-
const absolutePath = join15(assetsDir, ...relativePath.split("/"));
|
|
254912
|
-
const { size } = await stat(absolutePath);
|
|
254913
|
-
if (size > MAX_ASSET_SIZE_BYTES) {
|
|
254914
|
-
throw new InvalidInputError(`Static asset "${relativePath}" is ${size} bytes, which exceeds the 25 MiB per-file limit.`);
|
|
254915
|
-
}
|
|
254916
|
-
const content = await readFile2(absolutePath);
|
|
254917
|
-
const hash2 = hashAsset(appId, content);
|
|
254918
|
-
manifest[`/${relativePath}`] = { hash: hash2, size };
|
|
254919
|
-
if (!filesByHash.has(hash2)) {
|
|
254920
|
-
filesByHash.set(hash2, { absolutePath, hash: hash2, size });
|
|
254921
|
-
}
|
|
254922
|
-
}
|
|
254923
|
-
return { manifest, filesByHash };
|
|
254924
|
-
}
|
|
254925
|
-
|
|
254926
|
-
// src/core/site/upload.ts
|
|
254927
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
254928
|
-
var UPLOAD_CONCURRENCY = 3;
|
|
254929
|
-
var MAX_ATTEMPTS_PER_UPLOAD = 3;
|
|
254930
|
-
var RETRY_BASE_DELAY_MS = 500;
|
|
254931
|
-
async function uploadPresignedAssets(uploads, assets, onProgress) {
|
|
254932
|
-
let uploadedFiles = 0;
|
|
254933
|
-
let nextUpload = 0;
|
|
254934
|
-
const worker = async () => {
|
|
254935
|
-
while (nextUpload < uploads.length) {
|
|
254936
|
-
const upload = uploads[nextUpload++];
|
|
254937
|
-
await uploadPresignedAssetWithRetry(upload, assets);
|
|
254938
|
-
uploadedFiles++;
|
|
254939
|
-
onProgress?.({ uploadedFiles, totalFiles: uploads.length });
|
|
254940
|
-
}
|
|
254941
|
-
};
|
|
254942
|
-
await Promise.all(Array.from({ length: Math.min(UPLOAD_CONCURRENCY, uploads.length) }, worker));
|
|
254943
|
-
}
|
|
254944
|
-
async function uploadPresignedAssetWithRetry(upload, assets) {
|
|
254945
|
-
const entry = assets.manifest[upload.path];
|
|
254946
|
-
const file2 = entry && assets.filesByHash.get(entry.hash);
|
|
254947
|
-
if (!file2) {
|
|
254948
|
-
throw new InternalError(`Server requested upload of unknown asset path: ${upload.path}`);
|
|
254949
|
-
}
|
|
254950
|
-
const content = await readFile3(file2.absolutePath);
|
|
254951
|
-
let lastError;
|
|
254952
|
-
for (let attempt = 0;attempt < MAX_ATTEMPTS_PER_UPLOAD; attempt++) {
|
|
254953
|
-
if (attempt > 0) {
|
|
254954
|
-
await sleep3(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
|
|
254955
|
-
}
|
|
254956
|
-
try {
|
|
254957
|
-
await distribution_default.put(upload.url, {
|
|
254958
|
-
body: new Uint8Array(content),
|
|
254959
|
-
headers: { "Content-Type": upload.contentType },
|
|
254960
|
-
timeout: 120000,
|
|
254961
|
-
retry: 0
|
|
254962
|
-
});
|
|
254963
|
-
return;
|
|
254964
|
-
} catch (error48) {
|
|
254965
|
-
lastError = error48;
|
|
254966
|
-
}
|
|
254967
|
-
}
|
|
254968
|
-
throw await ApiError.fromHttpError(lastError, "uploading static assets");
|
|
254969
|
-
}
|
|
254970
|
-
function sleep3(ms) {
|
|
254971
|
-
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
254972
|
-
}
|
|
254973
|
-
|
|
254974
|
-
// src/core/site/static-site.ts
|
|
254975
|
-
async function deployStaticSite(options) {
|
|
254976
|
-
const { outputDir, projectRoot, progress } = options;
|
|
254977
|
-
const gitHash = await resolveGitHash(projectRoot, options.gitHash);
|
|
254978
|
-
const assets = await buildAssetManifest(outputDir, getAppContext().id);
|
|
254979
|
-
if (!assets.manifest["/index.html"]) {
|
|
254980
|
-
throw new InvalidInputError(`No index.html found in "${outputDir}" — a static site needs one at the output directory root.`);
|
|
254981
|
-
}
|
|
254982
|
-
const created = await createDeployment({
|
|
254983
|
-
git_hash: gitHash,
|
|
254984
|
-
asset_manifest: assets.manifest
|
|
254985
|
-
});
|
|
254986
|
-
const totalAssets = Object.keys(assets.manifest).length;
|
|
254987
|
-
progress?.onAssets?.({
|
|
254988
|
-
totalAssets,
|
|
254989
|
-
newAssets: created.assetUploads?.uploads.length ?? 0
|
|
254990
|
-
});
|
|
254991
|
-
if (created.assetUploads) {
|
|
254992
|
-
await uploadPresignedAssets(created.assetUploads.uploads, assets, progress?.onAssetUpload);
|
|
254993
|
-
}
|
|
254994
|
-
const indexHtml = await readFile4(join16(outputDir, "index.html"));
|
|
254995
|
-
const finalized = await finalizeStaticDeployment(created.deploymentId, new Uint8Array(indexHtml));
|
|
254996
|
-
return { deploymentId: finalized.deploymentId, gitHash };
|
|
254997
|
-
}
|
|
254998
|
-
async function resolveGitHash(projectRoot, explicit) {
|
|
254999
|
-
const hash2 = explicit ?? await getGitHead(projectRoot);
|
|
255000
|
-
if (!hash2 || !isGitCommitHash(hash2)) {
|
|
255001
|
-
throw new InvalidInputError(explicit ? `'${explicit}' is not a git commit hash.` : "Deployments are addressed by the commit that produced the build, and no git commit was found.", {
|
|
255002
|
-
hints: [
|
|
255003
|
-
{
|
|
255004
|
-
message: "Run the deploy from a git checkout, or pass the commit explicitly: base44 site deploy --git-hash <commit>."
|
|
255005
|
-
}
|
|
255006
|
-
]
|
|
255007
|
-
});
|
|
255008
|
-
}
|
|
255009
|
-
return hash2;
|
|
255010
|
-
}
|
|
255011
|
-
|
|
255012
|
-
// src/core/site/deploy-app.ts
|
|
255013
|
-
function planAppDeploy(target, staticDeployments) {
|
|
255014
|
-
const outputDirectory = target.site?.outputDirectory;
|
|
255015
|
-
if (!outputDirectory) {
|
|
255016
|
-
return { kind: "none" };
|
|
255017
|
-
}
|
|
255018
|
-
const outputDir = resolve3(target.root, outputDirectory);
|
|
255019
|
-
return staticDeployments ? { kind: "static-deployment", outputDir } : { kind: "static", outputDir };
|
|
255020
|
-
}
|
|
255021
|
-
function detectAppDeployKind(target, options = {}) {
|
|
255022
|
-
return planAppDeploy(target, options.staticDeployments ?? false).kind;
|
|
255023
|
-
}
|
|
255024
|
-
async function deployAppSite(target, options = {}) {
|
|
255025
|
-
const plan = planAppDeploy(target, options.staticDeployments ?? false);
|
|
255026
|
-
switch (plan.kind) {
|
|
255027
|
-
case "static-deployment": {
|
|
255028
|
-
const { deploymentId, gitHash } = await deployStaticSite({
|
|
255029
|
-
outputDir: plan.outputDir,
|
|
255030
|
-
projectRoot: target.root,
|
|
255031
|
-
gitHash: options.gitHash,
|
|
255032
|
-
progress: options.progress
|
|
255033
|
-
});
|
|
255034
|
-
return { kind: "static-deployment", deploymentId, gitHash };
|
|
255035
|
-
}
|
|
255036
|
-
case "static": {
|
|
255037
|
-
const { appUrl } = await deploySite(plan.outputDir);
|
|
255038
|
-
return { kind: "static", appUrl };
|
|
255039
|
-
}
|
|
255040
|
-
case "none":
|
|
255041
|
-
return { kind: "none" };
|
|
255042
|
-
}
|
|
255043
|
-
}
|
|
255044
|
-
// src/core/site/gate.ts
|
|
255045
|
-
var STATIC_DEPLOYMENTS_ENV = "BASE44_STATIC_DEPLOYMENTS";
|
|
255046
|
-
function staticDeploymentsEnabled(env2 = process.env) {
|
|
255047
|
-
const value = env2[STATIC_DEPLOYMENTS_ENV];
|
|
255048
|
-
return value === "1" || value === "true";
|
|
255049
|
-
}
|
|
255050
|
-
// src/core/project/deploy.ts
|
|
255051
|
-
function hasResourcesToDeploy(projectData) {
|
|
255052
|
-
const {
|
|
255053
|
-
project,
|
|
255054
|
-
entities,
|
|
255055
|
-
functions,
|
|
255056
|
-
agents,
|
|
255057
|
-
agentSkills,
|
|
255058
|
-
connectors,
|
|
255059
|
-
authConfig
|
|
255060
|
-
} = projectData;
|
|
255061
|
-
const hasSite = Boolean(project.site?.outputDirectory || project.site?.buildCommand);
|
|
255062
|
-
const hasEntities = entities.length > 0;
|
|
255063
|
-
const hasFunctions = functions.length > 0;
|
|
255064
|
-
const hasAgents = agents.length > 0;
|
|
255065
|
-
const hasAgentSkills = agentSkills.length > 0;
|
|
255066
|
-
const hasConnectors = connectors.length > 0;
|
|
255067
|
-
const hasAuthConfig = authConfig.length > 0;
|
|
255068
|
-
const hasVisibility = Boolean(project.visibility);
|
|
255069
|
-
return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
|
|
255070
|
-
}
|
|
255071
|
-
async function deployAll(projectData, options) {
|
|
255072
|
-
const {
|
|
255073
|
-
project,
|
|
255074
|
-
entities,
|
|
255075
|
-
functions,
|
|
255076
|
-
agents,
|
|
255077
|
-
agentSkills,
|
|
255078
|
-
connectors,
|
|
255079
|
-
authConfig
|
|
255080
|
-
} = projectData;
|
|
255081
|
-
await setAppVisibility(project.visibility);
|
|
255082
|
-
if (project.visibility) {
|
|
255083
|
-
options?.onVisibilitySet?.(project.visibility);
|
|
255084
|
-
}
|
|
255085
|
-
await entityResource.push(entities);
|
|
255086
|
-
await deployFunctionsSequentially(functions, {
|
|
255087
|
-
onStart: options?.onFunctionStart,
|
|
255088
|
-
onResult: options?.onFunctionResult
|
|
255089
|
-
});
|
|
255090
|
-
await agentSkillResource.push(agentSkills);
|
|
255091
|
-
await agentResource.push(agents);
|
|
255092
|
-
await authConfigResource.push(authConfig);
|
|
255093
|
-
const skipConnectorSync = connectors.length === 0 && hasWorkspaceApiKeyAuth();
|
|
255094
|
-
const connectorResults = skipConnectorSync ? [] : (await pushConnectors(connectors)).results;
|
|
255095
|
-
if ((options?.site ?? true) && project.site?.outputDirectory) {
|
|
255096
|
-
const outputDir = resolve4(project.root, project.site.outputDirectory);
|
|
255097
|
-
const { appUrl } = await deploySite(outputDir);
|
|
255098
|
-
return { appUrl, connectorResults };
|
|
255099
|
-
}
|
|
255100
|
-
return { connectorResults };
|
|
255101
|
-
}
|
|
255102
|
-
// src/core/clients/base44-client.ts
|
|
255103
|
-
var retriedRequests = new WeakSet;
|
|
255104
|
-
async function captureRequestBody(request, options) {
|
|
255105
|
-
if (request.body == null) {
|
|
255106
|
-
return;
|
|
255107
|
-
}
|
|
255108
|
-
try {
|
|
255109
|
-
const cloned = request.clone();
|
|
255110
|
-
const text = await cloned.text();
|
|
255111
|
-
options.context.__requestBody = text;
|
|
255112
|
-
} catch {}
|
|
255113
|
-
}
|
|
255114
|
-
async function handleUnauthorized(request, _options, response) {
|
|
255115
|
-
if (response.status !== 401) {
|
|
255116
|
-
return;
|
|
255117
|
-
}
|
|
255118
|
-
if (hasWorkspaceApiKeyAuth()) {
|
|
255119
|
-
return;
|
|
255120
|
-
}
|
|
255121
|
-
if (retriedRequests.has(request)) {
|
|
255122
|
-
return;
|
|
255123
|
-
}
|
|
255124
|
-
const newAccessToken = await refreshAndSaveTokens();
|
|
255125
|
-
if (!newAccessToken) {
|
|
255126
|
-
return;
|
|
255127
|
-
}
|
|
255128
|
-
retriedRequests.add(request);
|
|
255129
|
-
const requestId = request.headers.get("X-Request-ID");
|
|
255130
|
-
return distribution_default(request.clone(), {
|
|
255131
|
-
headers: {
|
|
255132
|
-
...requestId && { "X-Request-ID": requestId },
|
|
255133
|
-
Authorization: `Bearer ${newAccessToken}`
|
|
255134
|
-
}
|
|
255135
|
-
});
|
|
255136
|
-
}
|
|
255137
|
-
var base44Client = distribution_default.create({
|
|
255138
|
-
prefixUrl: getBase44ApiUrl(),
|
|
255139
|
-
headers: {
|
|
255140
|
-
"User-Agent": "Base44 CLI"
|
|
255141
|
-
},
|
|
255142
|
-
hooks: {
|
|
255143
|
-
beforeRequest: [
|
|
255144
|
-
(request) => {
|
|
255145
|
-
request.headers.set("X-Request-ID", randomUUID2());
|
|
255146
|
-
},
|
|
255147
|
-
captureRequestBody,
|
|
255148
|
-
async (request) => {
|
|
255149
|
-
const workspaceApiKey = getWorkspaceApiKeyFromEnv();
|
|
255150
|
-
if (workspaceApiKey && isWorkspaceApiKey(workspaceApiKey)) {
|
|
255151
|
-
request.headers.set("api_key", workspaceApiKey);
|
|
255152
|
-
return;
|
|
255153
|
-
}
|
|
255154
|
-
try {
|
|
255155
|
-
const auth = await readAuth();
|
|
255156
|
-
if (isTokenExpired(auth)) {
|
|
255157
|
-
const newAccessToken = await refreshAndSaveTokens();
|
|
255158
|
-
if (newAccessToken) {
|
|
255159
|
-
request.headers.set("Authorization", `Bearer ${newAccessToken}`);
|
|
255160
|
-
return;
|
|
255161
|
-
}
|
|
255162
|
-
}
|
|
255163
|
-
request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
|
|
255164
|
-
} catch {}
|
|
255165
|
-
}
|
|
255166
|
-
],
|
|
255167
|
-
afterResponse: [handleUnauthorized]
|
|
255168
|
-
}
|
|
255169
|
-
});
|
|
255170
|
-
function getAppClient() {
|
|
255171
|
-
const { id } = getAppContext();
|
|
255172
|
-
return base44Client.extend({
|
|
255173
|
-
prefixUrl: new URL(`/api/apps/${id}/`, getBase44ApiUrl()).href
|
|
255174
|
-
});
|
|
255175
|
-
}
|
|
255176
|
-
function getSandboxClient(appId) {
|
|
255177
|
-
return base44Client.extend({
|
|
255178
|
-
prefixUrl: new URL(`/api/apps/${appId}/sandbox-bridge/`, getBase44ApiUrl()).href
|
|
255179
|
-
});
|
|
255180
|
-
}
|
|
255181
|
-
// src/core/clients/oauth-client.ts
|
|
255182
|
-
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
255183
|
-
var oauthClient = distribution_default.create({
|
|
255184
|
-
prefixUrl: getBase44ApiUrl(),
|
|
255185
|
-
headers: {
|
|
255186
|
-
"User-Agent": "Base44 CLI"
|
|
255187
|
-
},
|
|
255188
|
-
hooks: {
|
|
255189
|
-
beforeRequest: [
|
|
255190
|
-
(request) => {
|
|
255191
|
-
request.headers.set("X-Request-ID", randomUUID3());
|
|
255192
|
-
}
|
|
255193
|
-
]
|
|
255194
|
-
}
|
|
255195
|
-
});
|
|
255196
|
-
// src/core/auth/api.ts
|
|
255197
|
-
async function generateDeviceCode() {
|
|
255198
|
-
const response = await oauthClient.post("oauth/device/code", {
|
|
255199
|
-
json: {
|
|
255200
|
-
client_id: AUTH_CLIENT_ID,
|
|
255201
|
-
scope: "apps:read apps:write sandbox:write"
|
|
255202
|
-
},
|
|
255203
|
-
throwHttpErrors: false
|
|
255204
|
-
});
|
|
255205
|
-
if (!response.ok) {
|
|
255206
|
-
throw new ApiError(`Failed to generate device code: ${response.status} ${response.statusText}`, { statusCode: response.status });
|
|
255207
|
-
}
|
|
255208
|
-
const result = DeviceCodeResponseSchema.safeParse(await response.json());
|
|
255209
|
-
if (!result.success) {
|
|
255210
|
-
throw new SchemaValidationError("Invalid device code response from server", result.error);
|
|
255211
|
-
}
|
|
255212
|
-
return result.data;
|
|
255213
|
-
}
|
|
255214
|
-
async function getTokenFromDeviceCode(deviceCode) {
|
|
255215
|
-
const searchParams = new URLSearchParams;
|
|
255216
|
-
searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
|
|
255217
|
-
searchParams.set("device_code", deviceCode);
|
|
255218
|
-
searchParams.set("client_id", AUTH_CLIENT_ID);
|
|
255219
|
-
const response = await oauthClient.post("oauth/token", {
|
|
255220
|
-
body: searchParams.toString(),
|
|
255221
|
-
headers: {
|
|
255222
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
255223
|
-
},
|
|
255224
|
-
throwHttpErrors: false
|
|
255225
|
-
});
|
|
255226
|
-
const json2 = await response.json();
|
|
255227
|
-
if (!response.ok) {
|
|
255228
|
-
const errorResult = OAuthErrorSchema.safeParse(json2);
|
|
255229
|
-
if (!errorResult.success) {
|
|
255230
|
-
throw new SchemaValidationError("Token request failed", errorResult.error);
|
|
255231
|
-
}
|
|
255232
|
-
const { error: error48, error_description } = errorResult.data;
|
|
255233
|
-
if (error48 === "authorization_pending" || error48 === "slow_down") {
|
|
255234
|
-
return null;
|
|
255235
|
-
}
|
|
255236
|
-
throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
|
|
255237
|
-
statusCode: response.status
|
|
255238
|
-
});
|
|
255239
|
-
}
|
|
255240
|
-
const result = TokenResponseSchema.safeParse(json2);
|
|
255241
|
-
if (!result.success) {
|
|
255242
|
-
throw new SchemaValidationError("Invalid token response from server", result.error);
|
|
255243
|
-
}
|
|
255244
|
-
return result.data;
|
|
255245
|
-
}
|
|
255246
|
-
async function renewAccessToken(refreshToken) {
|
|
255247
|
-
const searchParams = new URLSearchParams;
|
|
255248
|
-
searchParams.set("grant_type", "refresh_token");
|
|
255249
|
-
searchParams.set("refresh_token", refreshToken);
|
|
255250
|
-
searchParams.set("client_id", AUTH_CLIENT_ID);
|
|
255251
|
-
const response = await oauthClient.post("oauth/token", {
|
|
255252
|
-
body: searchParams.toString(),
|
|
255253
|
-
headers: {
|
|
255254
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
255255
|
-
},
|
|
255256
|
-
throwHttpErrors: false
|
|
255257
|
-
});
|
|
255258
|
-
const json2 = await response.json();
|
|
255259
|
-
if (!response.ok) {
|
|
255260
|
-
const errorResult = OAuthErrorSchema.safeParse(json2);
|
|
255261
|
-
if (!errorResult.success) {
|
|
255262
|
-
throw new ApiError(`Token refresh failed: ${response.statusText}`, {
|
|
255263
|
-
statusCode: response.status
|
|
255264
|
-
});
|
|
255265
|
-
}
|
|
255266
|
-
const { error: error48, error_description } = errorResult.data;
|
|
255267
|
-
throw new ApiError(error_description ?? `OAuth error: ${error48}`, {
|
|
255268
|
-
statusCode: response.status
|
|
255269
|
-
});
|
|
255270
|
-
}
|
|
255271
|
-
const result = TokenResponseSchema.safeParse(json2);
|
|
255272
|
-
if (!result.success) {
|
|
255273
|
-
throw new SchemaValidationError("Invalid token response from server", result.error);
|
|
255274
|
-
}
|
|
255275
|
-
return result.data;
|
|
255276
|
-
}
|
|
255277
|
-
async function getUserInfo(accessToken) {
|
|
255278
|
-
const response = await oauthClient.get("oauth/userinfo", {
|
|
255279
|
-
headers: { Authorization: `Bearer ${accessToken}` }
|
|
255280
|
-
});
|
|
255281
|
-
if (!response.ok) {
|
|
255282
|
-
throw new ApiError(`Failed to fetch user info: ${response.status}`, {
|
|
255283
|
-
statusCode: response.status
|
|
255284
|
-
});
|
|
255285
|
-
}
|
|
255286
|
-
const result = UserInfoSchema.safeParse(await response.json());
|
|
255287
|
-
if (!result.success) {
|
|
255288
|
-
throw new SchemaValidationError("Invalid UserInfo response from server", result.error);
|
|
255289
|
-
}
|
|
255290
|
-
return result.data;
|
|
255291
|
-
}
|
|
255292
|
-
// src/cli/commands/auth/login-flow.ts
|
|
255293
|
-
async function generateAndDisplayDeviceCode(log, runTask) {
|
|
255294
|
-
const deviceCodeResponse = await runTask("Generating device code...", async () => {
|
|
255295
|
-
return await generateDeviceCode();
|
|
255296
|
-
}, {
|
|
255297
|
-
successMessage: "Device code generated",
|
|
255298
|
-
errorMessage: "Failed to generate device code"
|
|
255299
|
-
});
|
|
255300
|
-
log.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}` + `
|
|
255301
|
-
Please confirm this code at: ${deviceCodeResponse.verificationUri}`);
|
|
255302
|
-
return deviceCodeResponse;
|
|
255303
|
-
}
|
|
255304
|
-
async function waitForAuthentication(deviceCode, expiresIn, interval, runTask) {
|
|
255305
|
-
let tokenResponse;
|
|
255306
|
-
try {
|
|
255307
|
-
await runTask("Waiting for authentication...", async () => {
|
|
255308
|
-
await pWaitFor(async () => {
|
|
255309
|
-
const result = await getTokenFromDeviceCode(deviceCode);
|
|
255310
|
-
if (result !== null) {
|
|
255311
|
-
tokenResponse = result;
|
|
255312
|
-
return true;
|
|
255313
|
-
}
|
|
255314
|
-
return false;
|
|
255315
|
-
}, {
|
|
255316
|
-
interval: interval * 1000,
|
|
255317
|
-
timeout: expiresIn * 1000
|
|
255318
|
-
});
|
|
255319
|
-
}, {
|
|
255320
|
-
successMessage: "Authentication completed!",
|
|
255321
|
-
errorMessage: "Authentication failed"
|
|
255322
|
-
});
|
|
255323
|
-
} catch (error48) {
|
|
255324
|
-
if (error48 instanceof Error && error48.message.includes("timed out")) {
|
|
255325
|
-
throw new AuthExpiredError("Authentication timed out. Please try again.");
|
|
255326
|
-
}
|
|
255327
|
-
throw error48;
|
|
255328
|
-
}
|
|
255329
|
-
if (tokenResponse === undefined) {
|
|
255330
|
-
throw new InternalError("Failed to retrieve authentication token.");
|
|
255331
|
-
}
|
|
255332
|
-
return tokenResponse;
|
|
255333
|
-
}
|
|
255334
|
-
async function saveAuthData(response, userInfo) {
|
|
255335
|
-
const expiresAt = Date.now() + response.expiresIn * 1000;
|
|
255336
|
-
await writeAuth({
|
|
255337
|
-
accessToken: response.accessToken,
|
|
255338
|
-
refreshToken: response.refreshToken,
|
|
255339
|
-
expiresAt,
|
|
255340
|
-
email: userInfo.email,
|
|
255341
|
-
name: userInfo.name
|
|
255342
|
-
});
|
|
255343
|
-
}
|
|
255344
|
-
async function login({
|
|
255345
|
-
log,
|
|
255346
|
-
runTask
|
|
255347
|
-
}) {
|
|
255348
|
-
const deviceCodeResponse = await generateAndDisplayDeviceCode(log, runTask);
|
|
255349
|
-
const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval, runTask);
|
|
255350
|
-
const userInfo = await getUserInfo(token.accessToken);
|
|
255351
|
-
await saveAuthData(token, userInfo);
|
|
255352
|
-
return {
|
|
255353
|
-
outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}`
|
|
255354
|
-
};
|
|
255355
|
-
}
|
|
255356
|
-
|
|
255357
|
-
// src/cli/utils/command/middleware.ts
|
|
255358
|
-
async function ensureAuth(ctx) {
|
|
255359
|
-
if (hasWorkspaceApiKeyAuth()) {
|
|
255360
|
-
ctx.errorReporter.setContext({
|
|
255361
|
-
user: { email: "workspace-api-key", name: "Workspace API key" }
|
|
255362
|
-
});
|
|
255363
|
-
return;
|
|
255364
|
-
}
|
|
255365
|
-
await seedAuthFromEnv();
|
|
255366
|
-
const loggedIn = await isLoggedIn();
|
|
255367
|
-
if (!loggedIn) {
|
|
255368
|
-
ctx.log.info("You need to login first to continue.");
|
|
255369
|
-
await login(ctx);
|
|
255370
|
-
}
|
|
255371
|
-
try {
|
|
255372
|
-
const userInfo = await readAuth();
|
|
255373
|
-
ctx.errorReporter.setContext({
|
|
255374
|
-
user: { email: userInfo.email, name: userInfo.name }
|
|
255375
|
-
});
|
|
255376
|
-
} catch {}
|
|
255377
|
-
}
|
|
255378
|
-
async function ensureAppContext(ctx, options = {}) {
|
|
255379
|
-
const appContext = await initAppContext(options);
|
|
255380
|
-
ctx.app = appContext;
|
|
255381
|
-
ctx.errorReporter.setContext({ appId: appContext.id });
|
|
255382
|
-
}
|
|
255383
|
-
|
|
255384
255431
|
// src/cli/utils/version-check.ts
|
|
255385
255432
|
async function checkForUpgrade() {
|
|
255386
255433
|
const testLatestVersion = getTestOverrides()?.latestVersion;
|
|
@@ -255773,6 +255820,11 @@ function verifyDenoInstalled(context) {
|
|
|
255773
255820
|
});
|
|
255774
255821
|
}
|
|
255775
255822
|
}
|
|
255823
|
+
// src/core/utils/git.ts
|
|
255824
|
+
var GIT_HASH_PATTERN = /^[a-fA-F0-9]{7,64}$/;
|
|
255825
|
+
function isGitCommitHash(value) {
|
|
255826
|
+
return GIT_HASH_PATTERN.test(value);
|
|
255827
|
+
}
|
|
255776
255828
|
// src/core/workspace/schema.ts
|
|
255777
255829
|
var WorkspaceSchema = exports_external.object({
|
|
255778
255830
|
id: exports_external.string(),
|
|
@@ -256076,7 +256128,7 @@ function getAuthPushCommand() {
|
|
|
256076
256128
|
}
|
|
256077
256129
|
|
|
256078
256130
|
// src/cli/commands/auth/social-login.ts
|
|
256079
|
-
import { dirname as dirname14, join as join21, resolve as
|
|
256131
|
+
import { dirname as dirname14, join as join21, resolve as resolve4 } from "node:path";
|
|
256080
256132
|
var PROVIDER_LABELS = {
|
|
256081
256133
|
google: "Google",
|
|
256082
256134
|
microsoft: "Microsoft",
|
|
@@ -256116,7 +256168,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask: runTask2 }, p
|
|
|
256116
256168
|
let clientSecret;
|
|
256117
256169
|
if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
|
|
256118
256170
|
if (options.envFile) {
|
|
256119
|
-
const secrets = await parseEnvFile(
|
|
256171
|
+
const secrets = await parseEnvFile(resolve4(options.envFile));
|
|
256120
256172
|
const value = secrets[oauthCli.envVar];
|
|
256121
256173
|
if (!value) {
|
|
256122
256174
|
throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
|
|
@@ -256172,7 +256224,7 @@ function getSocialLoginCommand() {
|
|
|
256172
256224
|
}
|
|
256173
256225
|
|
|
256174
256226
|
// src/cli/commands/auth/sso.ts
|
|
256175
|
-
import { dirname as dirname15, join as join22, resolve as
|
|
256227
|
+
import { dirname as dirname15, join as join22, resolve as resolve5 } from "node:path";
|
|
256176
256228
|
var SSOConfigFileSchema = exports_external.object({
|
|
256177
256229
|
provider: exports_external.enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
256178
256230
|
clientId: exports_external.string(),
|
|
@@ -256188,7 +256240,7 @@ var SSOConfigFileSchema = exports_external.object({
|
|
|
256188
256240
|
ssoName: exports_external.string().optional()
|
|
256189
256241
|
});
|
|
256190
256242
|
async function loadSSOConfigFile(filePath) {
|
|
256191
|
-
const resolved =
|
|
256243
|
+
const resolved = resolve5(filePath);
|
|
256192
256244
|
const raw2 = await readJsonFile(resolved);
|
|
256193
256245
|
const result = SSOConfigFileSchema.safeParse(raw2);
|
|
256194
256246
|
if (!result.success) {
|
|
@@ -256276,7 +256328,7 @@ async function ssoEnableAction({ isNonInteractive, runTask: runTask2 }, options)
|
|
|
256276
256328
|
}
|
|
256277
256329
|
let clientSecret;
|
|
256278
256330
|
if (merged.envFile && !merged.clientSecret) {
|
|
256279
|
-
const secrets2 = await parseEnvFile(
|
|
256331
|
+
const secrets2 = await parseEnvFile(resolve5(merged.envFile));
|
|
256280
256332
|
const value = secrets2.sso_client_secret;
|
|
256281
256333
|
if (!value) {
|
|
256282
256334
|
throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
|
|
@@ -256914,19 +256966,19 @@ var baseOpen = async (options) => {
|
|
|
256914
256966
|
}
|
|
256915
256967
|
const subprocess = childProcess3.spawn(command2, cliArguments, childProcessOptions);
|
|
256916
256968
|
if (options.wait) {
|
|
256917
|
-
return new Promise((
|
|
256969
|
+
return new Promise((resolve6, reject) => {
|
|
256918
256970
|
subprocess.once("error", reject);
|
|
256919
256971
|
subprocess.once("close", (exitCode) => {
|
|
256920
256972
|
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
256921
256973
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
256922
256974
|
return;
|
|
256923
256975
|
}
|
|
256924
|
-
|
|
256976
|
+
resolve6(subprocess);
|
|
256925
256977
|
});
|
|
256926
256978
|
});
|
|
256927
256979
|
}
|
|
256928
256980
|
if (isFallbackAttempt) {
|
|
256929
|
-
return new Promise((
|
|
256981
|
+
return new Promise((resolve6, reject) => {
|
|
256930
256982
|
subprocess.once("error", reject);
|
|
256931
256983
|
subprocess.once("spawn", () => {
|
|
256932
256984
|
subprocess.once("close", (exitCode) => {
|
|
@@ -256936,17 +256988,17 @@ var baseOpen = async (options) => {
|
|
|
256936
256988
|
return;
|
|
256937
256989
|
}
|
|
256938
256990
|
subprocess.unref();
|
|
256939
|
-
|
|
256991
|
+
resolve6(subprocess);
|
|
256940
256992
|
});
|
|
256941
256993
|
});
|
|
256942
256994
|
});
|
|
256943
256995
|
}
|
|
256944
256996
|
subprocess.unref();
|
|
256945
|
-
return new Promise((
|
|
256997
|
+
return new Promise((resolve6, reject) => {
|
|
256946
256998
|
subprocess.once("error", reject);
|
|
256947
256999
|
subprocess.once("spawn", () => {
|
|
256948
257000
|
subprocess.off("error", reject);
|
|
256949
|
-
|
|
257001
|
+
resolve6(subprocess);
|
|
256950
257002
|
});
|
|
256951
257003
|
});
|
|
256952
257004
|
};
|
|
@@ -257209,10 +257261,10 @@ function getConnectorsListAvailableCommand() {
|
|
|
257209
257261
|
}
|
|
257210
257262
|
|
|
257211
257263
|
// src/cli/commands/connectors/pull.ts
|
|
257212
|
-
import { dirname as dirname16, join as join23, resolve as
|
|
257264
|
+
import { dirname as dirname16, join as join23, resolve as resolve6 } from "node:path";
|
|
257213
257265
|
async function resolveConnectorsDir(options) {
|
|
257214
257266
|
if (!getAppContext().projectRoot) {
|
|
257215
|
-
return
|
|
257267
|
+
return resolve6(options.dir ?? "connectors");
|
|
257216
257268
|
}
|
|
257217
257269
|
const { project: project2 } = await readProjectConfig();
|
|
257218
257270
|
return join23(dirname16(project2.configPath), project2.connectorsDir);
|
|
@@ -257256,10 +257308,10 @@ function getConnectorsPullCommand() {
|
|
|
257256
257308
|
}
|
|
257257
257309
|
|
|
257258
257310
|
// src/cli/commands/connectors/push.ts
|
|
257259
|
-
import { resolve as
|
|
257311
|
+
import { resolve as resolve7 } from "node:path";
|
|
257260
257312
|
async function readConnectorsToPush(options) {
|
|
257261
257313
|
if (!getAppContext().projectRoot) {
|
|
257262
|
-
return readAllConnectors(
|
|
257314
|
+
return readAllConnectors(resolve7(options.dir ?? "connectors"));
|
|
257263
257315
|
}
|
|
257264
257316
|
const { connectors } = await readProjectConfig();
|
|
257265
257317
|
return connectors;
|
|
@@ -257760,7 +257812,7 @@ function getBuildCommand() {
|
|
|
257760
257812
|
}
|
|
257761
257813
|
|
|
257762
257814
|
// src/cli/commands/project/create.ts
|
|
257763
|
-
import { basename as basename5, resolve as
|
|
257815
|
+
import { basename as basename5, resolve as resolve8 } from "node:path";
|
|
257764
257816
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
257765
257817
|
|
|
257766
257818
|
// src/cli/commands/project/scaffold-shared.ts
|
|
@@ -257952,7 +258004,7 @@ async function createInteractive(options, ctx) {
|
|
|
257952
258004
|
}, ctx);
|
|
257953
258005
|
}
|
|
257954
258006
|
async function createNonInteractive(options, ctx) {
|
|
257955
|
-
ctx.log.info(`Creating a new project at ${
|
|
258007
|
+
ctx.log.info(`Creating a new project at ${resolve8(options.path)}`);
|
|
257956
258008
|
const template2 = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
|
|
257957
258009
|
return await executeCreate({
|
|
257958
258010
|
template: template2,
|
|
@@ -257976,7 +258028,7 @@ async function executeCreate({
|
|
|
257976
258028
|
}, ctx) {
|
|
257977
258029
|
const { log, runTask: runTask2 } = ctx;
|
|
257978
258030
|
const name2 = rawName.trim();
|
|
257979
|
-
const resolvedPath =
|
|
258031
|
+
const resolvedPath = resolve8(projectPath);
|
|
257980
258032
|
const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
|
|
257981
258033
|
const { projectId } = await runTask2("Setting up your project...", async () => {
|
|
257982
258034
|
return await createProjectFiles({
|
|
@@ -258026,48 +258078,6 @@ Examples:
|
|
|
258026
258078
|
$ base44 create my-app --workspace 507f1f77bcf86cd799439011 Creates a base44 project in the given workspace`).hook("preAction", validateCreateOptions).action(createAction);
|
|
258027
258079
|
}
|
|
258028
258080
|
|
|
258029
|
-
// src/cli/commands/site/run-app-deploy.ts
|
|
258030
|
-
var TASK_LABELS = {
|
|
258031
|
-
"static-deployment": {
|
|
258032
|
-
start: "Deploying site...",
|
|
258033
|
-
success: "Site deployed",
|
|
258034
|
-
error: "Site deploy failed"
|
|
258035
|
-
},
|
|
258036
|
-
static: {
|
|
258037
|
-
start: "Creating archive and deploying site...",
|
|
258038
|
-
success: "Site deployed successfully",
|
|
258039
|
-
error: "Deployment failed"
|
|
258040
|
-
}
|
|
258041
|
-
};
|
|
258042
|
-
async function runAppSiteDeploy({ runTask: runTask2, log, staticDeployments }, target, options = {}) {
|
|
258043
|
-
const kind = detectAppDeployKind(target, { staticDeployments });
|
|
258044
|
-
if (kind === "none")
|
|
258045
|
-
return { kind: "none" };
|
|
258046
|
-
const labels = TASK_LABELS[kind];
|
|
258047
|
-
const progressLines = [];
|
|
258048
|
-
const result = await runTask2(labels.start, async (updateMessage) => await deployAppSite(target, {
|
|
258049
|
-
staticDeployments,
|
|
258050
|
-
gitHash: options.gitHash,
|
|
258051
|
-
progress: {
|
|
258052
|
-
onAssets: ({ totalAssets, newAssets }) => {
|
|
258053
|
-
const line = `Found ${totalAssets} static assets (${newAssets} new)`;
|
|
258054
|
-
progressLines.push(line);
|
|
258055
|
-
updateMessage(line);
|
|
258056
|
-
},
|
|
258057
|
-
onAssetUpload: ({ uploadedFiles, totalFiles }) => {
|
|
258058
|
-
updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
|
|
258059
|
-
}
|
|
258060
|
-
}
|
|
258061
|
-
}), {
|
|
258062
|
-
successMessage: labels.success,
|
|
258063
|
-
errorMessage: labels.error
|
|
258064
|
-
});
|
|
258065
|
-
for (const line of progressLines) {
|
|
258066
|
-
log.message(theme.styles.dim(line));
|
|
258067
|
-
}
|
|
258068
|
-
return result;
|
|
258069
|
-
}
|
|
258070
|
-
|
|
258071
258081
|
// src/cli/commands/project/deploy.ts
|
|
258072
258082
|
async function deployAction(ctx, options = {}) {
|
|
258073
258083
|
const { isNonInteractive, log } = ctx;
|
|
@@ -258075,12 +258085,12 @@ async function deployAction(ctx, options = {}) {
|
|
|
258075
258085
|
throw new InvalidInputError("--yes is required in non-interactive mode");
|
|
258076
258086
|
}
|
|
258077
258087
|
const projectData = await readProjectConfig(options.projectRoot);
|
|
258078
|
-
const { project: project2, entities, functions, agents, connectors, authConfig } = projectData;
|
|
258079
258088
|
if (!hasResourcesToDeploy(projectData)) {
|
|
258080
258089
|
return {
|
|
258081
258090
|
outroMessage: "No resources found to deploy"
|
|
258082
258091
|
};
|
|
258083
258092
|
}
|
|
258093
|
+
const { project: project2, entities, functions, agents, connectors, authConfig } = projectData;
|
|
258084
258094
|
const summaryLines = [];
|
|
258085
258095
|
if (entities.length > 0) {
|
|
258086
258096
|
summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
|
|
@@ -258122,7 +258132,6 @@ ${summaryLines.join(`
|
|
|
258122
258132
|
let functionCompleted = 0;
|
|
258123
258133
|
const functionTotal = functions.length;
|
|
258124
258134
|
const result = await deployAll(projectData, {
|
|
258125
|
-
site: false,
|
|
258126
258135
|
onVisibilitySet: (level) => {
|
|
258127
258136
|
log.success(`App visibility set to ${level}`);
|
|
258128
258137
|
},
|
|
@@ -258135,7 +258144,6 @@ ${summaryLines.join(`
|
|
|
258135
258144
|
formatDeployResult(r, log);
|
|
258136
258145
|
}
|
|
258137
258146
|
});
|
|
258138
|
-
const siteResult = await runAppSiteDeploy(ctx, project2);
|
|
258139
258147
|
const connectorResults = result.connectorResults ?? [];
|
|
258140
258148
|
await handleOAuthConnectors(connectorResults, isNonInteractive, options, log);
|
|
258141
258149
|
const stripeResult = connectorResults.find((r) => r.type === "stripe");
|
|
@@ -258143,24 +258151,10 @@ ${summaryLines.join(`
|
|
|
258143
258151
|
printStripeResult(stripeResult, log);
|
|
258144
258152
|
}
|
|
258145
258153
|
log.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
|
|
258146
|
-
if (
|
|
258147
|
-
log.message(`${theme.styles.header("App URL")}: ${theme.colors.links(
|
|
258154
|
+
if (result.appUrl) {
|
|
258155
|
+
log.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
|
|
258148
258156
|
}
|
|
258149
|
-
|
|
258150
|
-
if (deployment) {
|
|
258151
|
-
printDeploymentSummary(deployment, log);
|
|
258152
|
-
}
|
|
258153
|
-
return {
|
|
258154
|
-
outroMessage: "App deployed successfully",
|
|
258155
|
-
stdout: ctx.jsonMode && deployment ? `${JSON.stringify({
|
|
258156
|
-
deploymentId: deployment.deploymentId,
|
|
258157
|
-
gitHash: deployment.gitHash
|
|
258158
|
-
}, null, 2)}
|
|
258159
|
-
` : undefined
|
|
258160
|
-
};
|
|
258161
|
-
}
|
|
258162
|
-
function printDeploymentSummary(deployment, log) {
|
|
258163
|
-
log.message(`${theme.styles.header("Deployment")}: ${deployment.deploymentId} ${theme.styles.dim(`(commit ${deployment.gitHash.slice(0, 12)})`)}`);
|
|
258157
|
+
return { outroMessage: "App deployed successfully" };
|
|
258164
258158
|
}
|
|
258165
258159
|
function getDeployCommand2() {
|
|
258166
258160
|
return new Base44Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").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)").action(deployAction);
|
|
@@ -258441,7 +258435,7 @@ async function followLogs(functionNames, options, availableFunctionNames, jsonMo
|
|
|
258441
258435
|
for (const entry of fresh)
|
|
258442
258436
|
writeFollowLine(entry, jsonMode);
|
|
258443
258437
|
first = false;
|
|
258444
|
-
await new Promise((
|
|
258438
|
+
await new Promise((resolve9) => setTimeout(resolve9, 2000));
|
|
258445
258439
|
}
|
|
258446
258440
|
}
|
|
258447
258441
|
function formatLogs(entries, env3) {
|
|
@@ -258555,7 +258549,7 @@ function getLogsCommand() {
|
|
|
258555
258549
|
}
|
|
258556
258550
|
|
|
258557
258551
|
// src/cli/commands/project/scaffold.ts
|
|
258558
|
-
import { basename as basename6, resolve as
|
|
258552
|
+
import { basename as basename6, resolve as resolve9 } from "node:path";
|
|
258559
258553
|
function resolveAppId(options) {
|
|
258560
258554
|
const appId = options.appId;
|
|
258561
258555
|
if (!appId) {
|
|
@@ -258571,7 +258565,7 @@ function resolveAppId(options) {
|
|
|
258571
258565
|
async function scaffoldAction(ctx, name2, options, command2) {
|
|
258572
258566
|
const { log, runTask: runTask2 } = ctx;
|
|
258573
258567
|
const appId = resolveAppId(command2.optsWithGlobals());
|
|
258574
|
-
const resolvedPath =
|
|
258568
|
+
const resolvedPath = resolve9("./");
|
|
258575
258569
|
const projectName = (name2 ?? basename6(resolvedPath)).trim();
|
|
258576
258570
|
const template2 = await getTemplateById("backend-only");
|
|
258577
258571
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
@@ -258968,7 +258962,7 @@ function getSecretsListCommand() {
|
|
|
258968
258962
|
}
|
|
258969
258963
|
|
|
258970
258964
|
// src/cli/commands/secrets/set.ts
|
|
258971
|
-
import { resolve as
|
|
258965
|
+
import { resolve as resolve10 } from "node:path";
|
|
258972
258966
|
function parseEntries(entries) {
|
|
258973
258967
|
const secrets = {};
|
|
258974
258968
|
for (const entry of entries) {
|
|
@@ -258999,7 +258993,7 @@ async function setSecretsAction({ log, runTask: runTask2 }, entries, options) {
|
|
|
258999
258993
|
validateInput(entries, options);
|
|
259000
258994
|
let secrets;
|
|
259001
258995
|
if (options.envFile) {
|
|
259002
|
-
secrets = await parseEnvFile(
|
|
258996
|
+
secrets = await parseEnvFile(resolve10(options.envFile));
|
|
259003
258997
|
if (Object.keys(secrets).length === 0) {
|
|
259004
258998
|
throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
|
|
259005
258999
|
}
|
|
@@ -259028,6 +259022,7 @@ function getSecretsCommand() {
|
|
|
259028
259022
|
}
|
|
259029
259023
|
|
|
259030
259024
|
// src/cli/commands/site/deploy.ts
|
|
259025
|
+
import { resolve as resolve11 } from "node:path";
|
|
259031
259026
|
async function deployAction2(ctx, options) {
|
|
259032
259027
|
const { isNonInteractive } = ctx;
|
|
259033
259028
|
if (isNonInteractive && !options.yes) {
|
|
@@ -259053,28 +259048,67 @@ async function deployAction2(ctx, options) {
|
|
|
259053
259048
|
}
|
|
259054
259049
|
}
|
|
259055
259050
|
await maybeBuildBeforeDeploy(ctx, project2, options.build);
|
|
259056
|
-
const
|
|
259057
|
-
|
|
259058
|
-
|
|
259059
|
-
|
|
259060
|
-
|
|
259061
|
-
|
|
259062
|
-
|
|
259063
|
-
|
|
259064
|
-
|
|
259065
|
-
|
|
259066
|
-
|
|
259067
|
-
|
|
259051
|
+
const outputDir = resolve11(project2.root, outputDirectory);
|
|
259052
|
+
const { gitHash, concurrency } = options;
|
|
259053
|
+
return gitHash ? await deployToDeploymentsApi(ctx, outputDir, gitHash, concurrency) : await deployTarball(ctx, outputDir);
|
|
259054
|
+
}
|
|
259055
|
+
async function deployToDeploymentsApi({ runTask: runTask2, log, jsonMode }, outputDir, gitHash, concurrency) {
|
|
259056
|
+
const progressLines = [];
|
|
259057
|
+
const { deploymentId } = await runTask2("Deploying site...", async (updateMessage) => await deployStaticSite({
|
|
259058
|
+
outputDir,
|
|
259059
|
+
gitHash,
|
|
259060
|
+
concurrency,
|
|
259061
|
+
progress: {
|
|
259062
|
+
onAssets: ({ totalAssets, newAssets }) => {
|
|
259063
|
+
const line = `Found ${totalAssets} static assets (${newAssets} new)`;
|
|
259064
|
+
progressLines.push(line);
|
|
259065
|
+
updateMessage(line);
|
|
259066
|
+
},
|
|
259067
|
+
onAssetUpload: ({ uploadedFiles, totalFiles }) => {
|
|
259068
|
+
updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} assets`);
|
|
259069
|
+
}
|
|
259070
|
+
}
|
|
259071
|
+
}), { successMessage: "Site deployed", errorMessage: "Site deploy failed" });
|
|
259072
|
+
for (const line of progressLines) {
|
|
259073
|
+
log.message(theme.styles.dim(line));
|
|
259068
259074
|
}
|
|
259069
|
-
return {
|
|
259075
|
+
return {
|
|
259076
|
+
outroMessage: `Deployment ${deploymentId} (commit ${gitHash.slice(0, 12)})`,
|
|
259077
|
+
stdout: jsonMode ? `${JSON.stringify({ deploymentId, gitHash }, null, 2)}
|
|
259078
|
+
` : undefined
|
|
259079
|
+
};
|
|
259080
|
+
}
|
|
259081
|
+
async function deployTarball({ runTask: runTask2 }, outputDir) {
|
|
259082
|
+
const { appUrl } = await runTask2("Creating archive and deploying site...", async () => await deploySite(outputDir), {
|
|
259083
|
+
successMessage: "Site deployed successfully",
|
|
259084
|
+
errorMessage: "Deployment failed"
|
|
259085
|
+
});
|
|
259086
|
+
return { outroMessage: `Visit your site at: ${appUrl}` };
|
|
259070
259087
|
}
|
|
259071
|
-
function getSiteDeployCommand(
|
|
259088
|
+
function getSiteDeployCommand() {
|
|
259072
259089
|
const command2 = 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)");
|
|
259073
|
-
if (
|
|
259074
|
-
command2.addOption(new Option("--git-hash <hash>", "Commit the build came from
|
|
259090
|
+
if (staticDeploymentsEnabled()) {
|
|
259091
|
+
command2.addOption(new Option("--git-hash <hash>", "Commit the build came from — deploys through the deployments API").argParser((value) => {
|
|
259092
|
+
if (!isGitCommitHash(value)) {
|
|
259093
|
+
throw new InvalidArgumentError("Expected a git commit hash (7-64 hex chars).");
|
|
259094
|
+
}
|
|
259095
|
+
return value;
|
|
259096
|
+
}));
|
|
259097
|
+
command2.addOption(new Option("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency));
|
|
259075
259098
|
}
|
|
259076
259099
|
return command2.action(deployAction2);
|
|
259077
259100
|
}
|
|
259101
|
+
function parseConcurrency(value) {
|
|
259102
|
+
const parsed = Number(value);
|
|
259103
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_UPLOAD_CONCURRENCY) {
|
|
259104
|
+
throw new InvalidArgumentError(`Expected a whole number between 1 and ${MAX_UPLOAD_CONCURRENCY}.`);
|
|
259105
|
+
}
|
|
259106
|
+
return parsed;
|
|
259107
|
+
}
|
|
259108
|
+
function staticDeploymentsEnabled(env3 = process.env) {
|
|
259109
|
+
const value = env3.BASE44_STATIC_DEPLOYMENTS;
|
|
259110
|
+
return value === "1" || value === "true";
|
|
259111
|
+
}
|
|
259078
259112
|
|
|
259079
259113
|
// src/cli/commands/site/open.ts
|
|
259080
259114
|
async function openAction({
|
|
@@ -259091,8 +259125,8 @@ function getSiteOpenCommand() {
|
|
|
259091
259125
|
}
|
|
259092
259126
|
|
|
259093
259127
|
// src/cli/commands/site/index.ts
|
|
259094
|
-
function getSiteCommand(
|
|
259095
|
-
return new Command("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand(
|
|
259128
|
+
function getSiteCommand() {
|
|
259129
|
+
return new Command("site").description("Manage app site (frontend app)").addCommand(getSiteDeployCommand()).addCommand(getSiteOpenCommand());
|
|
259096
259130
|
}
|
|
259097
259131
|
|
|
259098
259132
|
// src/core/types/generator.ts
|
|
@@ -263615,7 +263649,7 @@ function createProgram(context) {
|
|
|
263615
263649
|
program2.addCommand(getSecretsCommand());
|
|
263616
263650
|
program2.addCommand(getSandboxCommand());
|
|
263617
263651
|
program2.addCommand(getAuthCommand());
|
|
263618
|
-
program2.addCommand(getSiteCommand(
|
|
263652
|
+
program2.addCommand(getSiteCommand());
|
|
263619
263653
|
program2.addCommand(getTypesCommand());
|
|
263620
263654
|
program2.addCommand(getExecCommand());
|
|
263621
263655
|
program2.addCommand(getDevCommand());
|
|
@@ -267839,7 +267873,6 @@ async function runCLI(options8) {
|
|
|
267839
267873
|
errorReporter,
|
|
267840
267874
|
isNonInteractive,
|
|
267841
267875
|
jsonMode,
|
|
267842
|
-
staticDeployments: staticDeploymentsEnabled(),
|
|
267843
267876
|
distribution: options8?.distribution ?? "npm",
|
|
267844
267877
|
log,
|
|
267845
267878
|
runTask: runTask2
|
|
@@ -267868,4 +267901,4 @@ export {
|
|
|
267868
267901
|
CLIExitError
|
|
267869
267902
|
};
|
|
267870
267903
|
|
|
267871
|
-
//# debugId=
|
|
267904
|
+
//# debugId=8588EA2CAEB0DBAE64756E2164756E21
|